第二道题《南充茶坊》历时3天,已于5号中午12点关闭攻击通道。共有2548人围观,最终只有4支团队攻破成功。7HxzZ战队率先攻破此题,一共用时约28小时,可见此题难度很大,Acehub战队和大众代表队的readyu攻势迅猛,金左手战队也迎头赶上,与前几位选手相差不大。
"鸡米花系统第一级开启"
我一睁眼,只见一片塞外风光,往来行人车马络绎,似是个边疆小镇。
起身差点被自己绊倒,才发现竟已换上了缎袍,腰间还有一把折扇("唰"),我成了……古代文人……?
"阁下真是好运气,初次来到就碰上这么个<b>简单</b>关卡。边塞风光可是壮美,只是风沙些许大,阁下不妨先去茶馆避避吧。"
视线扫过四周,我终于看清身后兀然竟立着一座茶馆,风裹着大漠的气息,将门外的旌旗吹得漫卷飞扬,旗上四个大字"南充茶坊"。
一头雾水,进去探探再说。将将落座,却见一六七岁样貌孩童嬉笑着向我跑来。
"大哥哥,刚才有个仙女姐姐来,让我把<b>谜题</b>交给一个摇扇子的大哥哥,应该就是大哥哥你啦!"
又有仙女儿,又有谜题,甚好甚好。
"不过,大哥哥要陪我玩<b>成语接龙</b>,我才把谜题给你。"
成语接龙……?也行也行,为了拿到仙女姐姐的谜题,哥哥就陪你玩儿会。
"既然在我们家的茶馆,就以'茶'字开头吧。大哥哥先来。"
茶余饭后→后来居上→上善若水→水落石出→出其不意→意气用事→事在人为→为所欲为
//众所周知,为所欲为是成语接龙自动机的接受状态,那我换一个
事不关己→己所不欲→欲加之罪→罪孽深重→重义轻利→利诱威逼→逼上梁山→山穷水尽→尽力而为→为所欲为
//emmmmmm,那我再换一个
尽心尽力→力大无穷→穷兵黩武→武偃文修→修身养性→性命攸关→关怀备至→至高无上→上下一心→心猿意马→马首欲东→东遮西掩→掩口卢胡→胡作非为→为所欲为
//怎么又回来了,重来重来
东门黄犬→犬牙差互→互通有无→无可奈何→何乐不为→为所欲为
//……
事出有因→因小失大→大智若愚→愚公移山→山穷水尽→尽力而为→为所欲为
//……
显然,这个小朋友是'有备而来',没准仙女姐姐正躲在哪里看着我们偷笑呢。
怎样才能挽回局面呢……?
这道题考查的范围较为广泛,需要参赛者对密码学、PE文件结构、python反编译等都有一定程度的理解,题目质量较高。因此,攻破此题的参赛者数量也不多。此外,题目writeup的质量较高,值得一看。
4th拜各位大佬!
本次2019KCTF决赛的中娅之戒由4名队员组成:
iiiiiiiiiiii:一个小肥宅,晚上不睡觉,白天起不来
xh1998:国家一级彩蛋制造专家
leafpad:仍旧是萌新
Venessa:深深觉得还是自然科学有意思的密码学方向在读研(小)究(姑)生(娘)
# 我们的征程是吸尘器和云台
# 两只黄鹂鸣翠柳 一行白鹭上青天
v3 = fopen("CM.exe", "rb");
v4 = calloc(0x28131ui64, 1ui64);
fseek(v3, 0x8000, 0);
fread(v4, 1ui64, 0x28131ui64, v3);
LODWORD(v3) = aPsafe_get_orig_size(v4);
v5 = calloc((unsigned int)v3, 1ui64);
aPsafe_depack(v4, 0x28131i64, v5, (unsigned int)v3);
[*] Processing cm.exe
[*] Error : Unsupported pyinstaller version or not a pyinstaller archive
def checkFile(self):
print('[*] Processing {0}'.format(self.filePath))
self.fPtr.seek(self.fileSize - self.PYINST20_COOKIE_SIZE, os.SEEK_SET)
magicFromFile = self.fPtr.read(len(self.MAGIC))
if magicFromFile == self.MAGIC:
self.pyinstVer = 20
print('[*] Pyinstaller version: 2.0')
return True
self.fPtr.seek(self.fileSize - self.PYINST21_COOKIE_SIZE, os.SEEK_SET)
magicFromFile = self.fPtr.read(len(self.MAGIC))
if magicFromFile == self.MAGIC:
print('[*] Pyinstaller version: 2.1+')
self.pyinstVer = 21
return True
print('[*] Error : Unsupported pyinstaller version or not a pyinstaller archive')
return False
from CMpub import pub_n_list, pub_e_list
from general import valid_serial, valid_username, get_enc_seq, enc0
from Crypto.Util.number import bytes_to_long
from os import system
def check(serial, seq):
now = serial
for j in range(len(seq)):
i = seq[j]
n = pub_n_list[i]
e = pub_e_list[i]
if now > pub_n_list[i]:
return False
if i > 0:
now = pow(now, e, n)
else:
now = enc0(now, e, n)
if 0 == now:
return False
return now
def main():
username0 = input('Please input Username:\t')
serial0 = input('Please input Serial:\t')
try:
valid_serial(serial0)
valid_username(username0)
except:
print('\nInvalid Input\n')
return
else:
serial = int(serial0, 16)
username = username0.encode('utf-8')
seq = get_enc_seq(username)
username = bytes_to_long(username)
check_value = check(serial, seq)
if check_value == username:
print('\nCorrect!\n')
else:
print('\nOops! The encrypted Serial is not "' + username0 + '".\n')
system('pause')
if __name__ == '__main__':
main()
from hashlib import sha256
def valid_serial(serial):
assert type(serial) == str
assert len(serial) > 0
if not '0' != serial[0]:
assert 1 == len(serial)
for c in serial:
if not ord('0') <= ord(c) <= ord('9'):
if not ord('A') <= ord(c) <= ord('F'):
raise AssertionError
return serial
def valid_username(username):
assert type(username) == str
assert len(username) > 0
for c in username:
assert ord(c) > 0
return username
def get_enc_seq(username):
h = sha256()
h.update(username)
hash_value = int(h.hexdigest(), 16)
T = 9
S = 10
stat = [0] * (T + 1)
seq = [0]
n = hash_value
while n > 0:
if S * T > len(seq):
now = n % T + 1
if stat[now] < S:
seq.append(now)
stat[now] += 1
n //= T
return seq
def enc0(m, e, n):
nbit = 192
T = (n.bit_length() - 1) // nbit + 1
ans = 0
for i in range(T - 1, -1, -1):
def xxx(x, t):
return x >> t * nbit & (1 << nbit) - 1
now_n = xxx(n, i)
now_e = xxx(e, i)
now_m = xxx(m, i)
if now_m >= now_n:
return 0
ans = (ans << nbit) + pow(now_m, now_e, now_n)
return ans
检查用户名及序列号格式
用户名编码成0开头的其余皆为1-9的数字序列
通过数字序列和序列号计算对应的用户名
利用计算出的用户名校验输入用户名
试除法(Trial division)
轮式因子分解法(Wheel factorization)
Pollard's rho算法(Pollard's rho algorithm)
代数群因子分解算法(Algebraic-group factorisation algorithms),包括:
Pollard's p-1算法(Pollard'sp−1 algorithm)
Williams' p+1算法(Williams'p+1 algorithm)
Lenstra椭圆曲线因子分解法(Lenstra elliptic curve factorization)
费尔马因子分解法(Fermat's factorization method)
欧拉因子分解法(Euler's factorization method)
特殊数域筛选法(Special number field sieve, SNFS)
Dixon's算法(Dixon's algorithm)
连分数因子分解法(Continued fraction factorization, CFRAC)
二次筛选法(Quadratic sieve)
自然筛选法(Rational sieve)
普通数域筛选法(General number field sieve, GNFS)
二次剩余因子分解法(Shanks' square forms factorization, SQUFOF)
Wiener’s attack
模数公约数
def de_cofactor():
l = [3,4,5,6,7,8,9]
for idx1 in l[:-1]:
tmp = l.index(idx1)
for idx2 in l[tmp+1:]:
n1 = pub_n_list[idx1]
n2 = pub_n_list[idx2]
fa = gcd(n1,n2)
if fa != 1:
print('{}-{}:{}'.format(idx1,idx2,fa))
break
def de_fmt():
for idx in [3,4,5,6,9]:
n = pub_n_list[idx]
n1,flag= iroot(n,2)
for i in range(1,100000000):
d = (n1+i)**2 - n
d1,d1_flag = iroot(d,2)
if d1_flag:
print('{}:{} * {}'.format(idx,n1+i-d1,n1+i+d1))
break
def de_nenc():
for idx in [3,5]:
c = 1234
c = pow(c,pub_e_list[idx],pub_n_list[idx])
for i in range(1,3000):
c = pow(c,pub_e_list[idx],pub_n_list[idx])
if c == 1234:
print(idx,i)
break
3012613441
408348887278831461892610983390456945715612189153595698014201723503582993177671598068402822885301113712860820610804438839912419021850712894809826330539771179969086301239790288951959814006579380835620367785931463468740342519
33432251606513919330224622231317366537583494828490610118526091564149071313914670507018535045422242143860852944567717
36796059015915981995743432427927902530578158826788662547913509800095517347118062478922356654842254755916234587213077
35649202521608097930406469243867007880953508969230221480710213863570107942900924156757677983779306674419762868555881
34508357350889186927005771176009938286558270433215942821530479444470024241863567490529149148811494601012847563892119
35073848198058968264749790689745197012385911613318747771531468291963621262770461817935405298684967674641247961569207
35073848198058968264749790689745197012385911613318747864444430571453140176920442860760331340059929469925220710756489
26153324138194530872309557862464074525306735281010877795840958405693838446634362256045094682633541743845611502925341
47037312003475104493787837223043052957997925611039410248119470723357078273788416725476266555402464778755414193496517
31550999035553713541658090861648847436644679578302163888858659624252927748982782365539915958668921514993162014394013
38990070212574870147996976234485159783294770114760127229326637585796111190341078784636949590143174262955343019982189
31550999035553713541658090861648847436644679578302163888858659624252927748982782365539915958668921514993162014394013
38990721481148651230245403302870059427845712033679000902896256935166030973974325392836914596772977488693063112507763
33478071698956898786044169848212690817704794983713768568912431388982883793878002287614711652531743087737814467999489
36746043666799590428244633799627952632279158164343087642676032283815739666511279233373417143396810270092798736308917
d_list = [ 0,
1229061379053482744823152709690434888605435342198642793057361495153090878523561729157374272032362247153476832905266577597936263875922635915871109425948662301015976854125739243408750974498511602088546684816889116185016023460221241669,
777757116197429014363243483536399809327489478672765799132008796613164652485176625704586327714092043960999487185568710834915265226900792279774759093092549483626423808502139519027474793822444064402879491357824424416255246538629615833,
823517544270505260875748293850542665969704501523967290816451493771583601768953397655610971102989198539746963950912153425409736040224095605717482218948794082459357645210952999432155985335398508720958815348576453854403675948095665769,
201419093613711761798540120588879041236840801068737686325195769604622639638393093247553615834885873886104026065263583851481439063609372020322699902282368593094548575688163522138303256348801329176798576662806247524508598547117027909,
0,
922636550562204599680939922372659456090989853033213781402035071733018496656291847983487357218691366381484789513851952285401356211108779700672241308549478980097499945532484886375918716118514969665502334756552044884230174523807259329,
627567627354326605515830278366021138159090868181225778581524414114680017539982571880336309158282300554534438008003322761037932916796881232969829716072515736525821134512405811777096389132413642826921797756179543381108933388795804769,
87763698610259057934268676955169084425464093902524300758830437447338976666426976224860384022223934601405128988601223084334832120115000652985202766336425151725676233383146800117094745887838499800523801384784235875984207816521259103,
476133969086427941368462698171675198835788633664060460402567958612344234273279077792246479357026462298849835811290909092037603283477920353500979549470973082158764663458247740861805650589884280458476962517272738918503674157481390819]
def main():
username0 = input('Please input Username:\t')
try:
valid_username(username0)
except:
print('\nInvalid Input\n')
return
else:
username = username0.encode('utf-8')
seq = get_enc_seq(username)
username = bytes_to_long(username)
serial = gen_code(username,seq)
check_value = check(serial, seq)
if check_value == username:
print('\nCorrect!\n')
print('Username:'+username0)
print('Serial:'+long_to_bytes(serial).hex().upper())
else:
print('\nOops! The encrypted Serial is not "' + username0 + '".\n')
system('pause')
def gen_code(name,seq):
now = name
for j in range(len(seq)-1,-1,-1):
i = seq[j]
n = pub_n_list[i]
d = d_list[i]
e = pub_e_list[i]
if now > pub_n_list[i]:
return False
if i == 5:
for _ in range(972):
now = pow(now, e, n)
elif i > 0:
now = pow(now, d, n)
else:
now = dec0(now, e, n)
return now
def dec0(m, e, n):
nbit = 192
T = (n.bit_length() - 1) // nbit + 1
ans = 0
now_d = [ 3278088227273880484685188900446423165326324359156241482897,
5595268830569065289149075246423557309146176813871482913465,
5168422726700129702446055556002687483861807983023239862033,
935387432279493795970516178982877288303534264234974679937,
]
now_n = [ 6277052177355867862708971469565390229110991711310599757597,
6277031389885428580574088212602983156224270664268963309877,
6277087998938792861042405062580257456598525084583043892593,
4973828634074084070222279013150769733596223651485114564273,
]
for i in range(T - 1, -1, -1):
def xxx(x, t):
return x >> t * nbit & (1 << nbit) - 1
now_m = xxx(m, i)
tmp = pow(now_m, now_d[i], now_n[i])
ans = (ans << nbit) + tmp
return ans
【上海第五空间信息科技研究院】(简称:第五空间)是经上海市社会组织管理局批准成立,上海市科协作为业务主管部门的新型研发机构,由翼盾智能科技创始人积聚社会力量发起成立,立足科技事业,支撑国家战略,开展科技研究,推进协同创新。
【杭州安恒信息技术股份有限公司】(简称:安恒信息)成立于2007年,科创板股票代码:688023,一直专注于网络信息安全领域,公司主营业务为网络信息安全产品的研发、生产及销售,并为客户提供专业的网络信息安全服务。公司的产品及服务涉及应用安全、大数据安全、云安全、物联网安全、工业控制安全及工业互联网安全等领域。