반응형

 

 

 


 

login.php 페이지가 있으니 join.php을 입력해봤더니 존재한다.

 

<
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) {
    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>');
} <
/script> <
/body> <
/html>

 

join.php의 소스코드를 봤더니 위와 같이 나온다.

 

'l'과 'i'의 개수에 따라 알파벳과 숫자가 지정되어 있고, 특수 문자도 지정되어 있다.

 


 

개발자 도구 -> console 탭에 script 구문을 입력해봤더니 위와 같은 결과가 나온다.

 


 

if (eval(lIIIIIIIIIIIIIIIIIIl).indexOf(lIllIllIllIllIllIllIllIllIllIl) == -1) {
    alert('bye');
    throw "stop";
}

 

위의 구문은 아래와 같다.

 

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

 

eval은 JS 코드를 실행하는 함수이다.

(eval() 함수는 해커가 위험한 코드를 사용할 수 있기 때문에 사용을 권하지 않는다.)

 


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

 

위의 코드는 아래와 같다.

 

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

 


즉, 쿠키에 oldzombie라는 값이 있고, URL에 mode=1이 있으면, 조건은 패스된다.

 

 

그렇다면 위와 같이 oldzombie라는 쿠키를 생성하고 ?mode=1 파라미터를 주면 id와 password를 입력하는 창이 뜬다.

 

 

id와 pass에 admin을 입력했더니

 

 

이미 있다고 한다.

 

 

이번에는 위와 같이 입력했더니

 

 

성공적으로 해당 계정을 만들었다고 한다.

 


풀이

 

 

위와 같이 join.php 페이지에서 id에 admin을 입력하는데 맨 앞에 공백을 주고 제출하면

 

 

성공적으로 회원가입된다.

 

이유는 SQL에서 'admin'과 ' admin'을 같은 문자열이라 보고 TRUE를 반환하기 때문이다.

 

 

login.php 페이지로 돌아와 위와 같이 (공백)admin / admin을 입력하면 로그인이 되면서 문제가 풀린다.

 


INFO

 

mysql에서는 'admin'과 'admin '은 같다고 인식한다.

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

 

하지만 이는 자료형이 CHAR형 일 때만 가능한데, CHAR형은 문자열을 비교할 때 두 문자열 크기가 다르면 공백을 채워서 비교한다.

 

즉, 두 개의 문자열을 비교했을 때 글자 수가 더 적은 쪽에 공백을 붙여 길이를 똑같이 만든 다음 비교한다.

 

 

하지만 데이터를 꺼낼 때는 공백이 제거 되면서 나오기에 문제가 풀린 것 같다.

 

참고)

CHAR 형과 VARCHAR 형은 설정 크기보다 입력받은 문자열의 크기가 크면 뒤 문자들을 잘라서 저장한다는 공통점이 있지만

 

VARCHAR의 경우는 처음부터 입력받은 문자열의 크기만큼만 공간을 차지하므로 만약 VARCHAR(5)라고 되어 있다면 'admin '을 입력했을 시 맨 뒤의 공백문자를 빼버리는 것이다.

 


https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/eval

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf

 

'a'와 'a '는 TRUE를 반환한다 : https://techblog.woowahan.com/2559/

반응형

'전쟁 > Webhacking.kr' 카테고리의 다른 글

[Webhacking.kr] old-61  (0) 2022.07.19
[Webhacking.kr] old-59  (0) 2022.07.19
[Webhacking.kr] old-39  (0) 2022.07.13
[Webhacking.kr] old-3  (0) 2022.07.13
[Webhacking.kr] old-27  (0) 2022.07.13

+ Recent posts