쿠키의 REMTE_ADDR이 ip가 되므로 “127.0.0.1”을 입력해야 한다. 하지만 “..”은 “.”으로, “12”, “7.”, “0.”은 지워지므로 변형이 필요하다. 따라서 REMOTE_ADDR이라는 쿠키를 만들고 값을 “112277…00…00…1”이라고설정하면 ip에 127.0.0.1이 들어가면서 문제가 풀린다.
script의 ck 함수를 살펴보면 lv5frm.id.value와 lv5frm.cmt.value, lv5frm.captcha.value의 값이 공백이 아니고, lv5frm.captcha.value의 값이 lvm5frm.captcha_.value와 동일하면 lv5frm.submit()이 되면서 문제가 풀린다. chaptcha의 값이 새로 고침을 할 때마다 바뀌고, 2초의 time limit가 있기 때문에 콘솔 창을 이용해서 2초 안에 위의 코드를 입력하면 문제가 풀린다.
if($_GET[no])
{
if(eregi(" |/|\(|\)|\t|\||&|union|select|from|0x",$_GET[no])) exit("no hack");
$q=@mysql_fetch_array(mysql_query("select id from challenge18_table where id='guest' and no=$_GET[no]"));
if($q[0]=="guest") echo ("hi guest");
if($q[0]=="admin")
{
@solve();
echo ("hi admin!");
}
}
get 방식으로 no의 값을 받으면 아래의 코드들이 실행되게 된다. 그리고 만약 입력 받은 값에 공백, /, \(, \), \t, |, &, union, select, from, 0x 등의 문자열이 있을 경우 exit에 의해 종료된다. 그리고 쿼리문의 결과 데이터를 배열 형식으로 저장해서 배열의 첫번째 데이터가 “admin”이라면 문제가 풀리게 된다. 임의로 숫자를 대입해보자.
임의로 0, 1, 2를 대입해보았다. 주소에 no=0, no=1, no=2 형식으로 들어가게 되고, 1을 대입했을 때 ‘hi guest’라고 뜨는 것을 볼 수 있다. 즉 select id from challenge18_table (where((id=’guest’) and (no=1)))이라는 쿼리문이 실행되면 q[0]에 guest라는 문자열이 저장되는 것이다. 그렇다면 특정 no 값에 ‘admin’ 데이터를 담고 있을 것이다. 이때 공백을 넣을 경우 조건문이 종료되므로 공백을 무시하는 ‘%0a’를 사용해야 한다.
no=2%0aor%0ano=2를 입력하면 id가 guest이고 no=2이거나(거짓, 1을 제외한 아무 값이나 넣어도 된다.), no가 2인 값을 쿼리문에 저장하게 된다. 즉 no=2인 값에 ‘admin’ 데이터를 담고있는 것이다.