首页
社区
课程
招聘
[推荐]看雪.纽盾 KCTF 2019 Q3 | 第一题点评及解题思路
发表于: 2019-9-25 17:17 3742

[推荐]看雪.纽盾 KCTF 2019 Q3 | 第一题点评及解题思路

2019-9-25 17:17
3742


KCTF Q3圆满落幕,感谢所有战队的参与,激烈的战争结束,让我们一起来看看赛题详解吧。


今天为大家带来第一题的点评及解题思路。



题目背景: 大地一片混沌,神明乘坐方舟穿越无边的宇宙,降临大陆,他创造世间最强大的力量——星钻,谁拥有星钻,谁就是天下的王。然而无上的力量滋生欲望,欲望带来战争。暗夜笼罩大陆,奇迹的光芒被掩映。大陆纷争四起,堕世之魔蠢蠢欲动,各路英雄层出不穷。在大陆即将再度轮入黑暗之际,神明带来了希望之光。希望之光能够穿透一切贪嗔痴,引导众生到达正义与胜利。生存或者毁灭,前路风云变幻,抵挡不了他们的脚步。出征吧,战士!

















END



合作伙伴



原文链接:https://mp.weixin.qq.com/s/heHjV40zxWOmCuCatAjvwA



攻破此题的战队排名一览:

接下来我们来对题目进行解析,破解其中的奥秘。



第一题的设计思路非常简单,作为一道签到题,解题成功的队伍的数量是最多的。而这道题也很好体现了新比赛规则:新规则模拟了现实世界中用户可以拿到一组序列号,考查此时攻击者是否能写出注册机。


A)界面

1.防守方发布的Crackme应允许输入用户名和序列号,并提示用户名和序列号是否匹配正确。例如类似的(界面仅供参考,可以是控制台):

┍━━━━━━━━━━━━━━━━━━━━┑
 │            ┌──────┐           │
            │name   └──────┘           │           
│            ┌──────┐           │
            │name   └──────┘           │           
│            ┌──────┐           │
│Serial   └──────┘           │
│        看雪CTF2019             │
┕━━━━━━━━━━━━━━━━━━━━┙


2.防守方在发布CrackMe时,应向大众公开一组用户名和序列号,即 “Name/Serial ”,其中公开的这个用户名“Name“,必须是该CrackMe文件的 hash值。hash算法指定为SHA256,用户名为hash结果的前64bit的16进制大写文字。

例如:参赛CrackMe.exe文件的hash结果是50be38745d82d93f3a974701e86c1cafcbc2ec83d1f1913d216079022ba7317f
则用户名 “Name“应为50BE38745D82D93F

如果CrackMe不止一个文件的话,计算hash时应包含CrackMe的所有文件(第三方共享库除外)。

参考hash计算工具:http://www.atool9.com/file_hash.php


B)判胜条件

1.若攻击方找出特定用户名(“KCTF”,不含引号)的序列号,经KCTF系统自动确认,将认定攻击方获胜;

2.若攻击方找出特定用户名(“KCTF”,不含引号) 的第二个序列号,经KCTF官方确认,将认定攻击方获胜,且此题多解。



出题团队简介


本题出题战队 中娅之戒 :


中娅之戒 团队简介:

又拜各位大佬!
Q3为大家带来了一道速成裸奔签到题(还因为赌赢「5min内会不会被一血」赚了一顿冰激凌。
藏在曹老板广告位的庇护下埋了一枚小彩蛋(不然要麻烦小编改图还会占某A开头友队的便宜。
最近是年纪轻轻打卡上班每天清晨咖啡续命缩在有限域上质疑人生再不来分屏眼睛要瞎了早睡早起热爱生活努力成为年轻富婆包养找工作心碎弟弟的WHU密码学方向在读研(小)究(姑)生(娘)。决赛见!



设计思路



本题运算流程如上图所示:

第一步:接收用户输入的用户名UName和序列号Serial
第二步:UName和Serial异或得到主密钥Mk
第三步:对Mk做摘要Dig(这里使用了MD5)
第四步:判断Dig是否等于目标摘要值Tgt,是→验证正确,否→验证错误破解思路:
由于MD5是一个单向过程,使用相同的Mk,就可以得到相同的Dig。
根据Mk=UName⊕Serial,对于给定的Uname,Serial=Mk ⊕UName即可得到所求Serial。



解题思路


本题解题思路由看雪论坛HHHso提供:


一不小心,拿了一血,也因这个开场坐了“跛豪”【英译:To be NO. 1】的位置半天。

直到大人们看不过眼,给他打上【签到题】,才有后来的群起攻之。

如果真的是看重比赛得分的话,一般都会忽略签到题,因为最终得分太低。

做题的顺序一般也是先攻没人攻破的,这样得分率较高。

一个残酷的事实是,某场公安部、信息部有涉及的CTF赛事中,一些团队攻破赛题数量上颇为可观,可最终却被一些只攻破一个赛题的团队甩几条街,这就是核心决胜策略。

乱世鬼雄,在人生前进的路上,不要给自己设限,尤其是新手,闻道有先后,术业有专攻,管它是人是鬼还是神,搞搞不就知了,开卷有益。

这有点凑字嫌疑,强扯抒情。

言归正传,全部攻击记录如下,回头写WriteUp,差点自己都没看明白:-)

请输入用户名:5D78C3FDF21998AC
请输入序列号:F3A0FD8D8DE1FEB889808A8FF2D7FDA2

C6 E4 CA B5 CE D2 B8 FC CF B2 BB B6 CB EF BC E1
C6 E4 CA B5 CE D2 B8 FC CF B2 BB B6 CB EF BC E1 其 实 我 更 喜 欢 孙 坚


80 00 00 00 00 00 00 00

DA E5 23 10 06 71 95 71 4B A2 CE E2 33 2B B8 66
 
>>> u ='KCTF'+'\x00'*12
>>> u
'KCTF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> x ='C6 E4 CA B5 CE D2 B8 FC CF B2 BB B6 CB EF BC E1'
>>> x.replace(' ','').decode('hex')
'\xc6\xe4\xca\xb5\xce\xd2\xb8\xfc\xcf\xb2\xbb\xb6\xcb\xef\xbc\xe1'
>>> xb = x.replace(' ','').decode('hex')
>>>''.join([chr(ord(u[i])^ord(xb[i]))for iin range(0x10)]).encode('hex')
'8da79ef3ced2b8fccfb2bbb6cbefbce1'
>>>''.join([chr(ord(u[i])^ord(xb[i]))for iin range(0x10)]).encode('hex').upper()
'8DA79EF3CED2B8FCCFB2BBB6CBEFBCE1' 

(1)全局变量数组记录输出的用户名,应当注意到,用户名信息长度是16字节对于不够的长的用户名,通过memset补足零。


(2)接着就是全局变量Hi_keybin记录序列号信息,32字节长度。如下第一张图,keyhex会先进行十六进制解码得到keybin,然后接着是第二张图keybin再十六进制编码得到keybinhex,然后与keyhex比对自校验。



(3)用户名信息(16字节)与keybin(32字节解码得到16字节)异或得到user_xor_key,然后计算user_xor_key的哈希值,hash_of_userXORkey。


(4) 最后hash_of_userXORkey与参考ref_hash比对。


(5)抓住主要矛盾

看到那几个常量,知道是hash就行,不需要知道是SM*还是MD*,这里只需要知道是哈希函数就行。

由于参考hash不变,所以hash的输入内容也不会变(当然,这是个有条件的真理,在王小云教授面前不一定成立)。

由题目提供的用户名和key,我们得到hash的输入内容为:

user_xor_key:=C6 E4 CA B5 CE D2 B8 FC CF B2 BB B6 CB EF BC E1 其 实 我 更 喜 欢 孙 坚

因为user_xor_key = userhex ^ keybin,所以user = KCTF时(补足16字节为:'KCTF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
对应的keybin = user_xor_key ^ userhex
key = keybin.encode('hex')
这就是为何KCTF的key为8DA79EF3CED2B8FCCFB2BBB6CBEFBCE1

>>> u ='KCTF'+'\x00'*12
>>> u
'KCTF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> x ='C6 E4 CA B5 CE D2 B8 FC CF B2 BB B6 CB EF BC E1'
>>> x.replace(' ','').decode('hex')
'\xc6\xe4\xca\xb5\xce\xd2\xb8\xfc\xcf\xb2\xbb\xb6\xcb\xef\xbc\xe1'
>>> xb = x.replace(' ','').decode('hex')
>>>''.join([chr(ord(u[i])^ord(xb[i]))for iin range(0x10)]).encode('hex')
'8da79ef3ced2b8fccfb2bbb6cbefbce1'
>>>''.join([chr(ord(u[i])^ord(xb[i]))for iin range(0x10)]).encode('hex').upper()
'8DA79EF3CED2B8FCCFB2BBB6CBEFBCE1' 



END



合作伙伴


┕━━━━━━━━━━━━━━━━━━━━┙
2.防守方在发布CrackMe时,应向大众公开一组用户名和序列号,即 “Name/Serial ”,其中公开的这个用户名“Name“,必须是该CrackMe文件的 hash值。hash算法指定为SHA256,用户名为hash结果的前64bit的16进制大写文字。

例如:参赛CrackMe.exe文件的hash结果是50be38745d82d93f3a974701e86c1cafcbc2ec83d1f1913d216079022ba7317f
则用户名 “Name“应为50BE38745D82D93F

如果CrackMe不止一个文件的话,计算hash时应包含CrackMe的所有文件(第三方共享库除外)。

参考hash计算工具:http://www.atool9.com/file_hash.php
B)判胜条件

1.若攻击方找出特定用户名(“KCTF”,不含引号)的序列号,经KCTF系统自动确认,将认定攻击方获胜;

2.若攻击方找出特定用户名(“KCTF”,不含引号) 的第二个序列号,经KCTF官方确认,将认定攻击方获胜,且此题多解。
本题出题战队 中娅之戒 :

中娅之戒 团队简介:

又拜各位大佬!
Q3为大家带来了一道速成裸奔签到题(还因为赌赢「5min内会不会被一血」赚了一顿冰激凌。
藏在曹老板广告位的庇护下埋了一枚小彩蛋(不然要麻烦小编改图还会占某A开头友队的便宜。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2019-10-10 13:31 被Editor编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//