DDCTF 2018線上賽writeup


 

 

 第一題:

d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e4b3b2b2e3e6b4b3e2b5b0b6b1b0e6e1e5e1b5fd

 

解題思路:

首先嘗試各種解密,無果。

開始研究,分析字符串,首先看看有哪些字符,然后准備分析頻率

import string

cipertext = "d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e4b3b2b2e3e6b4b3e2b5b0b6b1b0e6e1e5e1b5fd"
for i in string.lowercase: if i in cipertext: print i for i in string.digits: if i in cipertext: print i

打印出來發現字符串由a-f 0-9組成,瞬間想到16進制格式,開始向16進制進攻

len()查看到字符長度為134,16進制一般是兩個字符組成一個字節,所以兩個兩個拆解分開試試

cipertext = "d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e4b3b2b2e3e6b4b3e2b5b0b6b1b0e6e1e5e1b5fd"
i = 0 plaintext = "" while i < 133: plaintext += str(int(cipertext[i:i + 2], 16)) + " " i += 2 print plaintext

得到212 232 225 244 160 247 225 243 160 230 225 243 244 161 160 212 232 229 160 230 236 225 231 160 233 243 186 160 196 196 195 212 198 251 185 178 178 225 226 185 185 183 180 225 180 183 227 228 179 178 178 227 230 180 179 226 181 176 182 177 176 230 225 229 225 181 253 

明顯看到超出常規ascii范圍,考慮嘗試凱撒解密,由於ascii有128字符,嘗試先減去128

cipertext = "d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e4b3b2b2e3e6b4b3e2b5b0b6b1b0e6e1e5e1b5fd"
i = 0 plaintext = "" while i < 133: asciinum = int(cipertext[i:i + 2], 16)-128 plaintext += chr(asciinum) i += 2 print plaintext

得到flag

 

第二題:

打開下載的windows.jpg

非常普通的一張圖,看到圖片,第一聯想到隱寫術,自行用binwalk看看圖片有沒有藏東西

一大堆東西,嘗試提取分離,得到一個zip,打開一看需要密碼

 

 這里可以用暴力破解,不過花費時間較長,期間可以做一些其他事情,比如去看看圖片的詳細信息(可能藏東西)

在備注找到Pactera,嘗試作為密碼輸入,解壓成功Orz...............

打開file.txt

進行一頓柵欄,編碼等解密,無果。

破了很久,最后回頭看題目看了的提示

嘗試分析字符頻率,然后進行排序

file1 = open("file.txt", "r")
cipertext = file1.read() dic1 = {} for i in cipertext: if i not in dic1: dic1[i] = 1 else: dic1[i] += 1 z = zip(dic1.values(), dic1.keys()) plaintext = "" for i in sorted(z): plaintext = i[1] + plaintext print plaintext

直接得到flag

 

 

第三題:

本題差評!!!干擾項太多,不親切,這里不再贅述踩的坑

 

下載得到附件,是一個pcap文件,果斷丟入wireshark,把解析的到的文件一次導出

只有IMF的能導出,分析查看,大概在一個文件比較大的地方,看到

復制出來,看到是base64,解碼,得到一串字符

這個看到應該是一張圖片,所以這里保存成圖片看一看。。

#!/usr/bin/env python
# coding=utf-8
import base64

file1 = open("test", "r") cipertext = file1.read() file1.close() plaintext = base64.b64decode(cipertext) # 讀取file1進行base64解碼 file2 = open("testpng.png", "wb") # 以.png寫入保存 file2.write(plaintext) file2.close()

打開我們剛才保存的圖片

 

這里就要使用圖像識別了,ocr了解一下

#!/usr/bin/env python
# coding=utf-8

import base64
import pytesseract from PIL import Image def getcode(imgurl): """識別圖片""" image = Image.open(imgurl) vcode = pytesseract.image_to_string(image) code = base64.b64decode(vcode.encode("utf-8")) return code temp_imgurl = 'testpng.png' code = getcode(temp_imgurl) print code

這里無敵坑,ocr識別准確率不是很高,code得到后還要和圖片進行比對檢查。

根據提示,補全RSA

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDCm6vZmclJrVH1AAyGuCuSSZ8O+mIQiOUQCvN0HYbj8153JfSQ
LsJIhbRYS7+zZ1oXvPemWQDv/u/tzegt58q4ciNmcVnq1uKiygc6QOtvT7oiSTyO
vMX/q5iE2iClYUIHZEKX3BjjNDxrYvLQzPyGD1EY2DZIO6T45FNKYC2VDwIDAQAB
AoGAbtWUKUkx37lLfRq7B5sqjZVKdpBZe4tL0jg6cX5Djd3Uhk1inR9UXVNw4/y4
QGfzYqOn8+Cq7QSoBysHOeXSiPztW2cL09ktPgSlfTQyN6ELNGuiUOYnaTWYZpp/
QbRcZ/eHBulVQLlk5M6RVs9BLI9X08RAl7EcwumiRfWas6kCQQDvqC0dxl2wIjwN
czILcoWLig2c2u71Nev9DrWjWHU8eHDuzCJWvOUAHIrkexddWEK2VHd+F13GBCOQ
ZCM4prBjAkEAz+ENahsEjBE4+7H1HdIaw0+goe/45d6A2ewO/lYH6dDZTAzTW9z9
kzV8uz+Mmo5163/JtvwYQcKF39DJGGtqZQJBAKa18XR16fQ9TFL64EQwTQ+tYBzN
+04eTWQCmH3haeQ/0Cd9XyHBUveJ42Be8/jeDcIx7dGLxZKajHbEAfBFnAsCQGq1
AnbJ4Z6opJCGu+UP2c8SC8m0bhZJDelPRC8IKE28eB6SotgP61ZqaVmQ+HLJ1/wH
/5pfc3AmEyRdfyx6zwUCQCAH4SLJv/kprRz1a1gx8FR5tj4NeHEFFNEgq1gmiwmH
2STT5qZWzQFz8NRe+/otNOHBR2Xk4e8IS+ehIJ3TvyE=
-----END RSA PRIVATE KEY-----

 

看到這個rsa秘鑰,自然聯想到ssl,搜索一下(ssl了解一下)

看到了ssl的通信

把秘鑰導入

 

重啟wireshark,驚奇地發現在最后多了http

追蹤http流

 

第四題

#!/usr/bin/env python
import sys
import json
from Crypto.Cipher import AES
from Crypto import Random


def get_padding(rawstr):
    remainder = len(rawstr) % 16
    if remainder != 0:
        return '\x00' * (16 - remainder)
    return ''


def aes_encrypt(key, plaintext):
    plaintext += get_padding(plaintext)
    aes = AES.new(key, AES.MODE_ECB)
    cipher_text = aes.encrypt(plaintext).encode('hex')
    return cipher_text


def generate_hello(key, name, flag):
    message = "Connection for mission: {}, your mission's flag is: {}".format(name, flag)
    return aes_encrypt(key, message)


def get_input():
    return raw_input()


def print_output(message):
    print(message)
    sys.stdout.flush()


def handle():
    print_output("Please enter mission key:")
    mission_key = get_input().rstrip()

    print_output("Please enter your Agent ID to secure communications:")
    agentid = get_input().rstrip()
    rnd = Random.new()
    session_key = rnd.read(16)

    flag = '<secret>'
    print_output(generate_hello(session_key, agentid, flag))
    while True:
        print_output("Please send some messages to be encrypted, 'quit' to exit:")
        msg = get_input().rstrip()
        if msg == 'quit':
            print_output("Bye!")
            break
        enc = aes_encrypt(session_key, msg)
        print_output(enc)


if __name__ == "__main__":
    handle()

 

這題算是純crypto,采用的是MODE_ECB的AES加密。

題目大概的意思就是明文由agentid和flag組成,隨意輸入 agentid后明文會被隨機產生的key進行AES加密,由於每一次遠程到116.85.48.103時key都是隨機產生的,所以我們只能通過后面的加密嘗試來猜測出明文

首先AES了解一下

ECB加密是分組進行加密的,解密也是分組解密。分組與分組之間的明文產生的密文互相獨立,且由於算法的緣故,相同的明文分組在相同的密鑰加密下會產生相同的密文
加解密流程如下圖所示

22-50-28.jpg22-50-56.jpg

而我們要做的事是通過這些個分組且明文加密固定密文的特性猜出flag的每一位來
題中以16字節為一組,我們舉例也拿16字節為一組舉例
首先我們假設xxxx是我們可控的輸入,一般情況下的加密會是這樣的

ECB1.png

但是如果我們控制xxx為十五個固定的字符如十五個A
則加密過程會變成這樣:

ECB2.png

現在我們記錄下此時的HEX_1,在與密文進行比較,如果一樣就記下此時F的值,如此一個一個循環推測

以下是解題代碼

#!/usr/bin/env python
# coding=utf-8
import time
import socket
import string

agentid = ""
message = ""
flag = ""

for i in range(45):
    agentid += "1"


def returnmsg(data):
    """發送與接收"""
    s.send(data)
    time.sleep(0.3)
    msg = s.recv(1024)
    return msg


while True:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(("116.85.48.103", 5002))

    print returnmsg("2acba569d223cf7d6e48dee88378288a\n")  # 發送題目的mission key
    cipertext = returnmsg(agentid + "\n")  # 得到密文
    print cipertext

    for i in string.lowercase + string.digits + string.uppercase + "{}":
        message = "Connection for mission: {}, your mission's flag is: {}".format(agentid, flag + i)
        info = returnmsg(message + "\n")
        if info.split("\n")[0] in cipertext: # 如果嘗試加密的內容和第一次密文相同,則記下i
            print info
            flag += i
            print "find key code: " + i
            break

    print message
    s.shutdown(2)
    s.close()
    if agentid == "": # 每一次猜到keycode后,agentid都要減一位
        break
    else:
        agentid = agentid[:-1]
    if i == "}":
        break

 


免責聲明!

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



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