-
<Webhacking.kr> old-05Wargame/Webhacking.kr 2021. 11. 14. 01:42
로그인 버튼과 회원가입 버튼이 나타난다.
로그인 버튼을 누르면
로그인 화면이 나타난다.
회원가입 버튼을 누르면
접근할 수 없다고 한다.
먼저 로그인 화면에서 ' or 1=1-- 을 입력해보면 아무 일도 일어나지 않는다.
Webhacking.kr의 아이디로 로그인해봐도 아무 일이 일어나지 않는다.
아마 'admin'으로 로그인하라는 것 같지만, 아무런 정보가 없다.
로그인 화면의 URL을 살펴보면 "/mem/login.php"이다. 여기서 "login.php"를 지우면
위와 같은 페이지가 나타나게 된다.
이를 디렉터리 인덱싱이라 한다.
디렉터리 인덱싱(Directory indexing) 취약점은 웹 서버의 잘못된 설정으로 웹 서버 디렉터리의 파일들이 노출되는 취약점으로, 디렉터리 리스팅 취약점이라고도 하며 과거 국정원 8대 홈페이지 취약점으로 선정된 적이 있다.
아무튼 'login.php' 외에 'join.php'가 보인다.
'join.php'로 접속하면 아무것도 없다.
페이지 소스 코드를 살펴보면
<html> <title>Challenge 5</title></head><body bgcolor=black><center> <script> l='a';ll='b';lll='c';llll='d';lllll='e';llllll='f';lllllll='g';llllllll='h';lllllllll='i';llllllllll='j';lllllllllll='k';llllllllllll='l';lllllllllllll='m';llllllllllllll='n';lllllllllllllll='o';llllllllllllllll='p';lllllllllllllllll='q';llllllllllllllllll='r';lllllllllllllllllll='s';llllllllllllllllllll='t';lllllllllllllllllllll='u';llllllllllllllllllllll='v';lllllllllllllllllllllll='w';llllllllllllllllllllllll='x';lllllllllllllllllllllllll='y';llllllllllllllllllllllllll='z';I='1';II='2';III='3';IIII='4';IIIII='5';IIIIII='6';IIIIIII='7';IIIIIIII='8';IIIIIIIII='9';IIIIIIIIII='0';li='.';ii='<';iii='>';lIllIllIllIllIllIllIllIllIllIl=lllllllllllllll+llllllllllll+llll+llllllllllllllllllllllllll+lllllllllllllll+lllllllllllll+ll+lllllllll+lllll; lIIIIIIIIIIIIIIIIIIl=llll+lllllllllllllll+lll+lllllllllllllllllllll+lllllllllllll+lllll+llllllllllllll+llllllllllllllllllll+li+lll+lllllllllllllll+lllllllllllllll+lllllllllll+lllllllll+lllll;if(eval(lIIIIIIIIIIIIIIIIIIl).indexOf(lIllIllIllIllIllIllIllIllIllIl)==-1) {alert('bye');throw "stop";}if(eval(llll+lllllllllllllll+lll+lllllllllllllllllllll+lllllllllllll+lllll+llllllllllllll+llllllllllllllllllll+li+'U'+'R'+'L').indexOf(lllllllllllll+lllllllllllllll+llll+lllll+'='+I)==-1){alert('access_denied');throw "stop";}else{document.write('<font size=2 color=white>Join</font><p>');document.write('.<p>.<p>.<p>.<p>.<p>');document.write('<form method=post action='+llllllllll+lllllllllllllll+lllllllll+llllllllllllll+li+llllllllllllllll+llllllll+llllllllllllllll +'>');document.write('<table border=1><tr><td><font color=gray>id</font></td><td><input type=text name='+lllllllll+llll+' maxlength=20></td></tr>');document.write('<tr><td><font color=gray>pass</font></td><td><input type=text name='+llllllllllllllll+lllllllllllllllllllllll+'></td></tr>');document.write('<tr align=center><td colspan=2><input type=submit></td></tr></form></table>');} </script> </body> </html>
이해하기 쉽게 먼저 문자들로 치환하면
$str_1='oldzombie'; $str_2='document.cookie'; if(eval($str_2).indexOf($str_1)==-1) { alert('bye'); throw "stop"; } if(eval('document.URL').indexOf('mode=1')==-1){ alert('access_denied'); throw "stop"; } else{ document.write('<font size=2 color=white>Join</font><p>'); document.write('.<p>.<p>.<p>.<p>.<p>'); document.write('<form method=post action=join.php>'); document.write('<table border=1><tr><td><font color=gray>id</font></td><td><input type=text name=id maxlength=20></td></tr>'); document.write('<tr><td><font color=gray>pass</font></td><td><input type=text name=pw></td></tr>'); document.write('<tr align=center><td colspan=2><input type=submit></td></tr></form></table>'); }
위 코드의 조건을 만족하려면
'document.cookie'에 'oldzombie'라는 문자열이 포함되어야 한다.
그리고 URL에 'mode=1'이라는 문자열이 포함되어야 한다.
우선 쿠키 값을 바꾸기 위해 'EditThisCookie'를 사용해도 되고,
개발자 도구(F12)의 콘솔 창에 document.cookie='oldzombie=1111' 라고 입력한다.
(쿠키명이 'oldzombie'가 되어도 되고, 쿠키값이 'oldzombie'가 되어도 된다.)
그리고 'mode=1'이 포함되어야 하므로
현재 URL인 ./join.php?mode=1을 입력하면
회원 가입 창이 뜬다.
일단 아무렇게 가입해본다.
그리고 다시 ./login.php로 돌아와 로그인을 하면
admin 계정으로 로그인하라고 한다.
다시 ./join.php?mode=1로 돌아와 admin으로 가입을 해보면
id가 이미 존재한다고 한다.
이 경우, 새로운 admin으로 가입을 할 수 있다.
Burp Suite를 이용해 'admin%20%20%20%20%20%20%20%20%20%20%00'을 인자로 넘겨 회원 가입을 하면 된다.(%20 : 공백, %00 : NULL)
문제가 풀리게 된다.
이런 방법이 되는 이유는
MySQL DB에서 해당 자료형이 CHAR인 경우, 공백이 있어도 같은 문자열로 인식한다고 한다.
(CHAR는 받는 문자열 길이에 상관없이 미리 정해놓은 크기만큼 공백을 채워서 저장)
하지만 PHP에서는 strcmp나 직접 비교를 통해 문자열을 비교하게 되어 두 문자열을 다르게 인식한다.
따라서, PHP의 비교만 우회하면 데이터에 접근할 수 있다.
이를 막기 위해서는 PHP에서 input값을 비교할 때, 공백을 제거하는 함수나 정규표현식을 사용하여 공백을
제거한다.
'Wargame > Webhacking.kr' 카테고리의 다른 글
<Webhacking.kr> old-08 (0) 2021.11.16 <Webhacking.kr> old-07 (0) 2021.11.15 <Webhacking.kr> old-06 (0) 2021.11.11 <Webhacking.kr> old-03 (0) 2021.11.09 <Webhacking.kr> old-02 (0) 2021.11.08