作者b0920075 (Void)
看板C_and_CPP
标题[问题] 这个ret2text的exploit问题
时间Thu Nov 3 14:00:52 2016
开发平台(Platform): (Ex: Win10, Linux, ...)
linux
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
gcc -zexecstack -fno-stack-protector
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
问题(Question):
其实不知道能不能发到这里,但是资安版太少人,这又跟C有一点点关系就发到这里了,不妥麻烦版主删掉QQ
我自己在看大神教学影片学习的时候看到一个exploit,对大神的注解有点疑问
这是影片中的有洞的程式source code:
http://imgur.com/a/uogvP
环境下只有开ASLR,其他DEP和stack protector没开
这是大神的exploit(python写的,我只撷取部分):
http://imgur.com/a/gZcKS
补上完整版的:
http://imgur.com/a/Uj6nZ
後面加上r.interactive()就是完整版的exploit了
我的理解是:里面的'A'*112是padding,p32(0x08048310)是gets@plt的位址,後面的两个位址(0x0804b000-0x100)应该是要用gets写shellcode到该地址下然後再利用gets的ret address跳转过去
到0x08048310(gets@plt位址)的时候会push ebp→mov ebp,esp所以stack会变成
High
-------
'AAAA'
--------
p32(0x08048310) ......这边是用overwrite掉main的ret address
--------
p32(0x0804b000 - 0x100) ......1
--------
p32(0x0804b000-0x100) ......2
--------
old ebp
--------
Low
然後1那个address会被当成gets的参数也就是写入shellcode的地方(因为先push参数)
2那个地址就会被当成ret address,所以结束gets的时候ret会pop eip然後跳转
可是这样就跟影片中的注解颠倒,请问是我哪里搞错了吗?
喔喔我懂了
喂入的资料(Input):
预期的正确结果(Expected Output):
错误结果(Wrong Output):
程式码(Code):(请善用置底文网页, 记得排版)
补充说明(Supplement):
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.117.182.39
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1478152856.A.783.html
※ 编辑: b0920075 (140.117.182.39), 11/03/2016 14:02:22
1F:→ Schottky: 这个 exploit 根本不能用吧 11/03 14:46
2F:→ b0920075: 喔喔这个只是测试有没有跳过去啦,我没有截送shellcode 11/03 14:49
3F:→ b0920075: 的图,想说那边不是我要问的重点 11/03 14:49
4F:→ Schottky: 你的理解没错,呼叫时先 push 参数再 push ret address 11/03 14:58
5F:→ Schottky: 所以我觉得是写 exploit 的人完全弄反了 11/03 14:59
6F:→ Schottky: gets 填资料是由低位址向高位址填,就算 overflow 11/03 14:59
7F:→ Schottky: 也根本不会盖到 gets 的 return address 11/03 15:00
8F:→ Schottky: 你确定原始的 exploit 真的能用? 11/03 15:01
9F:→ b0920075: 我上面那个只是撷取exploit的一部分而已,原本的测试过 11/03 15:02
10F:→ b0920075: 可以用 11/03 15:02
11F:→ b0920075: 等下补放完整的 11/03 15:03
※ 编辑: b0920075 (140.117.168.190), 11/03/2016 15:35:38
12F:→ Schottky: 这 exploit 还是一样怎麽看都不对 11/03 15:40
13F:→ Schottky: 通常 padding 也是用 0x90 (NOP) 而不会用 'A' 11/03 15:42
14F:→ Schottky: 不过重点还是 gets 的 return address 并不会被盖到 11/03 15:42
15F:→ Schottky: 会被盖到的是 main() 的 return address 11/03 15:42
16F:→ Schottky: 所以我有点好奇,你是怎麽确定这 exploit 可以用的 11/03 15:43
17F:→ b0920075: 呃因为我测过可以用,然後他main ret address被盖成get@ 11/03 16:04
18F:→ b0920075: plt,所以後面gets的利用应该是自己做一个ret address让 11/03 16:04
19F:→ b0920075: 他跳而不是一般的覆盖 11/03 16:04
20F:→ b0920075: 至於nop sled我个人习惯也是写\×90啦,可是那是因为之 11/03 16:06
21F:→ b0920075: 前做的需要跳回buf让他滑,如果没有要跳回buf应该填A也 11/03 16:06
22F:→ b0920075: 没关系 11/03 16:06
23F:→ Schottky: 那听起来被盖到的是 main 而不是 gets 的 return addres 11/03 16:13
24F:→ Schottky: 但还是很不对劲,buf 里都填满 A 了,shell code 是写到 11/03 16:15
25F:→ Schottky: 哪里去? 11/03 16:15
26F:→ Schottky: 你既然知道 nop sled 那应该知道一般就是把 shell code 11/03 16:16
27F:→ Schottky: 填在 stack 的 char buf[100] 里面,免得出别的槌啊... 11/03 16:16
28F:→ b0920075: 因为有开aslr,所以应该是写到全域变数(即使开aslr也不 11/03 16:17
29F:→ b0920075: 会变)那个section里面吧 11/03 16:17
30F:→ b0920075: 因为global不会变,所以尽量写在global里面,讲师是这样 11/03 16:18
31F:→ b0920075: 讲的 11/03 16:18
32F:→ Schottky: Intel 组合语言里叫他 data segment ... 我懂你的意思了 11/03 16:19
33F:→ Schottky: 不过我还是觉得位置关系对不上 11/03 16:20
34F:→ Schottky: 可能这边的 calling convension 和我以前学的不太一样了 11/03 16:21
35F:→ b0920075: 啊记错惹><我老是把section segment搞错 11/03 16:21
36F:→ Schottky: 那个 'A' 为什麽是填 112 个,这一点我一直想不透 11/03 16:25
37F:→ b0920075: 这是buffer到ebp位置的byte数,测出来的 11/03 16:28
38F:→ Schottky: 可能是 main() 的某些特殊参数吧? 虽然原始码没写出来 11/03 16:31
39F:→ Schottky: 啊,main 的参数应该放在 main 的 ret addr 前面才对 11/03 16:32
※ 编辑: b0920075 (140.117.247.163), 11/04/2016 12:01:31