반응형

 

문제를 보면 다음과 같이 또 DB 모양이 있다.

 

이번 문제도 SQLi 문제일까? 하는 생각에 문제를 클릭해보자.

 

 

문제를 클릭하면 다음과 같이 LoginJoin 창이 보인다.

 

Login을 눌러보자.

 

 

Login을 눌르면 이렇게 IDPW를 입력하는 창이 나온다..

 

별다른 정보가 없기 때문에 페이지 소스를 보았다.

 

 

페이지 소스 보기를 봐도 별 다른 정보가 없어서 test/test를 입력해보았다.

 

 

 

test/test을 입력하고 login을 클릭한 결과 Wrong password라는 문구와 함께 다시 login 폼이 보인다.

 

IDPW를 알아내기 위해 IDPWSQLi를 수행보았지만 별다른 반응이 없었다.

 

따라서 이번 문제를 풀기 위해서는 계정을 알아야할것같았다.

 

따라서 제일 처음으로 돌아와 Join을 눌러보았다.

 

 

Join을 눌러 보니 Access_Denied이라는 문구와 함께 Join을 할 수 없게 되어있다.

 

페이지 소스에서도 아무런 정보도 찾을 수도 없고, ID, PWSQLi도 안먹히고..

 

그 다음 할 것이 없어 URL 주소를 보았다.

 

로그인 화면의 URL은 다음과 같다.

 

https://webhacking.kr/challenge/web-05/mem/login.php

 

우리는 할 수 있는 시도를 다 해보았고 문제에 힌트가 될 정보가 없기 때문에

 

https://webhacking.kr/challenge/web-05/mem를 입력하여

 

디렉토리 인덱스 취약점이 있는지 살펴보았다. 

 

여기서 말하는 디렉토리 인덱스 취약점을 짧게 정리하면 다음과 같다.


웹 애플리케이션을 사용하고 있는 서버의 미흡한 설정으로 인해 인덱싱 기능이 활성화 되어 있을 경우

공격자가 강제 호출을 통해 서버내의 모든 디렉터리 및 파일에 대해 접근이 가능하며

웹 애플리케이션 및 주요 정보가 노출될수 있는 취약점이다.


https://webhacking.kr/challenge/web-05/mem를 입력하니 디렉토리 인덱스 취약점이 발견되었다.

 

 

여기서 우리가 원하는 페이지인 join.php 페이지를 볼 수 있다.

 

join.php 페이지를 클릭해보자.

 

 

클릭하니 bye라는 문구와 함께 검은색 창만 보인다.

 

뭐지??하고 맨날 보았던 페이지 소스를 보았다.

 

 

script 태그에 이상한 script가 존재하였다.

 

원래의 보통의 script가 아니였기 때문에 이게 힌트일 것 같았다.

 

HTMl 소스코드를 가독성 있게 보면 다음과 같다.

 

<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='>';

...... 생략 ........

</script>
</body>

</html>

 

뭔가 딱 보자마자 바로 느낌이 왔다.

 

치환이다!!

 

예를 들어보자.

 

l='a';

 

말 그대로 l은 a이다. 

 

생략한 코드를 치환하면 다음과 같다.

 

<html>
<title>Challenge 5</title></head><body bgcolor=black><center>
<script>


...... 생략 ........

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

if(eval(document.'U''R''L').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>');
}
</script>
</body>
</html>

 

이렇게 위의 코드처럼 치환하면 문제를 풀 수 있을 듯하다.

 

코드를 분석해보자.

 

 

위의 코드는 현재 cookie값 중에 oldzombie 라는 값이 있는지 체크하는것이다.

 

즉, 현재 cookie값 중에 oldzombie가 없다면 bye라는 문구와 함께 alert창을 볼 수 있다.

 

따라서 먼저 이 부분을 우회를 해야할것같다.

 

따라서 cookie 이름은 test, 값은 oldzombie를 설정하는 명령어로 cookie값을 설정해보았다.

 

 

그리고 다시 join.php 페이지에 접속해보았다.

 

 

아까와는 달리 access_denied라는 문구를 볼 수 있다!!

 

그럼 그 아래의 코드 또한 우회 해주면 된다!!

 

document.URL 값은 다음과 같이 'https://webhacking.kr/challenge/web-05/mem/join.php' 값이다.

 

 

근데 위의 소스코드에서는 oldzombie처럼 mode=1이 있는지 확인하는것이다.

 

따라서 https://webhacking.kr/challenge/web-05/mem/join.php/mode=1를 입력해보았다.

 

 

이처럼 Join 할 수 있는 폼이 생겼다.

 

여기서 JoinIDPW를 입력하고 제출 버튼을 눌러보자.

 

 

 

이제 Login.php에 접속해서 가입한 정보로 로그인을 해보자!

 

 

이렇게 로그인은 된다.

 

하지만 admin이 아니라는 문구가 뜬다.

 

따라서 이 문제의 출제 의도는 admin으로 로그인을 해야 한다는 것이다.

 

그럼 다시 Join.php에서 admin으로 가입해보자.

 

 

 

????

 

이미 admin이라는 계정이 존재한다.

 

하지만 이번 문제는 admin으로 로그인을 해야 한다.

 

앞에서 로그인 화면에선 SQLi가 통하지 않았기 때문에 이번 문제는 Join.php에서

 

admin으로 가입을 해야한다.

 

가입할때의 패킷을 보자.

 

다음과 같다.

 

id와 pw라는 파라미터로 입력한 admin123POST 형식으로 서버로 넘어간다.

 

예전에 학교 다닐때 DB에 저장될때 띄어쓰기나 공백이 들어가면 저장되는 형태에 따라서

 

'admin'과 'admin '이 같다는걸 배운적이 있다.

 

따라서 id값에 'admin' 대신 'admin '로 서버로 보내봤다.

 

그 후 로그인을 해보았다.

 

 

기억을 더듬어 문제는 풀었는데 정확하게 기억이 나지 않아서 찾아보았다.

 

https://techblog.woowahan.com/2559/ 여기서 정말 자세히 설명이되어있다.

 


쉽게 정리하자면 mysql DB에서는 'a'와 'a ' 또는 ' a'는 같다라고 인식을 한다.

 

즉, 공백이 있어도 같은 문자나 문자열이라고 인식을 한다는것이다.

 

하지만 이건 DB에 저장될때의 자료형이 CHAR일때만 가능하다.

 

비교하려는 두 문자열의 길이가 다른 경우

 

짧은 쪽에 공백을 이어붙여 길이를 똑같이 만든 다음 비교하기 때문에 발생하는 일이다.

 

이런 식이라면 'admin'와 'admin  '를 비교해도 똑같을 수밖에 없다.


반응형

'웹 해킹 > Webhacking.kr' 카테고리의 다른 글

7. old-07  (0) 2021.11.04
6. old-06  (0) 2021.11.03
4. old-04  (0) 2021.11.01
3. old-03  (0) 2021.10.19
2. old-02  (0) 2021.10.18

+ Recent posts