2017XDCTF-Writeup

大国庆的,做着做着就不想做了,假装自己是一个战队。

Crypto

基础为王


Wireshark打开,分析发现向 chuantu.biz POST上传了两张图片,导出数据提取图片,得到

1
flag1.png flag2.png


单张看雪花屏,利用StegSolve将两张图片异或得到flag

基础之base64


下载得到包含多行base64后的内容,解码后得到奇怪的c代码。

编译再反编译发现是个helloworld程序。突然发现源代码横着看有字母hide。想到base64隐写,找到脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
def get_base64_diff_value(s1, s2):
base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
res = 0
for i in xrange(len(s1)):
if s1[i] != s2[i]:
return abs(base64chars.index(s1[i]) - base64chars.index(s2[i]))
return res
def solve_stego():
with open('encode_code.txt', 'rb') as f:
file_lines = f.readlines()
bin_str = ''
for line in file_lines:
steg_line = line.replace('\n', '')
norm_line = line.replace('\n', '').decode('base64').encode('base64').replace('\n', '')
diff = get_base64_diff_value(steg_line, norm_line)
pads_num = steg_line.count('=')
if diff:
bin_str += bin(diff)[2:].zfill(pads_num * 2)
else:
bin_str += '0' * pads_num * 2
res_str = ''
for i in xrange(0, len(bin_str), 8):
res_str += chr(int(bin_str[i:i+8], 2))
print res_str
solve_stego()

BASE64隐写

由于base64是以6比特为一组,而ascii、unicode等编码,最小单位都是一字节,也就是8比特。所以会出现不能正好大小一致的情况,当这种情况出现base64会在最后一个比特位不足6位的结尾补0,而base64中补齐的等于号=可以用来判断补零数量,不过没有也可以正常解码。所以base64隐写就是在这补上的零里做手脚。通过对解码后字符串再进行base64编码,我们可以得到正常补零的结果,然后将其与隐写过后的字符串进行比对,即可获得隐写的内容。

参考资料:ZJPCCTF:我未见过的base64隐写

Web

web2


Python沙盒逃逸,使用#coding:rot_13即可绕过检测,执行系统命令,得到flag

Wireless

sos


根据飞机判断给的文件应该是1090MHz抓包得到的航空广播数据。使用dump1090解析数据包,得到flag

MISC

水表


两张m1卡的数据,做一下对比发现只有两字节不同。观察立刻发现0x30为48十六进制,0x24为36十六进制,其后校验位用FF-钱数。构造flag

邮箱


提示注册,wireshark过滤http中register字样

在POST请求中发现邮箱地址

勒索病毒


流量中发现一个压缩包

提取解压得到一个vbs脚本文件,其中拼接替换字符串后调用了Wsciprt.shell,不确定题目要求内容,沙盘运行,发现调用了wscript.exe

智能变电站


分析流量,主要聚焦在IEC61850所用的mms协议上。在mms的最后几条数据中发现正在向报告控制块LLN0$BR$brcbRelayDin发送使能信号。并且连续发送了十六个,符合题目信息

Android

Crack Me


下载后发现先是个压缩包里面才是apk,运行包含提示


其中CryImpl的decrypt方法缺失,想到一开始压缩包里的图片。在真正的图片后面发现rar头,提取解压得到缺失的方法

整理整个流程,先将输入参数与1异或,然后md5,再base64编码,最后与2异或,结果为flag

工作验证码


调用了libxdctf中的encrypt与verify

ida打开so,分析encrypt方法

获取输入后调用了x_v_w_k随后进行了base64编码,
x_v_w_k中与内置密钥进行了异或

verify中发现了与encrypt处理过后的字符串做对比的答案

逆向进行流程,得到flag,这里密钥遍历结束后还空了一位才再次从头开始,坑了很久。

Muggles


调用了libtest中的check和rvgs,check检查base64后的输入,rvgs负责输出真正的flag。
ida加载后找到check和rvgs地址,但是check是thumb模式而ida识别错误,修复后创建函数,发现与rvgs大致相同,少了一步减操作。


关键函数为sub_E48,将字符变为十六进制,高4位与0xD异或,低四位与0xE异或,然后两个十六进制数反向。结果在check中与4898b9febb9889ba48a9898acb3bdb3e4d 对比。

反向操作:

在程序中输入结果,得到最终flag