본문 바로가기

----WARGAME----/Webhacking.kr

Webhacking.kr 5번 풀이 - Directory Traversal, Directory Listing and Code Obfuscation

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 

Webhacking.kr 워게임 사이트에 로그인 한 후, 'Challenges' 페이지에 접속한다.
  * Login
  * Challenges

 

Challenges 페이지에서 5번을 클릭하면 다음과 같은 5번 문제의 페이지를 볼 수 있다.

 

 

Login 버튼을 누르면 로그인 페이지가 출력되고,

Join 버튼을 누르면 Access_Denied 라는 Alert 창이 출력된다.

 

먼저, Login 버튼을 클릭하여 로그인 페이지로 이동해보자.

 

 

SQL Injection 문제인가 싶어 여러 우회 쿼리를 시도하여 보아도 성공하지 못한다.

또한 admin이 아닌 유저로 로그인 하면 아래와 같이 admin 유저가 아니라는 메시지가 출력된다.

 

 

즉, 결국 admin 유저의 패스워드를 알아내던가 해서 로그인해야할 것으로 생각된다.

다시 메인페이지로 돌아가서 힌트가 있는지 찾아보자.

메인페이지를 우클릭하여 소스 보기를 클릭한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<html>
<head>
<title>Challenge 5</title>
</head>
<body bgcolor=black>
<center>
<font color=black>
.<p>
.<p>
.<p>
.<p>
.<p>
.<p>
.<p>
</font>
<input type=button value='Login' style=border:0;width:100;background=black;color=green onmouseover=this.focus(); onclick=move('login');>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<input type=button value='Join' style=border:0;width:100;background=black;color=blue onmouseover=this.focus(); onclick=no();>
 
<script>
function no()
{
alert('Access_Denied');
}
 
function move(page)
{
if(page=='login') { location.href='mem/login.php'; }
 
}
 
</script>
</center>
</body>
</html>
cs

 

소스를 살펴보면 Join Button을 클릭하면 무조건 no() 함수가 실행되도록 되어 있다.

또한 Login Button을 클릭하면 실행되는 move(page) 함수 내부 값에 보면 'mem/login.php'라는 연결 값이 있다.

해당 값을 이용하여 Directory Listing 취약점이 있는지 확인해보자.

 -> 접속 : http://webhacking.kr/challenge/web/web-05/mem/

 

해당 경로(디렉터리)에서 기존에 알지 못했던 join.php 파일의 정보를 얻을 수 있다.

 

 

join.php 페이지로 접속 해보자.

 -> 접속 : http://webhacking.kr/challenge/web/web-05/mem/join.php

 

아무 화면이 출력되지 않는다.

하지만 에러메시지가 출력되거나 연결되지 않는 것으로 보아서 실제 존재하는 페이지일지도 모른다.

소스보기를 시도하면 다음과 같은 소스를 볼 수 있다.

1
2
3
4
5
6
7
8
9
<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) { bye; }if(eval(llll+lllllllllllllll+lll+lllllllllllllllllllll+lllllllllllll+lllll+llllllllllllll+llllllllllllllllllll+li+'U'+'R'+'L').indexOf(lllllllllllll+lllllllllllllll+llll+lllll+'='+I)==-1){alert('access_denied');history.go(-1);}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=5></td></tr>');document.write('<tr><td><font color=gray>pass</font></td><td><input type=text name='+llllllllllllllll+lllllllllllllllllllllll+' maxlength=10></td></tr>');document.write('<tr align=center><td colspan=2><input type=submit></td></tr></form></table>');}
</script>
</body>
</html>
cs

 

스크립트 내부의 내용이 문자열 치환을 통하여 난독화가 되어 있다.

또한 소스가 조금 보기 힘든데 아래 사이트에서 조금 더 보기좋게 개행등을 자동으로 진행한다.

 * JS-Beautifier

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<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) {
                bye;
            }
            if (eval(llll + lllllllllllllll + lll + lllllllllllllllllllll + lllllllllllll + lllll + llllllllllllll + llllllllllllllllllll + li + 'U' + 'R' + 'L').indexOf(lllllllllllll + lllllllllllllll + llll + lllll + '=' + I) == -1) {
                alert('access_denied');
                history.go(-1);
            } 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=5></td></tr>');
                document.write('<tr><td><font color=gray>pass</font></td><td><input type=text name=' + llllllllllllllll + lllllllllllllllllllllll + ' maxlength=10></td></tr>');
                document.write('<tr align=center><td colspan=2><input type=submit></td></tr></form></table>');
            }
        </script>
</body>
 
</html>
cs

 

굳이 난독화를 전부 해제하지 않아도, 쭉 보면 if문에 성립하면 access_denied 시키고 else로 들어가는 경우 Join과 관련되는 행위를 하는 것으로 보인다.

join.php 사이트에 접속한 상태로 개발자도구(F12)를 눌러 'Console' 기능을 활용해보자. (크롬, 파이어폭스 동일)

 

 

else { } 부분의 모든 값을 그대로 복사하여 콘솔에 입력한다.

1
2
3
4
5
6
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=5></td></tr>');
document.write('<tr><td><font color=gray>pass</font></td><td><input type=text name=' + llllllllllllllll + lllllllllllllllllllllll + ' maxlength=10></td></tr>');
document.write('<tr align=center><td colspan=2><input type=submit></td></tr></form></table>');
cs

 

입력하면 스크립트 코드들이 수행되면서 아래와 같은 Form이 출력된다.

 

 

우리는 앞에서 admin 유저로 Login을 성공해야 한다는 것을 파악했기 때문에,

admin 유저로 가입을 시도해보자.

다음과 같이 이미 admin 유저가 존재한다고 출력되고 실패한다.

 

 

한 가지 공격 기법으로 공백을 이용해볼 수 있다.

즉, 'admin' 대신 'admin ' 처럼 뒤에 공백을 하나 추가해서 가입을 시도해보자.

그런데 id 값에 5자를 초과해서 입력이 안되는 것을 볼 수 있다.

 

이전과 동일하게 개발자도구(F12)를 실행하고 'DOM과 스타일검사기' 기능을 클릭한다.

이후, Form 안의 값 중 id 값의 maxlength 값을 6 이상으로 수정한다.

(해당 값을 더블클릭하면 수정이 가능하다.)

 

 

수정이 완료되면 공백을 맨 뒤에 추가하여 'admin '로 가입을 시도한다.

다음과 같이 가입이 성공하는 것을 볼 수 있다.

 

 

이제 처음 방문했던 login.php로 이동하여 가입한 admin 유저로 로그인을 시도해보자.

 -> 접속 : http://webhacking.kr/challenge/web/web-05/mem/login.php

 

정상적으로 로그인이 수행되면 본 단계가 모두 종료되고, 축하 메시지가 출력된다.

 

 

- 끝 -

 

출처 : warsolve.org, http://warsolve.org/w_webhacking.kr/ko-kr/level-5.aspx