화면을 보면 아무것도 없이 Login과 Join 밖에 없다
login에서는 무언가로 로그인을 해야하는 것 같다
혹시나 해서 sql injection으로 했더니 안된다
그리고 join버튼은 alert만 실행되고 별 다른 건 없었다
풀이:
로그인 화면으로 간다면 경로가 mem으로 간 다음 login.php로 넘어간다
그럼 여기서 login.php를 지워 버린다면 어떻게 될까
파일을 관리하는 곳으로 이동된다 이 mem에서 페이지를 넘나 들 것이다
이 취약점을 바로 path traversal이라고 한다 꼭 기억해 두자
그러면 이 화면에서 보이는 것 처럼 join.php로 갈 수 있다!
하지만 join페이지에서는 bye라는 메세지만 뜨고 별 다른 것이 없어 보인다
개발자 도구나 열어 보자
개발자 도구에서 코드가 나온다 하지만 상당히 난독화 되어 있으니 보기 편하게 풀어보자
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>');
}
뭐 이렇게 되어 있다
난독화는 빠로 풀지 않을 것이다 왜냐하면 코드 조작으로 원하는 코드를 실행 할 수 있기 때문이다
우리가 alert함수로 bye를 보게 된 코드는 아마
첫번째 if문 일 것이다 alert로 bye를 호출한다
하지만 else문에서는 document.write으로 무언가 코드를 실행한다
그러면 document.write만 따로 따서 콘솔에 실행해보자
그러면 로그인 폼이 나온다 여기서 아무거나 쳐 보자
그러면 sign up as aaa success라며 회원가입에 성공 한 듯이 말한 것을 보아
회원가입 폼인가 보다 그러면 admin은 어떨까
이 아이디는 이미 있다며 admin으로 회원가입이 불가능하게 한다
그렇다면 우린 개발자 도구에서 분석 해 보자
여기서 id의 길이에 제한이 있는 것을 알 수 있다
여기서 취약점이 발생 할 수도 있다
api에서 인식하는 아이디의 길이는 20글자인데
클라이언트에서 20글자 이상의 데이터가 날아 온다면
아이디 중복 검사나 익스코드를 확인하는 영역이 20글자라는 소리다!
| 20글자(서버가 인식하는 데이터 길이) |
admin(인식 불가능) |
그렇다면 DB에서는 20글자 이상의 데이터가 저장되는 것이며 이는 admin과 아이디는 같되, 데이터는 다르므로 admin으로 로그인이 가능하다는 소리다! 실제 DB에서 ID를 저장하는 구문이 SET id = 값, INSERT id = 값 형식이기에 우회가 가능하다
끝