안녕하세요. 오늘은 webhacking 18번 문제를 풀어보겠습니다.

홈페이지로 들어가 webhacking 18번을 눌러주세요.


sql injection 문제이군요. 밑에 보시면 index.phps가 있습니다. phps가 php source 의 약자인것은 전부 아시지요? 한번 눌러 봅시다.

소스를 차례대로 분석해 봅시다.

일단 첫줄을 보시면 no를 get형식으로 입력받아야 소스가 실행되는 것을 알 수 있습니다.

그리고 eregi를 사용해 no를 입력받았을 때 no값에 

공백,/,\(,\),\t,|,&,union,select,from,0x 이러한 값들이 있을 경우 exit에 의해 함수가 실행이 되지 않고 종료된다는 것을 알 수 잇습니다.

그다음은 mysql함수를 사용하여 id가 guest이고 입력받은 no값과 일치하는 id를 검색하여 q라는 변수에 저장하는 것을 알 수 있습니다.

그렇다면 no가 무엇일까요?


개발자 도구를 이용해 확인을 하시면 문제의 입력칸의 이름이 no인것을 확인할 수 있습니다. 그리고 from method가 get으로 설정되있는 것을 보아 get형식으로 입력받는 다는 것을 알 수 있습니다.

위에 나온 sql함수와 php함수는 블로그항목에 게시되어 있으므로 자세히 알고 싶으시면 참고하시기 바랍니다.

그다음 소스를 봅시다.

if($q[0]=="guest") echo ("hi guest"); 
if(
$q[0]=="admin"

@solve(); 
echo (
"hi admin!"); 

q[0]가 게스트이면 hi guest를 출력하고 admin이면 문제가 해결된다고 나와 있습니다.

일단 테이블을 예상해봅시다.

id                                 no

admin                            ?

guest                             ?

대충 이렇게 되겠군요. 

그런데 우리는 no값을 모릅니다. 그래서 일단 무차별대입으로 한번 숫자를 입력해보겠습니다.

1을 입력하니 hi guest가 나오는 것을 볼 수 있습니다. 즉 id가 guest이고 no값이 1인 id를 검색했는데 guest가 나왔다는 것이지요.

테이블을 고쳐봅시다.

id                                 no

guest                             1

admin                            ?

만약 id가 guest하고 admin밖에 없다면 admin의 no값은 2일 확률이 큽니다. admin을 뽑아내봅시다. 

$q=@mysql_fetch_array(mysql_query("select id from challenge18_table where id='guest' and no=$_GET[no]")); 

여기 위의 소스를 보시면 조건에 id가 guest 이고.... 라고 되어 있습니다. 우리는 admin을 뽑아내야 하는데 id가 guest이면 no값이 얼마든 뽑아낼수가 없습니다.  그래서 이 조건을 무효화 시켜줄 필요가 있습니다. no값에 0 or no=2을 넣어 봅시다.

$q=@mysql_fetch_array(mysql_query("select id from challenge18_table where id='guest' and no=0 or no=2")); 

이렇게 되면 id가 guest이고 no값이 0인 id를 찾거나 no값이 2인 id를 찾으라는 뜻이됩니다. 왜 이렇게 되냐면 sql연산은 and>or순이기 때문에

(id='guest' and no=0) or no=2 이렇게 되기 때문이지요.

admin의 no값이 2라는 가정하에 정답은 0 or no=2가 될 수 있겠군요.

단 eregi에 의해 no값에 공백이 있으면 함수를 종료하기 때문에 공백을 우회해줄 필요가 있습니다. 공백을 우회하는 방법으로는 /를 이용한 주석이나 \t, \n 등이 있습니다.하지만 /와 \t는 eregi에 의해서 막힘으로 \n을 써봅시다.

그런데 \n을 직접 폼에 입력하여 전송하면 \따로 n따로 url 인코딩이 되어버립니다. 그래서 \n을 같이 인코딩한 %0a라는 값을 직접 주소창에 적어주셔야 합니다.

get방식으로 입력받기 때문에 주소창에서 적어주실 수 있습니다.

단 적기전에 ?를 붙여주시고 no값을 넣어주시면 됩니다.

즉 주소창에 no=0%0aor%0ano=2를 입력해봅시다. 

admin의 no값이 2가 맞은 모양입니다. 문제가 해결되었군요.

아 참고로 저는 no=2%0aor%0ano=2를 입력해서 문제를 해결했습니다.

앞의 no값은 어차피 거짓으로 만들기 위한거기 때문에 1을 제외한 그 어떤 값을 넣어줘도 문제가 해결됩니다. 

다만 1을 넣으면 앞의 조건도 참이 되버리기 때문에 guest와 admin이 둘다 불러오게 됩니다. q[0]이기 때문에 먼저 받아온 guest부터 저장이 되어버리기 때문에 문제를 해결 할 수 없습니다. 만약 소스에 q[1]이라고 되어있었다면 얘기는 달라졌겠군요.

암튼 이것으로 문제해결을 마치겠습니다.


'Webhacking' 카테고리의 다른 글

webhacking 15번 문제  (0) 2015.10.12
webhacking - 26번 문제  (0) 2015.10.02
webhacking - 18번 문제  (0) 2015.10.02
webhacking - 60번 문제  (0) 2015.09.25
webhacking - 20번 문제  (0) 2015.09.25
webhacking - 42번 문제  (0) 2015.09.18
Posted by englishmath