여러분 안녕하세요. POCI입니다.
이번 시간에는 Webhacking.kr의 5번 문제를 풀어보도록 하겠습니다.
1. 사이트 둘러보기
5번 문제에 들어가면 Login 버튼 하나와 Join 버튼 하나가 나옵니다.
Login 버튼을 누르면 로그인을 할 수 있게끔 아이디와 비밀번호를 입력하는 란이 나옵니다.
한번 webhacking.kr의 아이디와 비밀번호를 입력해봤습니다.
아이디가 admin이 아니기에 접근이 허가되지 않는다고 뜹니다.
여기서 알 수 있는 건 admin이라는 아이디가 필요하다는 것입니다.
다시 처음으로 돌아가서 Join 버튼을 눌러봅시다.
Join 버튼을 누르면 접근이 허가되지 않는다는 메시지가 뜹니다.
그럼 회원가입을 하기 위한 창으로 가는 것이 문제겠네요.
2. 디렉터리 이동하기
웹페이지는 각각의 디렉터리로 이루어져 있습니다.
Login 버튼을 눌렀을 때의 url을 보시면 다음과 같습니다.
이 뜻은 webhacking.kr 디렉터리 밑의 challenge 디렉터리 밑의 web 디렉터리 밑의 web-05 디렉터리 밑의 mem 디렉터리에 있는 login.php 파일을 의미합니다.
한번 url에서 login.php을 지워보겠습니다.
그러면 webhacking.kr/challenge/web/web-05/mem으로 들어오게 됩니다.
원래라면 이 곳은 아무나 들어와서는 안 되는 곳이라서 따로 구분을 해줘야 하지만, 구분을 해주지 않아서 발생한 취약점으로 이곳에 접근할 수 있습니다.
보시면 join.php와 login.php가 있습니다. login.php는 아까 확인한 곳이므로 회원가입을 위해서는 join.php를 열어야 할거 같습니다.
join.php를 클릭하면 아무것도 없이 까만 화면만 나오게 됩니다.
소스코드를 확인해봅시다.
코드가 난잡하게 쓰여있는 걸 보실 수 있습니다.
개행을 제대로 안 하면 코드의 가독성이 저렇게 떨어집니다. 저희 모두 개행하는 습관을 들이도록 합시다.
3. 코드 해독하기
https://www.strictly-software.com/unpack-javascript에서 개행을 자동적으로 해주므로 이 사이트를 이용합시다.
난독화가 해제된 코드를 보면 다음과 같습니다.
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
|
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>');
}
|
cs |
난독화가 해제되어도 l와 i가 너무 많고, 다 비슷비슷한 변수명으로 되어있어서 보기 어렵다는 게 문제입니다.
그렇기에 이를 해석하기 위해 크롬의 Console 기능을 사용했습니다.
F12를 눌러 개발자 모드로 들어간 다음, Console을 클릭하면 됩니다.
여기에 코드의 변수 지정부를 복사-붙여 넣기 합니다.
이제 코드 중간중간에 있는 난독화 된 부분을 복사-붙여 넣기 하시면 그 부분이 뭘 의미하는지 해석해줍니다.
이런 식으로 해석한 부분은 다음과 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
if (eval(document.cookie).indexOf(oldzombie) == -1) {
bye;
}
if (eval(document.URL).indexOf(mode=1) == -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=join.php>');
document.write('<table border=1><tr><td><font color=gray>id</font></td><td><input type=text name=id maxlength=5></td></tr>');
document.write('<tr><td><font color=gray>pass</font></td><td><input type=text name=pw maxlength=10></td></tr>');
document.write('<tr align=center><td colspan=2><input type=submit></td></tr></form></table>');
}
|
cs |
코드를 하나씩 해석해보겠습니다.
if(eval(document.cookie).indexOf(oldzombie)==-1) {
bye;
}
이 코드는 oldzombie라는 쿠킷값이 없다면 bye를 호출한다는 의미입니다.
if(eval(document.URL).indexof(mode=1)==-1){
alert('access_denied');
history.go(-1);
}
이 코드는 URL에 mode=1이 없으면 access_denied 메시지를 띄우고 이전 페이지로 돌아간다는 의미입니다.
아래 else 부분은 URL에 mode=1이 있으면 이러이러한 html를 띄운다는 의미입니다.
즉, oldzombie라는 쿠킷값이 필요하고 URL에 mode=1이 있어야 회원가입 페이지가 활성화된다는 의미입니다.
EditThisCookie로 oldzombie 쿠키를 추가합니다.
그리고 URL 뒤에 ?mode=1를 추가합니다.
그러면 회원가입을 할 수 있는 박스가 나오게 됩니다.
4. 회원 가입하기
admin 아이디가 필요하기에 id에는 admin, pass에는 아무 문자를 넣어주고 제출을 클릭합니다.
하지만 admin는 이미 있는 아이디라고 뜹니다.
코드를 확인하니 입력할 수 있는 아이디의 최대 길이가 5글자입니다. 이 길이를 10으로 늘려줍니다.
그런 다음 id에 admin(공백)을 입력하고 pass를 입력하고 제출을 클릭하면 회원가입이 되었다고 뜹니다.
마지막으로 login 화면으로 가서 아이디에 admin(공백), 비밀번호는 회원 가입할 때 쓴 문자로 로그인을 합니다.
그럼 로그인이 완료되어 문제가 풀렸다는 메시지가 나옵니다.
아이디를 무조건 5글자 이내로 설정했기 때문에 admin(공백)을 입력해도 DB에 admin으로 입력되는 취약점으로 인해 admin(공백)을 입력해도 admin으로 로그인이 되는 겁니다.
이번 강의는 여기까지입니다.
5번 문제는 여러 기법이 필요해서 난해했지만, 차근차근 풀어보면 쉽게 풀 수 있는 문제였습니다.
오늘도 수고하셨습니다.
정리
- 디렉터리 이동을 통해 join.php로 이동한다.
- 난독화된 코드를 해석한다.
- 입력할 수 있는 아이디의 최대길이를 늘린 후 admin(공백)으로 회원가입을 한다.
- 회원 가입할 때 입력했던 아이디와 비밀번호를 입력해서 admin으로 로그인한다.
강의가 유익하셨거나 마음에 드셨으면 댓글과 좋아요 부탁드립니다.
궁금하신 점이나 질문은 댓글이나 메일 남겨주세요.
'Write Up > webhacking.kr' 카테고리의 다른 글
Webhacking.kr 문제풀이_Part8_8번 문제 (0) | 2019.07.09 |
---|---|
Webhacking.kr 문제풀이_Part7_6번 문제 (0) | 2019.07.04 |
Webhacking.kr 문제풀이_Part5_4번 문제 (0) | 2019.07.02 |
Webhacking.kr 문제풀이_Part4_3번 문제 (2) | 2019.06.26 |
Webhacking.kr 문제풀이_Part3_2번 문제 (0) | 2019.06.24 |