DDCTF-2018-writeup(5misc)


打了好幾天最后也只是80多名,我好菜啊.jpg

 

0x00  (╯°□°)╯︵ ┻━┻ 

題目:

(╯°□°)╯︵ ┻━┻

d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9e1e6b3e3b9e4b3b7b7e2b6b1e4b2b6b9e2b1b1b3b3b7e6b3b3b0e3b9b3b5e6fd

一開始被這個(╯°□°)╯︵ ┻━┻誤導以為是jjencode,嘗試了好久沒啥結果,后面又有人說是翻轉,試了很久還是沒結果。然后跑了下移位密碼獲取flag

貼上腳本

 1 s='d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9e1e6b3e3b9e4b3b7b7e2b6b1e4b2b6b9e2b1b1b3b3b7e6b3b3b0e3b9b3b5e6fd'
 2 '''
 3 s1=''
 4 for x in range(len(s)/2):
 5     s1+=chr((int(s[x*2:x*2+2],16))%128)
 6 print s1
 7 '''
 8 
 9 for j in range(20):
10     s1=''
11     for x in range(len(s)/2):
12         s1+=chr((int(s[x*2:x*2+2],16)-j)%128)
13     print s1
14     

 

0x01 第四擴展FS

題目:D公司正在調查一起內部數據泄露事件,鎖定嫌疑人小明,取證人員從小明手機中獲取了一張圖片引起了懷疑。這是一道送分題,提示已經在題目里,日常違規審計中頻次有時候非常重要。 https://pan.baidu.com/s/1DJpMFU2lajHGTo0yfzTHVQ 密碼:fpp4

這道題很多坑,拿到題目看題目名字就可以知道它考的是ext4文件,先用壓縮軟件打開查看了一下

因為沒怎么接觸過ext4文件系統所以不知道journal文件是拿來干嘛的,百度后說是文件系統日志,所以考慮mount到linux上,但是怎么都不成功。

另外還有一個加密的file.txt,用binwalk掃了下文件,發覺就是這兩個文件

 

為了尋找file.txt密碼,用winhex打開jpg后發現有些圖片有敏感信息,然后直接查看圖片屬性,發現解壓密碼

解壓打開file.txt

根據提示頻率,統計一下字符出現頻率,貼上腳本,得到flag

1 import collections
2 
3 f=open('file.txt','r')
4 print collections.Counter(f.read())

 

0x02 流量分析

題目:提示一:若感覺在中間某個容易出錯的步驟,若有需要檢驗是否正確時,可以比較MD5: 90c490781f9c320cd1ba671fcb112d1c
提示二:注意補齊私鑰格式
-----BEGIN RSA PRIVATE KEY-----
XXXXXXX
-----END RSA PRIVATE KEY-----

這題給的數據包很大,而且有很多坑,數據包前面有兩個用ftp傳輸加密壓縮文件fl-g.zip,sqlmap-dev.zip,中間有九封郵件,只到看到最后才會發現本題關鍵ssl加密通信。

 前面的兩個壓縮包可能是本題彩蛋,不過我是真的解不出來。。。所以跳過,直接導出郵件。

將導出的郵件導入qq郵箱中查看,可以發現這個

 

這里是本題關鍵,在數據包中這里是很大一串base64,解密后得到rsa私鑰

,將私鑰識別補齊格式進行ssl解密得到

 

 

 

0x03 安全通信

題目:請通過nc XXXX.XXXX.XXXX.XXXX XXXX答題,mission keyb9ba15b341c847c8beba85273f9b7f90agent id隨意填就可以

 1 #!/usr/bin/env python
 2 import sys
 3 import json
 4 from Crypto.Cipher import AES
 5 from Crypto import Random
 6 
 7 
 8 def get_padding(rawstr):
 9     remainder = len(rawstr) % 16
10     if remainder != 0:
11         return '\x00' * (16 - remainder)
12     return ''
13 
14 
15 def aes_encrypt(key, plaintext):
16     plaintext += get_padding(plaintext)
17     aes = AES.new(key, AES.MODE_ECB)
18     cipher_text = aes.encrypt(plaintext).encode('hex')
19     return cipher_text
20 
21 
22 def generate_hello(key, name, flag):
23     message = "Connection for mission: {}, your mission's flag is: {}".format(name, flag)
24     return aes_encrypt(key, message)
25 
26 
27 def get_input():
28     return raw_input()
29 
30 
31 def print_output(message):
32     print(message)
33     sys.stdout.flush()
34 
35 
36 def handle():
37     print_output("Please enter mission key:")
38     mission_key = get_input().rstrip()
39 
40     print_output("Please enter your Agent ID to secure communications:")
41     agentid = get_input().rstrip()
42     rnd = Random.new()
43     session_key = rnd.read(16)
44 
45     flag = '<secret>'
46     print_output(generate_hello(session_key, agentid, flag))
47     while True:
48         print_output("Please send some messages to be encrypted, 'quit' to exit:")
49         msg = get_input().rstrip()
50         if msg == 'quit':
51             print_output("Bye!")
52             break
53         enc = aes_encrypt(session_key, msg)
54         print_output(enc)
55 
56 
57 if __name__ == "__main__":
58     handle()

分析代碼得知,該題為aes  ecb加密,這幾天密碼學課剛好講到這,ecb是一種非常不安全的加密,wiki上有很好的舉例。腳本放后面了。

1.本題通過輸入agent_id,構造形如

Connection for mission: {agent_id}, your mission's flag is: DDCTF{32位}的字符串,

用隨機生成的16位密鑰進行加密,在一次連接中密鑰不會變換

2.因為aes的特性通過改變輸入agent_id長度,可以確定flag長度為32位,如下圖

3.因為aes特性將字符串16位一組分組,當輸入12345678時,字符串多出一位},分析腳本得知會用0補齊。

4.aes_ecb的特性,最后一組的}和單獨輸入}加密后一樣,得知可以進行爆破,通過改變agent_id長度進行爆破。得到flag

 1 #coding=utf-8
 2 import socket
 3 import string
 4 mission_key = '''xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'''
 5 a='''1234567890123456789012345678901234567890'''#最初的agent_id
 6 flag='DDCTF{'
 7 msg="flag is: DDCTF{"
 8 for x in range(1,33):#長度32位
 9     agent=a[:40-x]+'\n'#每次變換agent
10     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        
11     s.connect(('116.85.48.103',5002))
12     s.recv(1024)
13     s.send(mission_key+'\n')
14     s.recv(1024)
15     s.send(agent)
16     c=s.recv(1024).rstrip()
17     for i in string.printable:
18         s.recv(1024)
19         s.send(msg+i+'\n')
20         ss=s.recv(1024).rstrip()[:32]
21         if(ss==c[160:192]):
22             msg=msg[1:]+i
23             flag+=i
24             print flag
25             break
26     s.close()
27 print flag+'}'

 

 

0x04 complex stego

題目:

不算提示的提示3:這道題一共有兩個解法,之前只提示了一種,另外一種比較簡單

不算提示的提示2:https://www.bilibili.com/video/av19141078
https://www.bilibili.com/video/av21411551
P.S. 出題時間在出視頻時間之前,從這個意義上說跟題目沒有關系,因此這是不算提示的提示

提示:請善用搜索引擎來學習,重點是z

=====

警方正在利用某黑客使用過的設備,來追查其行蹤,並發現了下面附件中的文件。

該黑客利用附件中的encrypt.py,將其密鑰轉換成encrypted.bmp保存。警方在測試時,發現利用encrypt.py字符串“DDCTF{}”能被轉換成下圖的美麗圖樣。
DDCTF{}

你能幫助警方從encrypted.bmp恢復出該黑客的密鑰么?(為便於修正誤差,本題flag后面重復出現了一次flag本體)

題解:根據兩張圖片和一些我自定義的字符串進行加密,得到字符串長7位時每種顏色出現6次,8位時出現7次,數出加密圖片顏色次數位37次可以確定加密的字符串長38位。根據題意flag本體重復了一次所以加密字符串格式為DDCTF{15位} 15位,還有一位一直不知道是啥,現在知道是空格了

直接引用出題人的解答吧,畢竟我連傅里葉變換都沒學過。只知道解題腳本是用那個微分方程寫出來的。

https://github.com/garzon/DDCTF_2018/tree/master/complex_stego

貼一下出題人的解題腳本

 1 from PIL import Image
 2 import cmath, math, random, string
 3 
 4 maxLen = 45
 5 img_size = 800
 6 abs_cor_size = 1.05
 7 maxValue = 2200.0
 8 
 9 def linear_map(v, old_dbound, old_ubound, new_dbound, new_ubound):
10     return (v-old_dbound)*1.0/(old_ubound-old_dbound)*(new_ubound-new_dbound) + new_dbound
11     
12 def read_from_img(img):
13     def mapping(r, i):
14         x = int(round(linear_map(r, -abs_cor_size, abs_cor_size, 0, img_size)))
15         y = int(round(linear_map(i, -abs_cor_size, abs_cor_size, img_size, 0)))
16         return (x, y)
17     def X(z):
18         pix_pos = mapping(z.real, z.imag)
19         t = img.getpixel(pix_pos)
20         return complex(linear_map(t[1], 0, 255, -maxValue, maxValue), linear_map(t[2], 0, 255, -maxValue, maxValue))
21     return X
22     
23 def z_decrypt(X):
24     real_max_val = 0.0
25     decrypted = []
26     for n in xrange(maxLen):
27         res = 0.0
28         dw = 0.001
29         w = -math.pi
30         while w < math.pi:
31             v = X(pow(math.e, 1j * w))
32             if v.real > real_max_val: real_max_val = v.real
33             if v.imag > real_max_val: real_max_val = v.imag
34             res += v * pow(math.e, 1j * w * n) * dw
35             w += dw
36         decrypted.append(res/math.pi/2)
37     print 'realmax', real_max_val
38     err = [math.fabs(j.imag) for j in decrypted]
39     res = ''.join([string.printable[j-1] if j <= len(string.printable) and j >= 1 else '?' for i in decrypted for j in [int(round(i.real))]]).strip('?')
40     return res
41     
42 img = Image.open('encrypted.bmp')
43 X = read_from_img(img)
44 decrypted = z_decrypt(X)
45 print len(decrypted), decrypted
46 print '--------- decrypted! ----------------'

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM