1. 程式人生 > >西普CTF部分題目(解密)

西普CTF部分題目(解密)

1、simple algorithm
題目地址:http://www.simplexue.com/ctf/examctfdetail/737
題目給了一個py指令碼和一個密文檔案,py指令碼將明文轉換為密文,現在需要將密文檔案中的密文解密得到明文。
加密演算法為

flag = '[censored]'
hflag = flag.encode('hex')
iflag = int(hflag[2:], 16)

def FAN(n, m):
    i = 0
    z = []
    s = 0
    while n > 0:
        if n % 2 != 0:
            z.append(2
- (n % 4)) else: z.append(0) n = (n - z[i])/2 i = i + 1 z = z[::-1] l = len(z) for i in range(0, l): s += z[i] * m ** (l - 1 - i) return s i = 0 r = '' while i < len(str(iflag)): d = str(iflag)[i:i+2] nf = FAN(int(d), 3) r += str(nf) i += 2
print r

很明顯加密流程為將明文轉換為16進位制編碼,在轉化為10進位制數,將每兩位數字構成的數進行FAN函式運算,再拼接起來得到密文。
因此解密流程為:將0~99利用FAN函式求得加密值,建立加密值–>原數的字典,在明文中查字典拼接得到10進位制數,轉化為16進位制數,再求取字串。程式碼如下:

xxx={} #字典
for kk in range(0,100):
    xxx[FAN(kk, 3)]=kk
ff=open('enc.txt','r')
dd=ff.read()
print dd
str1=''
jj=0
while jj<len(dd):
    if xxx.has_key(int
(dd[jj:jj+4])): str1+='%d'%(xxx[int(dd[jj:jj+4])]) jj+=4 elif xxx.has_key(int(dd[jj:jj+3])): str1+='%02d'%(xxx[int(dd[jj:jj+3])]) jj+=3 elif xxx.has_key(int(dd[jj:jj+2])): str1+='%02d'%(xxx[int(dd[jj:jj+2])]) jj+=2 elif xxx.has_key(int(dd[jj:jj+1])): str1+='%02d'%(xxx[int(dd[jj:jj+1])]) jj+=1 print str1 str2='%x'%(int(str1)) print str2.decode('hex')

得到明文為SIS{a9ab115c488a311896dac4e8bc20a6d7},根據演算法還缺一位字母,加上題目來自ASIS(一個伊朗的CTF比賽),故key應該為ASIS{a9ab115c488a311896dac4e8bc20a6d7}。不過該題儲存的答案是SIS{a9ab115c488a311896dac4e8bc20a6d7}。
該題還是不簡單的,國外的題目確實很新穎,值得學習,開拓思路。

2、Broken heart
檔案地址:http://ctf5.simplexue.com/misc/myheart
該檔案用linux的file指令看一下,是個7z格式的壓縮包,解壓得到myheart~,再用file指令看一下得到pcap-ng capture file - version 1.0,可知是個抓包檔案,用wireshalk開啟,選擇file–>export objects–>HTTP,匯出全部檔案,修改第一個檔名為LoiRLUoq(0),得到23個檔案,將檔案命名為LoiRLUoq(0)~LoiRLUoq(22)
檢視http資料包看到
這裡寫圖片描述
其中的content-Range包括檔案的位元組位置。
linux中執行:

strings myheart.pcap | grep 'Content-Range' | awk '{print NR,$3}' > myheart.txt

輸出到檔案myheart.txt,將txt和匯出的23個檔案放在一個資料夾下
編寫程式碼,輸出到檔案,後來觀察頭包含HDR,前面缺少13個位元組,猜測可能是個PNG圖片,補充PNG頭的前13個位元組。開啟圖片。

f=open('myheart.txt','r')
x=list(f.readlines())
f.close()
listvalues=[]
indexlist=[]
for i in xrange(len(x)):
    d=x[i].split()[1].split('/')[0].split('-') #提取前後兩個數
    flag=True
    for kline in listvalues:
        if (int(d[0])>=kline[0] and int(d[1])<=kline[1]):#若數在已存在的列表中,則取消儲存
            flag=False
            break
    if flag:
        listvalues.append((int(d[0]),int(d[1])))#儲存
        indexlist.append(i) #儲存原順序,以得到檔名

sortedpos=sorted([xx[0] for xx in listvalues]) #排序

fresult=open('resultx.png','wb')
fresult.write('89504E470D0A1A0A0000000D49'.decode('hex')) #寫入png頭,共13個位元組
for i in xrange(len(sortedpos)):
    index=0
    for searchnums in listvalues:
        if(sortedpos[i]==searchnums[0]): #在儲存的範圍列表中找到位置序號
            break
        else:
            index+=1
    f=open('LoiRLUoq(%d)'%(indexlist[index]),'rb') #開啟檔案
    if(i!=len(sortedpos)-1):
        fresult.write(f.read()[:sortedpos[i+1]-sortedpos[i]])
    else:
        fresult.write(f.read())    
    f.close()
fresult.close()
print '執行完畢,請檢視圖片得到key'

這裡寫圖片描述

3、黑客叔叔(雨襲團)內部交流題
密文連結:http://ctf5.simplexue.com/crypto/p0tt1%20.html
該題設計太差,完全需要腦洞,沒有水平,完全是坑爹的節奏。題目給了125位長度的密文,有大小有小寫有數字。看起來不是base64加密的,不過去掉最後一位試一下base64解碼,得到umfpbljhawrfrmxhz19zmf9megnrmw45x3donhq|01|03|07|+|+1|+3|+7|2+1|2+2|2+6|2+7|2+9|3+0|3+3|3+7|3
仍然很大的坑,後有人提示後面的數字代表前面的字串中第n個字元應變換為大寫,+代表*10+,如+表示10,+7表示17,2+9表示29,3+7表示37。最後面還有個特殊的3,啥意思(仍在坑人)。試了一下是代表最後的3位需要為大寫。最後在base64解碼一下得到key。國內出題人的邏輯和水平堪憂,題目差評。

import base64
sss="dW1mcGJsamhhd3Jmcm14aHoxOXptZjltZWducm13NDV4M2RvbmhxfDAxfDAzfDA3fCt8KzF8KzN8Kzd8MisxfDIrMnwyKzZ8Mis3fDIrOXwzKzB8MyszfDMrN3wzK"
x=base64.b64decode(sss[:-1])
print x
#umfpbljhawrfrmxhz19zmf9megnrmw45x3donhq|01|03|07|+|+1|+3|+7|2+1|2+2|2+6|2+7|2+9|3+0|3+3|3+7|3
res=x.split('|')
content=res[0]
result=list(content)
for ke in res[1:-1]:
    numstr=ke.replace('+','*10+')
    if numstr[0]=='*':
        numstr='1'+numstr
    if numstr[-1]=='+':
        numstr=numstr+"0"
    num=eval(numstr)
    result[num-1]=chr(ord(result[num-1])-32)

strs=''.join(result)+"="#長度不夠4的倍數,最後補上等號
strs=strs[:-3]+strs[-3:].upper()#最後三位變為大寫
print strs
#UmFpblJhaWRfRmxhZ19zMF9meGNrMW45X3doNHQ=
print "Flag is "+base64.b64decode(strs)
#Flag is RainRaid_Flag_s0_fxck1n9_wh4t

4、zcrypt(ASIS2015)
給了一個附件及一串字串提示和一個工具pkcrack
檢視附件是個7z檔案,解壓再看一下是wireshalk檔案,用wireshalk開啟匯出全部http物件為檔案,發現7個很特殊的檔案,均為zip格式,檔案大小依次減小為一半,flag檔案在最後一個壓縮包中。
這裡寫圖片描述
根據提示,搜尋發現,從最大的壓縮包入口解密,依次解,最後解開flag壓縮包得到flag。根據pkcrack說明,需要一個參考檔案,且檔案sha1值為317fc6d41e3d0f79f3e9c470cda48f52a7168c6f,但參考檔案哪裡有呢。搜尋發現有個地方有sha1值滿足的檔案下載地址
下載後得到一個壓縮包,解壓(密碼: infected)得到參考檔案,重新命名為plaintext,zip壓縮為參考zip。

root@kali:~/Desktop/1234# sha1sum plaintext 
317fc6d41e3d0f79f3e9c470cda48f52a7168c6f  plaintext
root@kali:~/Desktop/1234# zip plaintext.zip plaintext
  adding: plaintext (deflated 0%)
[email protected]:~/Desktop/1234# extract xnCub4eW 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f
[email protected]:~/Desktop/1234# pkcrack  -p plaintext -c 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f -P plaintext.zip -d decrypted1.zip -C xnCub4eW Files read. Starting stage 1 on Fri Sep 11 14:03:38 2015
Generating 1st generation of possible key2_2725465 values...done.
Found 4194304 possible key2-values.
Now we're trying to reduce these...
Lowest number: 959 values at offset 2722246
省略中間的
Lowest number: 97 values at offset 2689991
Done. Left with 97 possible Values. bestOffset is 2689991.
Stage 1 completed. Starting stage 2 on Fri Sep 11 14:05:25 2015
Ta-daaaaa! key0=70a8cda4, key1=547222ce, key2=4c7d562e
Probabilistic test succeeded for 35479 bytes.
Stage 2 completed. Starting zipdecrypt on Fri Sep 11 14:05:52 2015
Decrypting 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f (ed5e829f7f1c27cbb62e5458)... OK!
Decrypting 2VT&Wb!XJ0dzG7JyvyH-II#J (15b6960191cbc71256147d67)... OK!
Finished on Fri Sep 11 14:05:52 2015

得到2VT&Wb!XJ0dzG7JyvyH-II#J 解密檔案,重複上述步驟,直到最後一個檔案,得到flag為ASIS{b72be7f18502dde0c2ca373ee3c2b03e}
bash指令碼如下:

#!/bin/sh
PATH=$PATH:~/work/tools/pkcrack
echo $PATH
cd ~/Desktop/1234
#路徑請修改為自己所在的資源和程式目錄
#下面的檔名可通過zipinfo filename來依次獲得,按照檔案從大到小順序執行
cp rawplaintext plaintext
zip plaintext.zip plaintext
extract xnCub4eW 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f
pkcrack  -p plaintext -c 317fc6d41e3d0f79f3e9c470cda48f52a7168c6f -P plaintext.zip -d decrypted.zip -C xnCub4eW 
unzip -o decrypted.zip

mv '2VT&Wb!XJ0dzG7JyvyH-II#J' plaintext
zip plaintext.zip plaintext
extract E0frzRAi cohaxOTDL4Iy4sK7DWFU6Mw6
pkcrack  -p plaintext -c cohaxOTDL4Iy4sK7DWFU6Mw6 -P plaintext.zip -d decrypted.zip -C E0frzRAi 
unzip -o decrypted.zip

mv 'Yy#FoK+YmAgM0#4*C2^i+WWA' plaintext
zip plaintext.zip plaintext
extract BOQqupmS 'JxdIs^43_74nc-1h3WGphjSUGigLPl'
pkcrack  -p plaintext -c 'JxdIs^43_74nc-1h3WGphjSUGigLPl' -P plaintext.zip -d decrypted.zip -C BOQqupmS
unzip -o decrypted.zip

mv 'fIIutQ+18TE0*Odi*XxM' plaintext
zip plaintext.zip plaintext
extract EX8UPdUb '7U0(ZB%[email protected]'
pkcrack  -p plaintext -c '7U0(ZB%[email protected]' -P plaintext.zip -d decrypted.zip -C EX8UPdUb
unzip -o decrypted.zip

mv '[email protected]#Ztp!m'  plaintext
zip plaintext.zip plaintext
extract YupE1RB8 'e7m1Jy+#%H!%bBD1FvCB)m!JM0gE'
pkcrack  -p plaintext -c 'e7m1Jy+#%H!%bBD1FvCB)m!JM0gE' -P plaintext.zip -d decrypted.zip -C YupE1RB8
unzip -o decrypted.zip

mv 'fU2G8r)1DD2QQ_xNWuclyde#'  plaintext
zip plaintext.zip plaintext
extract EO4qqhn8 '7^&V8S(J63s$K9csDk~xaFRDGK&Z'
pkcrack  -p plaintext -c '7^&V8S(J63s$K9csDk~xaFRDGK&Z' -P plaintext.zip -d decrypted.zip -C EO4qqhn8
unzip -o decrypted.zip

mv '%dQ+skWS84uT#KSKY1uND$v+'  plaintext
zip plaintext.zip plaintext
extract VuwPO9eM '9Ux)@Zzr1h03PA#p&#u~JWWgUtpF'
pkcrack  -p plaintext -c '9Ux)@Zzr1h03PA#p&#u~JWWgUtpF' -P plaintext.zip -d decrypted.zip -C VuwPO9eM
unzip -o decrypted.zip

cat flag.txt