2012.05.01
$ cat test.c
#include<stdio.h>
#include<unistd.h>
main(){
setreuid(500,500);
execl("/bin/sh","sh",0);
}
테스트할 프로그램은 다음과 같다.
추적하기 수월하도록 gdb에서 실행후 disp/i $pc를 이용해보자.
ebp값 +8 한곳에서 setreuid 인자 참조 확인
ebp값 +12 한곳에서도 setreuid 인자 참조 확인
1: x/i $pc 0x7d9869 <setreuid+9>: mov 0x8(%ebp),%edx
(gdb) info reg eax ebx ecx edx
eax 0x10 16
ebx 0x83eff4 8646644
ecx 0x1 1
edx 0x84119c 8655260
(gdb) ni
0x007d986c in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d986c <setreuid+12>: call 0x730c71 <__i686.get_pc_thunk.bx>
(gdb) info reg eax ebx ecx edx
eax 0x10 16
ebx 0x83eff4 8646644
ecx 0x1 1
edx 0x1f4 500
ebp+8한곳의 값을 edx에 넣었다.
(gdb) info reg ebp
ebp 0xfeedb898 0xfeedb898
(gdb) x/12bx 0xfeedb898
0xfeedb898: 0xc8 0xb8 0xed 0xfe 0xce 0x83 0x04 0x08
0xfeedb8a0: 0xf4 0x01 0x00 0x00
(gdb) ni
0x007d9871 in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d9871 <setreuid+17>: add $0x65783,%ebx
(gdb) info reg eax ebx ecx edx
eax 0x10 16
ebx 0x7d9871 8231025
ecx 0x1 1
edx 0x1f4 500
(gdb) ni
0x007d9877 in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d9877 <setreuid+23>: mov %esi,0xfffffffc(%ebp)
(gdb) info reg eax ebx ecx edx
eax 0x10 16
ebx 0x83eff4 8646644
ecx 0x1 1
edx 0x1f4 500
(gdb) info reg esi
esi 0xfeedb954 -17974956
(gdb) x/16bx 0xfeedb954
0xfeedb954: 0x2f 0xdc 0xf6 0xfe 0x00 0x00 0x00 0x00
0xfeedb95c: 0x3f 0xdc 0xf6 0xfe 0x58 0xdc 0xf6 0xfe
(gdb) x/s 0xfeedb954
0xfeedb954: "/俯"
(gdb) x/16bx $ebp-4
0xfeedb894: 0xf8 0x94 0x71 0x00 0xc8 0xb8 0xed 0xfe
0xfeedb89c: 0xce 0x83 0x04 0x08 0xf4 0x01 0x00 0x00
(gdb) x/i 0x7194f8
0x7194f8: add %al,(%eax)
(gdb) x/x 0x7194f8
0x7194f8: 0x00
(gdb) x/4bx 0x7194f8
0x7194f8: 0x00 0x00 0x00 0x00
(gdb) ni
0x007d987a in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d987a <setreuid+26>: mov 0xc(%ebp),%ecx
(gdb) info reg esi
esi 0xfeedb954 -17974956
(gdb) x/16bx $ebp-4
0xfeedb894: 0x54 0xb9 0xed 0xfe 0xc8 0xb8 0xed 0xfe
0xfeedb89c: 0xce 0x83 0x04 0x08 0xf4 0x01 0x00 0x00
(gdb) x/4bx $ebp+12
0xfeedb8a4: 0xf4 0x01 0x00 0x00
(gdb) info reg eax ebx ecx edx
eax 0x10 16
ebx 0x83eff4 8646644
ecx 0x1 1
edx 0x1f4 500
(gdb) ni
ebp+12한곳의 값을 ecx로 넣어준다.
Breakpoint 3, 0x007d987d in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d987d <setreuid+29>: xchg %edx,%ebx
(gdb) info reg eax ebx ecx edx
eax 0x10 16
ebx 0x83eff4 8646644
ecx 0x1f4 500
edx 0x1f4 500
edx의 값을 ebx와 바꾼다.(결과적으로 아까 가져온 500이 ebx에 들어간다.)
(gdb) ni
0x007d987f in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d987f <setreuid+31>: mov $0xcb,%eax
(gdb) info reg eax ebx ecx edx
eax 0x10 16
ebx 0x1f4 500
ecx 0x1f4 500
edx 0x83eff4 8646644
setreuid의 시스템호출넘버인 0xcb(203)을 eax에 넣는다.
$ cat /usr/include/asm/unistd.h |grep setreuid32
#define __NR_setreuid32 203
(gdb) ni
0x007d9884 in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d9884 <setreuid+36>: call *%gs:0x10
(gdb) info reg eax ebx ecx edx
eax 0xcb 203
ebx 0x1f4 500
ecx 0x1f4 500
edx 0x83eff4 8646644
(gdb) info reg gs
gs 0x33 51
(gdb) si
0x007037a0 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
1: x/i $pc 0x7037a0 <_dl_sysinfo_int80>: int $0x80
(gdb) info reg eax ebx ecx edx
eax 0xcb 203
ebx 0x1f4 500
ecx 0x1f4 500
edx 0x83eff4 8646644
(gdb) si
_dl_sysinfo_int80함수에 진입하여 인터럽트 0x80과 ret 수행
0x007037a2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
1: x/i $pc 0x7037a2 <_dl_sysinfo_int80+2>: ret
(gdb) si
0x007d988b in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d988b <setreuid+43>: xchg %edx,%ebx
(gdb) ni
0x007d988d in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d988d <setreuid+45>: cmp $0xfffff000,%eax
(gdb) info reg eax ebx ecx edx
eax 0x0 0
ebx 0x83eff4 8646644
ecx 0x1f4 500
edx 0x1f4 500
아까 ebx와 edx를 바꾼것을 되돌린다.
eax는 0으로 초기화시킨다.
(gdb) ni
0x007d9892 in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d9892 <setreuid+50>: mov %eax,%esi
(gdb) info reg eax ebx ecx edx
eax 0x0 0
ebx 0x83eff4 8646644
ecx 0x1f4 500
edx 0x1f4 500
(gdb) info reg esi
esi 0xfeedb954 -17974956
(gdb) ni
0x007d9894 in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d9894 <setreuid+52>: ja 0x7d98d5 <setreuid+117>
(gdb) info reg esi
esi 0x0 0
esi에 0이된 eax를 옮긴다.
(gdb) ni
0x007d9896 in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d9896 <setreuid+54>: test %eax,%eax
eax를 서로 비교한다.(널값체크인가)
(gdb)
0x007d9898 in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d9898 <setreuid+56>: jne 0x7d98a4 <setreuid+68>
(gdb)
0x007d989a in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d989a <setreuid+58>: mov 0x3b98(%ebx),%eax
(gdb)
0x007d98a0 in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d98a0 <setreuid+64>: test %eax,%eax
(gdb)
0x007d98a2 in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d98a2 <setreuid+66>: jne 0x7d98b0 <setreuid+80>
(gdb)
0x007d98a4 in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d98a4 <setreuid+68>: mov %esi,%eax
(gdb)
0x007d98a6 in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d98a6 <setreuid+70>: mov 0xfffffff8(%ebp),%ebx
(gdb)
0x007d98a9 in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d98a9 <setreuid+73>: mov 0xfffffffc(%ebp),%esi
(gdb)
0x007d98ac in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d98ac <setreuid+76>: mov %ebp,%esp
(gdb)
0x007d98ae in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d98ae <setreuid+78>: pop %ebp
(gdb)
0x007d98af in setreuid () from /lib/tls/libc.so.6
1: x/i $pc 0x7d98af <setreuid+79>: ret
(gdb)
여기까지가 setreuid()이다 반환후 메인으로 돌아간다.
0x080483ce in main ()
1: x/i $pc 0x80483ce <main+46>: add $0x10,%esp
결론 : setreuid 함수호출후 ebp+8, ebp+12에 리틀엔디언 방식으로 인자를 넘기면 된다.
0xf4 0x01 0x00 0x00
재미있는것은 disp/i $pc를 이용해보니까 leave같은것도 분리해서 보여준다는점ㅎㅎ
ps : system 함수는 달고나님 문서{
buffer_overflow_foundation_pub.pdf
}에서 확인해보자.
'Study > BOF' 카테고리의 다른 글
[POC 2013] Power of xx 여성해킹대회 본선 Pwning CGI (250) Write-up (0) | 2013.11.11 |
---|---|
NX, ASLR(only stack), Ascii-Armor 우회(미완성 소스공개) (0) | 2012.08.13 |
BOF 원정대 RedHat 풀이보고서 (0) | 2012.06.06 |
[Linux BOF 원정대 Red Hat 6.2] START (2) | 2011.09.22 |