프로젝트/Webhacking.kr

[Webhacking.kr] Challenge(old) 5번 문제

Uggjjini 2021. 7. 2. 12:49

문제 페이지는 해당 페이지와 같다.

 

 

Login 버튼을 클릭하여 로그인 페이지로 이동한다.

 

 

임의로 웹해킹 페이지 아이디로 로그인 해본다.

 

로그인이 되지 않는다.

처음 페이지로 돌아가서 Join 버튼을 눌러본다.

접근이 거부되는 것을 확인할 수 있다.

 

이 문제는 접근이 거부되는 join에 접근하여 회원가입을 하고 로그인하면 풀릴 것 같다.

 

디렉토리를 이동하여 join에 접근을 시도해본다.

로그인하는 페이지의 URL을 확인해 보면 https://webhacking.kr/challengeweb-05/mem/login.php 이다.

 

해당 페이지의 디렉토리는 가장 상위에 webhacking.kr 디렉터리가 존재하며 그 하위에 challengeweb-05 디렉터리가 존재한다. 그리고 challengeweb-05 디렉토리 하단에 존재하는 mem 디렉터리 안에 login.php  파일이 존재함을 알 수 있다.

 

login.php 가 들어있는 mem 디렉터리로 이동하기 위해 https://webhacking.kr/challengeweb-05/mem 으로 이동한다.

 

이동하면 상단의 페이지로 이동하게 되는데 join.php 파일이 존재하는 것을 볼 수 있다.

join.php 파일을 클릭하면 bye 라는 알림창이 뜨는 것을 확인 할 수 있다.

 

확인을 누르고 해당페이지의 소스를 확인해본다.

 

 

개행이 이루어지지지 않아 스크립트를 해석하기가 여간 복잡한게 아니다.

개행을 자동적으로 해주는 사이트를 이용하여 해당 코드를 해독한다.

 

https://www.strictly-software.com/unpack-javascript

 

Javascript Unpacker Tool - Strictly Software

This Javascript unpacker tool has now been upgraded to allow it to unpack multiple eval statements. So if your packed code has itself been packed a few times it will loop through until it finds the original source code. If you want to test this multiple ev

www.strictly-software.com

 

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>');
}

 

개행을 하였더라도 변수가 너무 l과 i가 너무 많고 다 비슷한 변수로 이루어져 있어서 해석하기 어렵다.

개발자 도구의 Console 기능을 사용하여 해석한다.

 

코드의 변수를 먼저 선언한다.

 

 

그리고 중간중간 난독화된 부분을 콘솔에 입력하면 난독화된 코드의 해석이 가능하다.

 

 

if (eval('document.cookie').indexOf('oldzombie') == -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>');
}

 

난독화가 풀린 상단의 코드를 해석해본다.

 

if (eval('document.cookie').indexOf('oldzombie') == -1) {
	alert('bye');
	throw "stop";
}

 

oldzombie라는 쿠키값이 없으면 bye 메세지와 함께 alert()함수를 호출한다는 것을 의미한다.

 

if (eval("document.URL").indexOf("mode=1") == -1) {
	alert('access_denied');
	throw "stop";
}

 

URL에 mode=1이 없으면 access_denied 메세지와 함께 alert()함수를 호출한다는 것을 의미한다.

 

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>');
}

 

URL에 mode=1가 있으면 해당 html를 띄운다는 의미이다.

 

즉, join에 접근하기 위해서는 oldzombie라는 쿠키값이 필요하고 URL에 mode=1이 있어야 한다는 것이다,

 

 

먼저 개발자 도구를 이용하여 oldzombie 쿠키를 추가한다.

 

 

쿠키값은 임의로 1234를 넣었다.

 

oldzombie 쿠키를 추가하고 URL 뒤에 ?mode=1을 추가하여 이동한다.

 

 

회원가입 입력창이 뜨는 페이지로 이동하는 것을 볼 수 있다.

 

임의의 아이디로 회원가입을 해본다.

 

 

 

가입이 성공적으로 이루어진 것을 볼 수 있다.

로그인 페이지로 이동하여 해당 아이디로 로그인 한다.

 

 

admin으로 로그인해야 한다는 문구가 뜨는 것을 확인할 수 있다.

 

다시 join 페이지로 접근하여 admin으로 회원가입을 시도한다.

 

 

이미 존재하는 아이디임을 알 수 있다.

 

그렇다면 php에서는 admin이 아니고 sql 상에서는 admin으로 인식하도록 회원가입 해야하는 것 같다.

php에서는 'a'와 'a(공백)' 은 다른 문자열로 인식하지만 sql에서는 같은 문자열로 인식한다.

 

이를 이용하여 '(공백)admin(공백)' 로 회원가입을 시도해본다.

 

 

 

admin으로 회원가입이 성공되는 것을 볼 수 있다.

 

로그인 페이지로 이동하여 admin으로 로그인한다.

 

 

 

해당 문제가 풀린 것을 확인 할 수 있다.