Level 26
<html> <head> <title>Challenge 26</title> <style type="text/css"> body { background:black; color:white; font-size:10pt; } a { color:lightgreen; } </style> </head> <body> <? if(eregi("admin",$_GET[id])) { echo("<p>no!"); exit(); } $_GET[id]=urldecode($_GET[id]); if($_GET[id]=="admin") { @solve(26,100); } ?> <br><br> <a href=index.phps>index.phps</a> </body> </html>
eregi 함수가 뭐지...😢
php에서 http메소드를 통해 들어오는 사용자의 입력 검증 또는 필터링을 통해 eregi와 같은 함수를 사용한다.
<? $_id = $_GET[id]; if (eregi("admin",$_id)) echo "Filtered !!" . "<br>"; else echo $_id . "<br>"; ?>
"id=admin"이라는 값을 넣었을 때, PHP 5.2+, 5.3+에서는 모두 정상적으로 필터링 되고 있다.
하지만 앞부분에 "%00"의 NULL을 넣으니 PHP 5.3+에서는 필터링을 하지 못했다. 이를 통해 PHP 5.3+ POSIX Regex필터링을 우회할 수 있다.
PHP 5.3+에서 위의 문제를 수정하기 위해 POSIX Regex함수들을 PCRE Regex로 변경하는 것을 요구하고 있다.
다시 문제로 돌아와서
해당 문제는 GET 방식으로 id를 받고, 해당 값이 "admin"이면 필터링을 수행한다.
그리고 urldecode를 통해 GET방식으로 받은 id값을 저장하고 그 값이 "admin"이면 문제가 풀린다.
urldecode는 또 뭐지...😢
urlencode() / urldecode()
하나의 특수문자, 한글, multi-byte 문자를 %xx 형식으로 변환한다.
단점으로 길이가 길어진다는 점이 있고, [0-9, a-z, A,Z] 등은 encode되지 않고 그대로 보인다는 점이 있다.
이제 admin의 urlencode된 값을 구하면 된다.
그런데 앞서 단점으로 알파벳은 그대로 노출된다고 하였다. 즉, admin을 urlencode함수로 돌리면 변경되지 않는 다는점.
그래서 urlencode Table을 찾아보니 알파벳의 ascii코드 넘버에 hex값이 urlencode값이였다. 따라서 파이썬으로 고고~
admin을 urlencode하면 위와 같다. url상에서는 %를 붙여야 하므로, %61%64%6d%69%6e가 되겠다.
위 값을 넣어보니... no!라고 admin을 넣었을 때와 같이 출력되며 문제가 풀리질 않는다...🧐
인코딩 된 값을 넣었는데 eregi함수에 의해 필터링 되었다.
여기서 eregi함수 내부에서 urldecode기능이 있을 것이라고 생각되어 한번더 인코딩 한 값을 넣어보기로 하였다.
정답 : %2561%2564%256d%2569%256e