SCTF-2014 writeup(部分)

code200:

    wKiom1SH8YPAkTqbAAFYJs-48YE071.jpg這個題目看着描述很複雜,實際上把數字轉成二進制,輸出二進制位上是 1 的位置序號就可以了。需要注意的是奇偶位是有符號的,如果最高位序號是奇數,需要在前面補一個偶數位。

編程的任務等待以後python練習的時候補吧。



code400:

wKiom1SH8nrztbiVAAFPHwWIMdE967.jpg

import json
import hashlib
import os
import base64
from Crypto.Cipher import AES

fp = open("secret.json", "r")
secret = json.load(fp)
fp.close()

if type(secret["the answer to life the universe and everything"]) != type(u"77"):
    destroy_the_universe()

answer = hashlib.sha1(secret["the answer to life the universe and everything"]).hexdigest()[0:16]
key = hashlib.sha1(secret["Don't google what it is"]).digest()[0:6]

if ord(key[4])*(ord(key[5])-5) != 17557:
    destroy_the_universe()

keys = ["hey"+key[2]+"check"+key[3]+"it"+key[0]+"out", 
        "come"+key[1]+"on"+key[4]+"baby"+key[5]+"~~!"]
answer = AES.new(keys[1], AES.MODE_ECB).encrypt(AES.new(keys[0], AES.MODE_ECB).encrypt(answer))

if base64.b64encode(answer) == "fm2knkCBHPuhCQHYE3spag==":
    fp = open("%s.txt" % hashlib.sha256(key).hexdigest(), "w")
    fp.write(secret["The entrance to the new world"])
    fp.close()

很明顯這個題目是要爆破的。首先計算出k[4]和k[5],對17557做因式分解:97*181。

因而存在兩組可能k[4]=97, k[5]=186;k[4]=102, k[5]=181。需要分別爆破。

這裏有個可以優化的地方,就是在對應一組k[4]和k[5]的情況下keys[1]只有256種可能,可以先解出keys[1]對應的256個答案的解,也就是破解出最外面那一層AES,而後keys[0]對應的DES進行爆破的時候,結果只要查keys[1]對應的256長度的答案表就可以了。雖然算法複雜度依然是255*255*255*255,但最外面那一層沒有計算AES,速度要快一些。

實際上直接暴力也可以。

import hashlib
import base64
from Crypto.Cipher import AES
k4=102
k5=181
kkk = hashlib.sha1("42").hexdigest()[0:16]
for k0 in range(255, 256):
    for k1 in range(0, 256):
        for k2 in range(0, 256):
            for k3 in range(0, 256):
                keys = ["hey"+chr(k2)+"check"+chr(k3)+"it"+chr(k0)+"out",
                        "come"+chr(k1)+"on"+chr(k4)+"baby"+chr(k5)+"~~!"]
                #print len(keys[0]), len(keys[1])
                answer = AES.new(keys[1], AES.MODE_ECB).encrypt(AES.new(keys[0], AES.MODE_ECB).encrypt(kkk))
                if base64.b64encode(answer) == "fm2knkCBHPuhCQHYE3spag==":
                    print "%s.txt" % hashlib.sha256(chr(k0)+chr(k1)+chr(k2)+chr(k3)+chr(k4)+chr(k5)).hexdigest()
                    exit();

經過測試,完成一次255*255*255的暴力,2分鐘左右。服務器上要更快些,開到16個進程,很快可以直接爆出hash文件名:http://download.sycsec.com/code/code400/5bd15779b922c19ef9a9ba2f112df1f2dbb0ad08bbf9edac27a28a0f3ba753f4.txt

沒想到打開這個txt,裏面還有一層加密:

Welcome to the new world!
Mallory把Alice給Bob的錢藏在了一個神祕的地方,還把地址加密,然後帶着密鑰,坐黃金之心離開了!
沒有密鑰的plusplus7用黑科技復原了一部分明文,然後打麻將去了,所以剩下的就交給你啦!
P.S.聽說您很會暴力破解:)

====== Base64格式密文 ======
Or18/xSC2xW5pT7BLbIE7YPGLwWytbZsxupMp4w6iaa0QvtYZUMefkf43wmzR36MekHm23wgI4buIJLGk7m7gTq9fP8UgtsVuaU+wS2yBO2Dxi8FsrW2bMbqTKeMOommtEL7WGVDHn5H+N8Js0d+jHpB5tt8ICOG7iCSxpO5u4E6vXz/FILbFbmlPsEtsgTtg8YvBbK1tmzG6kynjDqJprRC+1hlQx5+R/jfCbNHfox6QebbfCAjhu4gksaTubuBOr18/xSC2xW5pT7BLbIE7YPGLwWytbZsxupMp4w6iaa0QvtYZUMefkf43wmzR36MekHm23wgI4buIJLGk7m7gTq9fP8UgtsVuaU+wS2yBO2Dxi8FsrW2bMbqTKeMOommtEL7WGVDHn5H+N8Js0d+jHpB5tt8ICOG7iCSxpO5u4E=

====== 藏寶地址 ======
*****n**M****H***j***Wx*******d************h*****3****=*******==******t**F**M**f***hM************3***H*w**J*********=**==*******U******E**95**V*c*N****5**t*M*****J*c*Q*****c*h5**0******==*==****NUR*******************X2*u*H**Y************G**P****=***********0*****************************f***5****OX*********=*******=****

分析了一下,密文和部分破解的明文都是320個字節,以爲是異或,但怎麼嘗試都不對。最後注意點放到明文的“==”上面,第一段連續的“=*******==”出現的時候,假設這裏*都是=,那麼實際上是一段連續的=======,看明文,最後的“=*******=****”也應該是連續的======,那麼把這兩部分對應的密文進行比較,發現是一樣的。這裏實際上運氣比較好,第一段連續的“=*******==”結束位置正好是64個字符處。這樣可以發現,明文實際上是以64個字符分割的,列對齊的。處理後得到:

wKiom1SH94zQUheuAADRmGwJ0MU481.jpg

很明顯,每一列只有一個字符不是*,組合起來是一個base64字符串,解碼後就是flag。

實際上這個題目還是比較人性化的,每一行後面都加了許多====。給解密提供了線索。



re50:

文件見附件。

wKioL1SIB_zBCZKyAACe1qDT1IU510.jpg

文件是x86_64ELF,IDA查看,很簡單。下面是等效代碼。

int main()
{
    char s1[] = "Jr3gFud6";
    char s2[16];
    char passwd[16];
    int len;
    
    printf("input your password:");
    scanf("%s", passwd);
    len = strlen(passwd);
    if(len != 9)    #這裏按照ida的字節抄過來。
        return 0;
        
    memset(s2, 0, 16);
    for(int i=0; i<len; i++)
        s2[i] = passwd[i]+3;
        
    if(! strcmp(s1, s2))
        printf("The flag is SCTF{%s}\n", passwd);
    return 0;
}

解碼就是s1每個字符-3。



misc100:

此題可以學習到C++,異常處理throw--catch的反彙編分析。所以單獨開帖寫一下。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章