UTCTF 2024 个人题解
Lysithea 10583 45th
德克萨斯州立大学的两日校赛,题量不大但是难度在校赛里算是中等偏上的,misc以外各个分类基本都至少一道1000大题。我也一如既往的垃圾题杀手,会做的题大家基本都会,被动态分干到从20名掉到40名(第一名20000分,基本上all clear了),1000分大题基本没有能做出来的。
第一天基本垃圾题全清了,第二天专攻rev的In the Dark和pwn的Webserver,有点分散精力了,如果全力打webserver说不定能打下来。
Crypto
Crypto分类整体难度是偏低的,除了最后一个偏逆向的1000分题(forgery)看不懂
RSA-256
基本是签到题。RSA-256也就是用到大整数分解的质数大小是256位的,这个大小的质数是可以暴力分解,或者说查表的(factordb.com)
flag是utflag{just_send_plaintext}确实这种级别的加密不如直接给明文好了
numbers go brrr (2问)
这题感觉在考伪随机但感觉考的不深入。
作者自己实现了一个伪随机数,但种子范围在randint(0, 100000)。之后用这个伪随机生成密钥,对信息进行AES加密。
第一问你可以无限次对自己的信息加密获得密文,最后服务器会返回flag的密文。事实上只用一段明文就可以爆破出随机数种子,然后就知道加密flag时使用的key了(注意两个key不一样,第二个key是第一个key的后续)
第二问前面一样可以无限次获得任意信息密文,之后要猜key。但是同样一次明文就可以爆出seed,然后key就知道了。这样的猜一共有三次, 之后给flag。
这个flag表明出题人也放弃治疗了:
utflag{ok_you_are_either_really_lucky_or_you_solved_it_as_intended_yay}
bits and pieces
非常单纯的RSA题,给了三对N, e, c对,N很大,e=65537,看似无懈可击。
事实上第二组和第三组的共享公因数(gmpy2.gcd),因而可以直接分解。第一组没怎么看出来,但放到yafu里一跑就出来了,实际上两个因数大小十分接近(N本身非常接近一个整数的平方),所以也很容易分解。
Cryptordle
有点意思的一个题,相当于wordle。题目会根据一个字典(大概率是有意义的英文单词)生成一个五个字母的单词,然后我们有6次机会猜中。每次的反馈诸位字符差模31的乘积。
response = 1
for x in range(5):
a = ord(guess[x]) - ord('a')
b = ord(answer[x]) - ord('a')
response = (response * (a-b)) % 31
print(response)
这个题我用的方法是概率成功的(所以不是预期解,至少是预期解的弱化版),我用了一个弱化的策略,构造五组固定输入,通过5次反馈唯一解算答案(之所以是弱化,因为后四次可以通过之前的结果优化输入,这个应该可以优化成100%的方法)。假设答案为x1 x2 x3 x4 x5,这里每个数是0-25的整数
- 第一轮给
aaaaa,获得的O=x1*x2*x3*x4*x5 - 第二轮给
baaaa,获 得A=(x1-1)*x2*x3*x4*x5,则O*inv(O-A)即x1,其中inv是模31意义下的逆。 - 第三四五轮给
abaaa,aabaa,aaaba,基于同样原理可以算出x2,x3,x4 x5的值可以直接O * inv(x1*x2*x3*x4)
这个方法成功条件是每一步都可以逆,求逆的子串不能被31整除(或者说,不能有a)。我认为这个题应该是可以通过一种构造保证无论要猜什么都能成功的。我中间也想过这个题是不是能随机输入+Z3解算,不过好像计算量还是太大Z3搞不出来,看来还是需要精妙构造。
我现在又想了想,是不是要求被猜的答案里没有a就能猜出来?如果这样那用q这样的非常见字母来作为基底可能更容易。
据说主办方为了堵概率性的非预期中间才把题目改成需要猜中3次的,笑死。
simple signature
有点不知所云的题,题目信息只说了根据RSA实现了个签名机制,然后就只给了一个nc。连上去后,是这样的信息:
Welcome to the signature generator!
This service generates signatures for nonnegative integer messages.
Today's RSA parameters are:
n = (一个很大的整数)
e = 65537
Enter a message as an integer (enter 0 to stop):
然后我们可以无限次输入整数(虽然prompt说只能输入非负数,但是是可以输入的),似乎会进行RSA加密返回C。当输入0后,题目要求我们提供一组没有输入过的数字+签名。
一开始我没什么思路,直到我随机fuzz出来输入-1, 1, -1之后,给出的值一定是1。在RSA加密这种平均数字长度好几行的加密里出现1这种密文,一定是不正常的,这基本只代表一种情况,就是明文是1。
虽然到这一步就能拿flag了(utflag{a1m05t_t3xtb00k_3x3rc153}),但我们仍然搞不懂这到底是什么算法。另外1, -1给出的一定是1, 0,也是可以拿的
Forensics
取证里有一些挺有想法的题,但是我弱取证。共8个题做出4个。
Contracts
一眼GG签到题。PDF里藏了一张图片,Acrobat打开后,编辑模式拖出来,人眼OCR即可
A Very Professional Website
给了一个网站,基本啥都没有。我也不知道我怎么就想到看一眼/.git的,结果报403了。这个可是非常大的收获,说明可以直接访问git仓库,dump出所有内容(我用的git-dumper)
看一眼历史记录里没有异常,所以还是把所有objects全部打印出来比较好。这里记录一下命令:
# use this to print all objects in git repo, including ref log
git rev-list --objects -g --no-walk --all
# or alternatively
git cat-file --batch-check --batch-all-objects
# use this to print
git cat-file -p 1d2961fb02140ea819212ac081b0291c323fd056
# in git ref log?
# utflag{gitR3fl0g}
OSINT (2/3问)
包含三问的一个有故事线的开盒题,挺有意思的。
OSINT1 (泄露文档)
给了一个名为KAKUU公司的门户主页,要求我们寻找这家公司泄露的文档(公司当然是假的,不是同名的日本公司)
一开始我搞错方向,在网页上找了半天,还扒出了他们用的模板是Bootstrap Arsha。不过这毕竟不是Web题,出题人也放出hint说这个题显然不应该在公司主页上找泄露的文档。
后来我注意到主页上,公司人员介绍里,提到名为Cole Minerton(后面简称CM)的员工运营着公司的社交媒体,于是我开始google/duckduckgo找这个人。之后我在几个 地方找到了他。
- Youtube上有一个号,关注很少(说明是个人号不是专业视频号),发布了一个游戏的速通视频,只有一个人互动,互动那个人好像是真的是来互动的。主页简介有个discord群聊,但这个群聊里竟然有200多人,有点反常。
- twitter(X)有号,整个账号只有一条推,在2月25日左右说自己不在这里活动了,有linktree链接,还指向上面说的youtube,一个reddit(好像没什么信息),和一个名为Mastodon的社交平台,类似facebook。
- Mastodon上记录基本也是2月25日左右开始,有大概7条动态,其中一条提到了Kakuu Company,说明找对位置了。
其实到这里,基本确定那个discord是题目范围内的了,可惜我这时突发社恐恶疾,迟迟不敢点邀请链接,下了好久决心才进去,结果我是没有权限发言的,只有一段2月25日-3月1日左右的群聊记录,涉及CM和他两个朋友(也是Mastodon和他互动的那两个人)。
可以在聊天记录里看到CM和朋友吹逼时把自己签的合同给发出来了(底下还有人接龙💀的反应,我看了我也有权限接龙也就接了一下),flag是明文在其中的。
