ciscn_2021 HASH-TEAM RE/cry WP

以下为本次赛中的WP

re-glass

流程

发现是apk,直奔lib的.so文件

然后ida打开,发现字符长度39,接着发现最后的内存比较长度也是39,应该没有改变长度的操作。

把比较的内存dump下来。

在输入后发现重要字符串“12345678”,猜测是密钥。

然后依次点进去三个函数,前两个是rc4,没有魔改的。

第三个函数先划分成三元组,并通过异或加密,最后再跟密钥异或加密。

由于后两步使用ida python直接写的脚本,在此重补。

第一步

dump+异或

1
2
3
4
5
6
7
s='''A3 1A E3 69 2F BB 1A 84 65 C2 AD AD  9E 96 05 02 1F 8E 36 4F
E1 EB AF F0 EA C4 A8 2D 42 C7 6E 3F B0 D3 CC 78 F9 98 3F'''.split()
s=[int(i,16) for i in s]
t=[ord('1')+(i%8) for i in range(len(s))]
s1=[s[i]^t[i] for i in range(len(s))]
print(s1)
#[146, 40, 208, 93, 26, 141, 45, 188, 84, 240, 158, 153, 171, 160, 50, 58, 46, 188, 5, 123, 212, 221, 152, 200, 219, 246, 155, 25, 119, 241, 89, 7, 129, 225, 255, 76, 204, 174, 8]
第二步

写脚本

1
2
3
4
5
6
7
8
s2=[0]*39
for i in range(0,len(s1),3):
s2[i+1]=s1[i+1]^s1[i+0]
s2[i+0]=s1[i+1]^s1[i+2]
s2[i+2]=s1[i+1]^s1[i+0]^s1[i+2]

print(s2)
#[248, 186, 106, 151, 71, 202, 232, 145, 197, 7, 110, 247, 146, 11, 57, 146, 20, 168, 175, 126, 170, 80, 69, 141, 109, 45, 182, 134, 110, 159, 134, 94, 223, 179, 30, 82, 166, 98, 106]
第三步

直接用之前的脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import requests
import base64
import hashlib
from binascii import unhexlify
def crypt(data,key) :
s = [0] * 256
for i in range(256) :
s[i] = i
j = 0
for i in range(256) :
j = (j + s[i] + key[i % len(key)]) % 256
print(j)
s[i], s[j] = s[j], s[i]
i = 0
j = 0
res = ""
for c in data :
i = (i + 1) % 256
j = (j + s[i]) % 256
s[i], s[j] = s[j], s[i]
res = res + chr(c ^ s[(s[i] + s[j]) % 256])
return res

def tdecode(data ,key) :
data = base64.b64decode(data)
salt = data[:16]
return crypt(data[16:] ,hashlib.sha1(bytes(key,encoding='utf8') + salt).digest())

if __name__ =='__main__':
t=[0xf8, 0xba, 0x6a, 0x97, 0x47, 0xca, 0xe8, 0x91, 0xc5, 0x7, 0x6e, 0xf7, 0x92, 0xb, 0x39, 0x92, 0x14, 0xa8, 0xaf, 0x7e, 0xaa, 0x50, 0x45, 0x8d, 0x6d, 0x2d, 0xb6, 0x86, 0x6e, 0x9f, 0x86, 0x5e, 0xdf, 0xb3, 0x1e, 0x52, 0xa6, 0x62, 0x6a]
# t=[int(i,16) for i in s]
key = "12345678"
k=[ord(i) for i in key]
print(crypt(t,k))
#CISCN{6654d84617f627c88846c172e0f4d46c}

re-baby.bc

流程

查资料可知这是个llvm,下载llvm工具链和clang

1
2
llvm-dis baby.bc
clang baby.ll

然后分析out文件

输入长度25,且只有\(['0','5']\)可输入,后边的判断明显是5个一组,大胆猜测是5x5的结构,创建结构体。

第一个fill函数的逻辑是对于已经有值的格子判断输入为0,对于无值的格子则存入。

第二个函数docheck()函数首先进行了行列查重,然后按照比较结构体是1还是2约束大小。

其实就是个数独。

尝试输入

ps:本题有可能出现非预期的含有0的解,但未测试。

cry-rsa

发现是分成了三段。(这个题在终端写的)

第一段低指数加密攻击,直接开方得到。

1
2
3
4
5
6
7
8
from gmpy2 import *
from binascii import *
c0=19105765285510667553313898813498220212421177527647187802549913914263968945493144633390670605116251064550364704789358830072133349108808799075021540479815182657667763617178044110939458834654922540704196330451979349353031578518479199454480458137984734402248011464467312753683234543319955893
print(iroot(c0,3))
#(mpz(267334379257781603687613466720913534310764480084016847281446486946801530200295563483353634338157), True)
m1=unhexlify(hex(iroot(c0,3)[0])[2:])
print(m1)
#b' \nO wild West Wind, thou breath of Autum'

第二段是中国剩余定理,直接对17和65537剩余定理可得。

1
2
3
4
5
6
7
8
9
gcdext(17,65537)
#(mpz(1), mpz(30841), mpz(-8))
c1=54995751387258798791895413216172284653407054079765769704170763023830130981480272943338445245689293729308200574217959018462512790523622252479258419498858307898118907076773470253533344877959508766285730509067829684427375759345623701605997067135659404296663877453758701010726561824951602615501078818914410959610
c2=91290935267458356541959327381220067466104890455391103989639822855753797805354139741959957951983943146108552762756444475545250343766798220348240377590112854890482375744876016191773471853704014735936608436210153669829454288199838827646402742554134017280213707222338496271289894681312606239512924842845268366950
n2=111381961169589927896512557754289420474877632607334685306667977794938824018345795836303161492076539375959731633270626091498843936401996648820451019811592594528673182109109991384472979198906744569181673282663323892346854520052840694924830064546269187849702880332522636682366270177489467478933966884097824069977
m2=powmod(c1,30841,n2)*powmod(c2,-8,n2)%n2
m2=unhexlify(hex(m2)[2:])
print(m2)
#b"n's being,\nThou, from whose unseen presence the leaves dead\nAre driven, like ghosts from an enchanter fleeing,\nYellow, a"

发现是西风颂,第三段不会做,直接爆破原文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from Crypto.Util.number import long_to_bytes,bytes_to_long,getPrime
n3=113432930155033263769270712825121761080813952100666693606866355917116416984149165507231925180593860836255402950358327422447359200689537217528547623691586008952619063846801829802637448874451228957635707553980210685985215887107300416969549087293746310593988908287181025770739538992559714587375763131132963783147
c=59213696442373765895948702611659756779813897653022080905635545636905434038306468935283962686059037461940227618715695875589055593696352594630107082714757036815875497138523738695066811985036315624927897081153190329636864005133757096991035607918106529151451834369442313673849563635248465014289409374291381429646

s=b'''
O wild West Wind, thou breath of Autumn's being,
Thou, from whose unseen presence the leaves dead
Are driven, like ghosts from an enchanter fleeing,
Yellow, and black, and pale, and hectic red,
Pestilence-stricken multitudes: O thou,
Who chariotest to their dark wintry bed
The winged seeds, where they lie cold and low,
Each like a corpse within its grave, until
Thine azure sister of the Spring shall blow
Her clarion o'er the dreaming earth, and fill
(Driving sweet buds like flocks to feed in air)
With living hues and odours plain and hill:
Wild Spirit, which art moving everywhere;
Destroyer and preserver; hear, oh hear!'''
for i in range(160,len(s)):
m3=bytes_to_long(s[160:i])
ci=powmod(m3,65537,n3)
if ci==c:
print(s[160:i])

#b'nd black, and pale, and hectic red,\nPestilence-stricken multitudes: O thou,\nWho chariotest to their dark wintry bed\n'

然后从hashlib取md5结束。


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 [@Zuni](http://example.com/) 创建,使用 Stellar 作为主题。