crypto
AAAAAAAA·真·签到
根据题目描述很容易能想到凯撒密码。
凯撒枚举解密一下。
不是原始的,是一种凯撒密码的变形,根据flag的开头为TGCTF,就可以推算出偏移量为-1,0,1,2....。编写脚本还原。(只对大写字符进行偏移,其他字符不变)- base = -1
- ciphertext = "UGBRC{RI0G!O04_5C3_OVUI_DV_MNTB}"
- plaintext = ""
- for i in ciphertext:
- if i.isupper():
- start = ord("A")
- plaintext += chr((ord(i) - start + base) % 26 + start)
- else:
- plaintext += i
- base += 1
- print(plaintext) # TGCTF{WO0O!Y04_5R3_GOOD_AT_MOVE}
复制代码 mm不躲猫猫
给出了多组nc,考的就是RSA的公因数攻击。
这些nc还都是一个明文m,通过对不同的n进行gcd()算法,求出最大公约数,(即p)
求出P了,就能求出q,进而求出d, 解出明文m。费克特尔
yafu工具分解素数。
得到几个素因数后,就可以写脚本获取明文了。- import gmpy2
- import libnum
- c = 670610235999012099846283721569059674725712804950807955010725968103642359765806
- n = 810544624661213367964996895060815354972889892659483948276203088055391907479553
- e = 65537
- P1 = 113
- P2 = 18251
- P3 = 2001511
- P4 = 214168842768662180574654641
- P5 = 916848439436544911290378588839845528581
- phi = (P1 - 1) * (P2 - 1) * (P3 - 1) * (P4 - 1) * (P5 - 1)
- d = gmpy2.invert(e, phi)
- m = pow(c, d, n)
- print(libnum.n2s(int(m))) # b'TGCTF{f4888_6abdc_9c2bd_9036bb}'
复制代码 宝宝rsa
第一部分知道p、q,不知道e,但e的数值比较小,可以采用爆破的方式获得第一部分flag。第二部分知道n、e,一开始想通过yafu工具分解n,但长时间没有得到结果,e很小,所以可以直接n进行开方获得第二部分flag。- from Crypto.Util.number import *
- import gmpy2
- from tqdm import *
- p1 = 8362851990079664018649774360159786938757293294328116561219351503022492961843907118845919317399785168488103775809531198339213009936918460080250107807031483
- q1 = 8312546034426788223492083178829355192676175323324230533451989649056072814335528263136523605276378801682321623998646291206494179416941978672637426346496531
- c1 = 39711973075443303473292859404026809299317446021917391206568511014894789946819103680496756934914058521250438186214943037578346772475409633145435232816799913236259074769958139045997486622505579239448395807857034154142067866860431132262060279168752474990452298895511880964765819538256786616223902867436130100322
- n2 = 103873139604388138367962901582343595570773101048733694603978570485894317088745160532049473181477976966240986994452119002966492405873949673076731730953232584747066494028393377311943117296014622567610739232596396108513639030323602579269952539931712136467116373246367352649143304819856986264023237676167338361059
- c2 = 51380982170049779703682835988073709896409264083198805522051459033730166821511419536113492522308604225188048202917930917221
- e2 = 3
- # 第一部分flag
- m1 = ""
- phi_1 = (p1 - 1) * (q1 - 1)
- for i in trange(2**19):
- if GCD(i, phi_1) == 1:
- d1 = gmpy2.invert(i, phi_1)
- m1 = long_to_bytes(pow(c1, d1, p1*q1))
- if b"TGCTF" in m1:
- break
- # 第二部分
- m2 = ""
- for i in trange(2 ** 19):
- if gmpy2.iroot(c2, 3)[1]:
- m2 = long_to_bytes(gmpy2.iroot(c2, 3)[0])
- break
- c2 += n2
- print(m1 + m2)
复制代码
misc
这是啥o_o
查看文件头为gif,修改后缀。
用stegsolve查看,在23帧到31帧之间有破碎的二维码碎片。
将其拼接好,保存。
汉信码识别,得到内容:time is your fortune ,efficiency is your life。根据提示可以知道是gif的帧间隔隐写,利用puzzlesolver工具进行提取。
用脚本将每个数都除以10,转换成ascii字符即可拿到flag。- lst = ['840', '710', '670', '840', '700', '1230', '890', '1110', '1170', '950', '990', '970', '1170', '1030', '1040', '1160', '950', '1170', '1120', '950', '1190', '1050', '1160', '1040', '950', '1160', '1050', '1090', '1010', '330', '1250']
- for i in lst:
- print(chr(int(i)//10), end="") # TGCTF{You_caught_up_with_time!}
复制代码 ez_zip
加密压缩包,不是伪加密,只能利用archpr暴力破解,一般这种密码应该不会太难,破解得到密码20250412。
解压又得到一个加密压缩包和sh512.txt文件。
尝试用文件里的内容当作密码去解密,不行。想到文件名,是不是需要进行sha512加密呢。再看到加密压缩包的压缩方式为deflate,很可能就是明文攻击了。将sha512加密的内容保存为txt文件,并压缩得到mingwen.zip。
两个文件的crc一样了。
利用archpr进行明文攻击,如果长时间没接出来,直接停止也可以拿到解密的压缩包。
发现解压的时候提示压缩包错误,强行解压打开,一堆垃圾。
用winrar的修复功能也不行。只能去研究zip的文件格式了。第8~9个字节代表的是压缩方式,HxD中没有没有看到明文flag,但是压缩算法却为store,这里修改为DEFLATE。
第28个字节代表文件名的长度(即1A的位置),如果不知道怎么改,可以自己新建几个看看。
就是文件名多长,1A的位置就改为多少,故将flag.zip的这个位置改成08。
再无视损坏解压,就可以拿到flag了。
你能发现图中的秘密吗?
解压得到加密压缩包和一张图片,利用zsteg命令拿到key。
解压拿到一张图片和一个pdf。对图片进行隐写等命令的梭哈,没有发现。用010 editor打开运行png template,里面有多个IDAT块。
通过计算每个IDAT块的大小可以知道最后一个IDAT块是有问题的。计算方法如下:
- 第一个IDAT块的大小为8192.
- 每个IDAT块数据的起始位置为第9个字节,如下图中就是以789c开头,起始位置为0x29。
- IDAT块的最后四个字节为当前IDAT块的CRC值,故数据的结束位置在其前面,结束位置为0x2028。
- 结束位置减去起始位置的值再加1刚好是IDAT块的大小,说明IDAT块没问题。
最后一个IDAT块的大小读出来为48809。
通过结束位置减起始位置的方法计算出来为48808。
可以判断当前IDAT块是有问题的,通过tweak软件将其他的IDAT块删除。
查看感觉像是字符错乱。
利用puzzlesolver软件爆破宽高,拿到前半部分flag。
用ps打开pdf,发现两个图层,其中一个图层有部分flag。
两者拼接即可得到flag。flag{you_are_so_attentive_and_conscientious}
你的运气是好是坏?
纯属脑残题,完全没有做题的逻辑,也不知道是什么烂梗,这题可以不用看了。flag{114514}
where it is(osint)
直接截取部分图片谷歌识图。
是台北市立內湖高級工業職業學校,搜索关键词,可以知道是港墘站
next is the end
一个嵌套了无数层的文件夹,直接利用FileSeek工具找到flag.txt。
双击打开即可拿到flag。
web
前端GAME
查看前端代码没有发现,那就先玩一玩吧,玩到20分左右结束游戏提示flag的位置。
去访问没有内容。看到页面的标题Vue3 Game With Vite,猜测是不是跟Vue3 vite的漏洞相关,搜到Vite任意文件读取漏洞预警(CVE-2025-30208),看下利用方式(https://blog.csdn.net/IDHALASHAO/article/details/146611941) 。
访问http://127.0.0.1:63238/tgflagggg?import&raw??拿到flag。
前端GAME Plus
根据上面一题的经验,肯定也是跟vite任意文件读取漏洞相关的,可以去CVE官网搜索相关漏洞。
经过尝试,这题是CVE-2025-31486,相关文章可参考https://blog.csdn.net/qq_44159028/article/details/147150357 。
按照poc去访问拿到flag。
http://127.0.0.1:58248/tgflagggg?.svg?.wasm?init
进行base64解码即可。
或者http://127.0.0.1:58248/app?/../../../../../tgflagggg?import&?raw#/pc这个poc也行。
前端GAME Ultra
这题是CVE-2025-32395,查看利用方式(https://xz.aliyun.com/news/17745) 。
根据文章所讲,先访问@fs/tmp,可以拿到实际请求的访问路径/app。
所以poc就是curl --request-target /@fs/app/#/../../../../../../tgflagggg http://127.0.0.1:61565/。
AAA偷渡阴平
关键是要绕过preg_match函数的匹配,由于这里过滤的函数比较多,但是可以采用无参数rce的方式进行绕过,具体方法可参考RCE篇之无参数rce。
利用get_defined_vars()函数获取所有的变量。
用到current()函数,这个函数的作用是返回数组中的当前单元,而它的默认是第一个单元,也就是我们GET方式传入的参数
这里可以看到成功输出了我们二维数组中的第一个数据,也就是将GET的数据全部输出了出来,相当于它就已经变成了一个一维数组了,那按照我们上面的方法,我们就可以利用end()函数以字符串的形式取出最后的值,然后直接eval执行就行了。
AAA偷渡阴平(复仇)
这题较上一题过滤了很多函数,所以无参数RCE就行不通了。
剩下能用的就只有2了。跟2相关的函数还有个hex2bin,将16进制转为字符串执行。可参考如下图片。
但因为题目里过滤了eval,用system来代替。
告知session已被启动,就不能再修改了。
所以需要对这个poc执行顺序进行改变。
火眼辩魑魅
查看源代码,没有提示,没思路的情况下只能用御剑扫描了。
找到一个robots.txt,访问一下。
发现了6个文件,每个都访问一遍,其中tgupload.php可能是个文件上传漏洞,tgshell.php可能是个任意命令执行漏洞,tgser.php可能是个反序列化漏洞,tgphp.php可能是个任意命令执行漏洞,tginclude.php可能是个任意文件包含漏洞。但是结合主页面的提示shell学姐,所以最有可能的应该是tgshell.php。直接用蚁剑连接,成功!在根目录下看到tgfffffllllaagggggg文件。
打开即是flag。
(ez)upload
上传个一句话木马,被拦截,经过尝试,进行了后缀名白名单识别,内容检测,但是具体的防护措施无从而知。经过御剑的扫描,得到个index.php.bak。
既然index.php都有备份,那upload.php会不会也有备份呢?访问一下,果真有。- <?php
- define('UPLOAD_PATH', __DIR__ . '/uploads/');
- $is_upload = false;
- $msg = null;
- $status_code = 200; // 默认状态码为 200
- if (isset($_POST['submit'])) {
- if (file_exists(UPLOAD_PATH)) {
- $deny_ext = array("php", "php5", "php4", "php3", "php2", "html", "htm", "phtml", "pht", "jsp", "jspa", "jspx", "jsw", "jsv", "jspf", "jtml", "asp", "aspx", "asa", "asax", "ascx", "ashx", "asmx", "cer", "swf", "htaccess");
- if (isset($_GET['name'])) {
- $file_name = $_GET['name'];
- } else {
- $file_name = basename($_FILES['name']['name']);
- }
- $file_ext = pathinfo($file_name, PATHINFO_EXTENSION);
- if (!in_array($file_ext, $deny_ext)) {
- $temp_file = $_FILES['name']['tmp_name'];
- $file_content = file_get_contents($temp_file);
- if (preg_match('/.+?</s', $file_content)) {
- $msg = '文件内容包含非法字符,禁止上传!';
- $status_code = 403; // 403 表示禁止访问
- } else {
- $img_path = UPLOAD_PATH . $file_name;
- if (move_uploaded_file($temp_file, $img_path)) {
- $is_upload = true;
- $msg = '文件上传成功!';
- } else {
- $msg = '上传出错!';
- $status_code = 500; // 500 表示服务器内部错误
- }
- }
- } else {
- $msg = '禁止保存为该类型文件!';
- $status_code = 403; // 403 表示禁止访问
- }
- } else {
- $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
- $status_code = 404; // 404 表示资源未找到
- }
- }
- // 设置 HTTP 状态码
- http_response_code($status_code);
- // 输出结果
- echo json_encode([
- 'status_code' => $status_code,
- 'msg' => $msg,
- ]);
复制代码 发包成功。
从upload.php.bak中得知上传文件的目录在uploads目录下,访问。
可以看到一句话木马没有显示,说明被执行了,用蚁剑连接,但在根目录下没看到flag。
最后通过执行phpinfo命令找到flag。
什么文件上传?
又是一堆尝试,被拦截,查看页面源代码,有个提示。
提示我们可能有robots.txt文件,扫描一下确实存在。
访问一下。
有个class.php文件,看一下。
[code] |