2018 DDCTF 杂项 writeup

栏目: 编程工具 · 发布时间: 6年前

内容简介:今年的签到题就直接pass了,从第二道开始。题目就给出了一串一开始是想看看是不是什么文件的,但没有发现。

前言

今年的 DDCTF 玩的非常充实,7天的时间里基本每天都在学习新东西,整个 Writeup 会按题目类型进行分类。

(╯°□°)╯︵ ┻━┻

签到题就直接pass了,从第二道开始。题目就给出了一串 16进制 的字符:

d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e4b3b2b2e3e6b4b3e2b5b0b6b1b0e6e1e5e1b5fd

一开始是想看看是不是什么文件的,但没有发现。

2018 DDCTF 杂项 writeup

而且观察发现按两位数转10进制的话全都超出了可见字符的 ASCII 码表,当然解题时也考虑过对每两个16进制进行 ^ 异或,但都不对。然后尝试对每两个字符转出来的 10进制 进行减 128 ,因为这样每个值得范围就能落在 ASCII 码表。

import re
sss = 'd4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e4b3b2b2e3e6b4b3e2b5b0b6b1b0e6e1e5e1b5fd'
nums = re.findall('\w{2}',sss)
flag = ''
for one in nums:
    ch = chr(int(one,16) - 128)
    flag += ch
print(flag)
# That was fast! The flag is: DDCTF{922ab9974a47cd322cf43b50610faea5} 

第四扩展FS

附件下下来发现很大,用 winhex 查看了一下,发现后面全是填充的,然后还有个压缩包,我们把它提取出来,但需要解压密码,然后解压密码可以在原图片的 备注 信息里找到。

2018 DDCTF 杂项 writeup

接着我们就能拿到一堆乱码的字符。

2018 DDCTF 杂项 writeup

因为题目描述中说到 频次 很重要,所以尝试使用在线的词频密码分析网站,但没有发现,所以考虑另一种可能,就是不用还原成句子,只需要里面的每个词的频次。然后写个脚本跑一下:

# -*- coding:utf-8 -*-
with open ('file.txt','r') as f:
    dd3 = f.read()

a = {}
for i in dd3:
    if i not in a:
        a[i]=1
    else:
        a[i] +=1

b = sorted(a.items(), lambda x, y: cmp(x[1], y[1]), reverse=True)
flag = ''
for i in b:
    flag += i[0]
print(flag)

# DCTF{x1n9shaNgbIci}

流量分析

下载后使用 wireshark 进行分析,流量分析题如果不掌握点小技巧,估计眼睛会看瞎。

打开后直接拉到 灰色 报文块,如下图,然后一把 TCP追踪流 过去。

2018 DDCTF 杂项 writeup

2018 DDCTF 杂项 writeup

然后逐个查看流,然后你会发现有两个压缩包,但后面发现那就是坑来的,反正我没用上。。。。在查看他们的邮件往来记录的时候有一张图片引起了我的注意:

2018 DDCTF 杂项 writeup

恢复过来后看起来比较奇怪,,因为以前也没搞过密码,所以一开始还真没注意到它的作用。

2018 DDCTF 杂项 writeup

接着再往下走,有一个地方引起了我的注意。

2018 DDCTF 杂项 writeup

TLSv1.2https 上使用的,后面的传输数据都会被服务器的私钥进行加密,然后这时想起上面得到的那张图片,就联系起来了。百度了一下在 wireshark 里还原 https 数据的方法: 传送门 。按照这里的方法进行恢复,然后就能拿到flag了。

2018 DDCTF 杂项 writeup

PS一下:这里对我提取出来的文件进行 md5 ,但都没有得到题目中给的那个值。。。

安全通信

题目描述:

请通过nc 116.85.48.103 5002答题,mission key是f49348cf84d390da52498077ae7137d5,agent id随意填就可以
#!/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()

这道题考的是 aes ecb 的攻击方法,经过一通 google 后找到了一个比较有参考意义的writeup,传送门。

需要了解的是 ECB分组 加密的(一组16个字符),也就是一块一块的,这点是我们后续攻击的重要前提。

2018 DDCTF 杂项 writeup

然后我们看一下他这个脚本,经过分析后我们可以发现加密的消息的 长度 我们是可以控制的。

2018 DDCTF 杂项 writeup

而且对于一次 连接 ,在同一密钥的情况下,我们可以随意加密任何数据任何次。

2018 DDCTF 杂项 writeup

所以攻击手段就很清晰了。

明文分组(16个字符)             对于的密文(对得到的一长串密文进行32位切割)
Connection for m     ---->   eae138090c7a60d97a6c54ce15fe7888    # 第1块
ission: 12345678     ---->   aaaab01d2ba84861447153e790047db4    # 第2块
90123, your miss     ---->   d9d2a15efa5c6f75097d89f1e5cc629c    # 第3块
ion's flag is: D     ---->   8e16cf020a37e52a28fdee32d469c2b4    # 第4块
DCTF{afafjafj101     ---->   5ca9b0e48d1dec7bb06a73dd163380a0    # 第5块
.....

如上所示,我们可以控制 name 的长度来使(在这种情况下) 第4块 的最后一个字符是 flag 中我们要求的第一个字符,而它明文的前15个字符我们是知道的,密文我们也知道,所以我们可以使用这样来暴力猜测出 最后一位 到底是什么。

# 伪代码
raw = 'ion's flag is: '
for ch in range(33,128):
    tmp = raw + chr(ch)
    my_miwen = encrypt(tmp)
    if my_miwen == true_miwen:
        print('要求的是:',tmp)

所以只要我们设计好 填充的长度 就能将flag的所有字符都爆破出来。填充的时候有一个需要注意的地方就是块的 推进 (进位),因为你不能无限制退后,所以当我们用完填充块的大小后要更新需要爆破的块。代码如下:

# coding:utf-8
import socket   # 导入 socket 模块
import re

sc = None
c = '-'
def sendAgent(agent):
    global sc
    sc = socket.socket()  # 创建 socket 对象
    host = "116.85.48.103"  # 获取本地主机名
    port = 5002  # 设置端口
    addr = (host, port)
    sc.connect(addr)  # 绑定端口号
    sc.recv(1024)  # 打印接收的数据
    sc.send('f49348cf84d390da52498077ae7137d5\n')
    sc.recv(1024)  # 打印接收的数据
    sc.send(agent+'\n')
    return sc.recv(1024)

def tryChar():
    raw = '0000000000000000'
    allstr = "Connection for mission: {}, your mission's flag is: "
    while True:
        # 除去 {},
        req = 15 - (len(allstr)-2) % 16 # 求出要填充的长度
        raw_t = raw[:req]

        raw_t_concat = allstr.format(raw_t).replace('-','{',-1).replace('=','}',-1)
        print(raw_t_concat)
        rex = re.compile('.{1,16}') # 对明文进行分组
        tmp = re.findall(rex, raw_t_concat)
        print(tmp)
        rs_len = len(tmp) # 分组长度
        rs = tmp[-1]      # 要爆破的块(最后一块)
        print('正在爆破:%s' % rs)
        # 重新连接 发送Agent = raw_t
        firstRs = sendAgent(raw_t)
        block = re.findall('.{32}',firstRs)[rs_len-1]   # 拿到密文对应需要爆破的明文分组的一块

        # 爆破
        for cs in range(33,128):
            sc.recv(1024)
            sc.send(rs+ chr(cs)+'\n')
            rss = sc.recv(1024).split('\n') [0]
            if rss==block:
                c = chr(cs)
                allstr+=c.replace('{','-').replace('}', '=')
                break
        if c=='}':
            print('over!')
            return
tryChar()

最后得到flag: DDCTF{87fa2cd38a4259c29ab1af39995be81a}


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

嵌入式Linux应用开发完全手册

嵌入式Linux应用开发完全手册

韦东山 主编 / 人民邮电出版社 / 2008-8 / 69.00元

本书全部实例代码及相关工具。 基于ARM 9+Linux 206平台,从基础讲起,引导读者快速入门,实例丰富,可直接应用于工程实践。 本书全面介绍了嵌入式Linux系统开发过程中,从底层系统支持到上层GUI应用的方方面面,内容涵盖Linux操作系统的安装及相关工具的使用、配置,嵌入式编程所需要的基础知识(交叉编译工具的选项设置、Makefile语法、ARM汇编指令等),硬件部件的使用及......一起来看看 《嵌入式Linux应用开发完全手册》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换