IceCTF 2016

来源:互联网 发布:鸟倦飞而知还的而用法 编辑:程序博客网 时间:2024/05/29 07:31

WriteUp

  1. Corrupt Transmission
  2. Rotated!
  3. Blue Monday
  4. All your Base are belong to us
  5. Thor’s a hacker now
  6. Scavenger Hunt
  7. R.I.P Transmission

涨姿势

  1. Audio Problems
  2. Intercepted Conversations Pt.1
  3. Intercepted Conversations Pt.2

Corrupt Transmission

原题

这里写图片描述

解题思路

PNG图片格式

WriteUp

已知PNG是损坏的,拿张正常的PNG对比,一下就可以发现题目的PNG前几个字节不对

这里写图片描述

这里写图片描述

将正确的字节替换错误的字节保存即可

这里写图片描述


Blue Monday

原题

这里写图片描述

解题思路

观察法

WriteUp

不知道是什么文件,用HxD看看再说

这里写图片描述

可以知道这是MIDI文件,播放一遍后没发现异常,准备用Audacity看看,这时发现了关键信息

这里写图片描述

在字节数据中发现了IceCTF,这不就是flag的开头吗?接下来还有' { '符号和' } '符号,可以肯定flag就在其中,那么只要一个个字符抄下来即可

Rotated!

原题

这里写图片描述

解题思路

ROT13

WriteUp

这里写图片描述


All your Base are belong to us

原题

这里写图片描述

解题思路

二进制转ASCII

WriteUp

这里写图片描述

将前面两个转为十进制再转为ASCII对照一下就可以发现是要将所有二进制转为ASCII
f = open('01.txt','r')numList = []for line in f.readlines():    numList += list(line.rstrip().split(' '))s = ''for n in numList:    s += chr(int(n,2))print(s)

Thor’s a hacker now

原题

这里写图片描述

解题思路

LZIP是Linux压缩文件

WriteUp
这里写图片描述

很明显这是某种文件在十六进制查看工具下的数据分布,开头的前几个bytes说明了文件类型:LZIP
将数据部分提取出来后粘贴到HxD中生成文件,Linux下解压即可
f = open('in.txt','r')f2 = open('out.txt','w')for line in f.readlines():    line = line[10:50]+'\n'    f2.write(line)f.close()f2.close()

这里写图片描述

这里写图片描述


Scavenger Hunt

原题

这里写图片描述

解题思路

那就找吧

WriteUp

整个网站下载下来就容易找了

这里写图片描述

这里写图片描述


R.I.P Transmission

原题

这里写图片描述

解题思路

Binwalk,爆破

WriteUp

直接仍Binwalk里面可以发现隐藏有zip文件

这里写图片描述

提取出来发现需要密码,爆破即可

这里写图片描述

这里写图片描述


Audio Problems

原题

这里写图片描述

解题思路

Audacity?还是要sox

WriteUp

惯例先上Audacity,频谱图有发现,不过好像太模糊了

这里写图片描述

怎么看都看不清,怎么办,sox试试啊

这里写图片描述

涨姿势点

sox, the Swiss Army knife of sound processing programs掌握基本用法

Intercepted Conversations Pt.1

原题

这里写图片描述

解题思路

键盘数据包,tshark提取数据,Dvorak键盘

WriteUp

参考资料

从后缀 '.pcapng' 为截取的数据包,Wireshark查看证实是usb通信的数据包

这里写图片描述

那么应该就是要从里面提取键盘输入的数据,用tshark完成
tshark -r interceptpt1.pcapng -T fields -e usb.capdata -Y 'usb.capdata && usb.transfer_type == 0x01 && frame.len == 72' >cap.txt
提取的数据如下02 和 20 开头的数据表示输入的是大写02 = 20 = shift

这里写图片描述

学过汇编应该都知道系统在读取键盘输入时在缓冲区存储的是字母的代码,例如G的代码是0x0a,前面的02或者20控制大写,那么我们就要把代码转换为字母
可是转换后会发现根本就不是flag,这个时候就要用到另一种键盘,Dvorak键盘,它的字母排列和我们常用的键盘不同,只要在根据转化表转换即可
#代码修改自 @Jhonathan Davihids_codes = {"0x04":"a","0x05":"b","0x06":"c","0x07":"d","0x08":"e","0x09":"f","0x0A":"g","0x0B":"h","0x0C":"i","0x0D":"j","0x0E":"k","0x0F":"l","0x10":"m","0x11":"n","0x12":"o","0x13":"p","0x14":"q","0x15":"r","0x16":"s","0x17":"t","0x18":"u","0x19":"v","0x1A":"w","0x1B":"x","0x1C":"y","0x1D":"z","0x1E":"1","0x1F":"2","0x20":"3","0x21":"4","0x22":"5","0x23":"6","0x24":"7","0x25":"8","0x26":"9","0x27":"0","0x36":",","0x33":":","0x28":"\n","0x2C":" ","0x2D":"_","0x2E":"=","0x2F":"{","0x30":"}"}layout_dvorak = { 'q':"'", 'w':',', 'e':'.', 'r':'p', 't':'y', 'y':'f', 'u':'g', 'i':'c', 'o':'r', 'p':'l', '_':'_', ':':'S','[':'/', '{':'{', '}':'}' ,']':'=','a':'a', 's':'o', 'd':'e', 'f':'u', 'g':'i', 'h':'d', 'j':'h', 'k':'t', 'l':'n', ';':'s', "'":'-','z':';', 'x':'q', 'c':'j', 'v':'k', 'b':'x', 'n':'b', 'm':'m', ',':'w', '.':'v', '.':'z',' ':' ','Q':"'", 'W':',', 'E':'.', 'R':'P', 'T':'Y', 'Y':'F', 'U':'G', 'I':'C', 'O':'R', 'P':'L','A':'A', 'S':'O', 'D':'E', 'F':'U', 'G':'I', 'H':'D', 'J':'H', 'K':'T', 'L':'N', ';':'S', "'":'-','Z':';', 'X':'Q', 'C':'J', 'V':'K', 'B':'X', 'N':'B', 'M':'M','0':'0','1':'1','2':'2','3':'3','4':'4','5':'5','6':'6','7':'7','7':'7','8':'8','9':'9'}flag = ''file = open('cap.txt','r') for line in file.readlines():    spli = line.split(':')    conv = '0x'+spli[2].upper()    if conv in hids_codes:        if spli[0] == '00':            flag += layout_dvorak[hids_codes[conv]]        else:            flag += layout_dvorak[hids_codes[conv].upper()]print(flag)

这里写图片描述

涨姿势点

Wireshark能抓取不同端口的数据包tshark的基本用法Dvorak键盘的排列不同于普通键盘

Intercepted Conversations Pt.1

原题

这里写图片描述

解题思路

Wireshark发现关键信息及提取文件,反编译pyc,算法逆向

WriteUp

参考资料

Wireshark分析数据包可以发现有个IRC网络的,解析几个数据包可以发现有人正在通信

这里写图片描述

这里写图片描述

这里写图片描述

从截取的对话可以发现通信方发送了一个名为 encode.pyc 的文件,我们可以在接下来的几个TCP协议的数据包的data段获取该文件

这里写图片描述

然后我们在通信的最后可以发现通信方发送了一个字符串'Wmkvw680HDzDqMK6UBXChDXCtC7CosKmw7R9w7JLwr/CoT44UcKNwp7DllpPwo3DtsOID8OPTcOWwrzDpi3CtMOKw4PColrCpXUYRhXChMK9w6PDhxfDicOdwoAgwpgNw5/Cvw=='

这里写图片描述

Google之后知道 .pyc文件是python文件编译后的文件,那么我们反编译后就可以获得 .py 文件,推测和最后一个字符串的加密有关,那么只要算法逆向就可以从字符串中得到关键信息
把获取到的文件数据粘贴进HxD中生成 .pyc 文件

这里写图片描述

接下来进行反编译,网上有在线反编译的,不过对于这个文件来说效果不好,那么就自己反编译,这里用到python'uncompyle6',用 pip 安装即可
这里顺便提一下文件开头的 16 0D的含义,这是magic number,不同版本编译出来的 .pyc 文件的magic number是不同的,具体可查阅 https://gist.github.com/delimitry/bad5496b52161449f6de。按照对照表,16 0D代表的是python 3.5b2 这在uncompyle6进行反编译时也会有提示

这里写图片描述

然后我们就得到了加密的 .py文件
import random            #加密 .pyimport base64P = [ 27, 35, 50, 11, 8, 20, 44, 30, 6, 1, 5, 2, 33, 16, 36, 64, 3, 61, 54, 25, 12, 21, 26, 10, 57, 53, 38, 56, 58, 37, 43, 17, 42, 47, 4, 14, 7, 46, 34, 19, 23, 40, 63, 18, 45, 60, 13, 15, 22, 9, 62, 51, 32, 55, 29, 24, 41, 39, 49, 52, 48, 28, 31, 59]inp = input()inp += ''.join((chr(random.randint(0, 47)) for _ in range(64 - len(inp) % 64)))ans = ['' for i in range(len(inp))]for j in range(0, len(inp), 64):    for i in range(64):        ans[j + P[i] - 1] = chr((ord(inp[j + i]) + S[i]) % 256)ans = ''.join(ans)print(base64.b64encode(ans.encode('utf8')).decode('utf8'))
分析加密代码后写出解密代码,解密最后一个字符串即可
# Offsec Research CTF Team   import random, base64, string, sysP = [27, 35, 50, 11, 8, 20, 44, 30, 6, 1, 5, 2, 33, 16, 36, 64, 3, 61, 54, 25, 12, 21, 26, 10, 57, 53, 38, 56, 58, 37, 43, 17, 42, 47, 4, 14, 7, 46, 34, 19, 23, 40, 63, 18, 45, 60, 13, 15, 22, 9, 62, 51, 32, 55, 29, 24, 41, 39, 49, 52, 48, 28, 31, 59]S = [68, 172, 225, 210, 148, 172, 72, 38, 208, 227, 0, 240, 193, 67, 122, 108, 252, 57, 174, 197, 83, 236, 16, 226, 133, 94, 104, 228, 135, 251, 150, 52, 85, 56, 174, 105, 215, 251, 111, 77, 44, 116, 128, 196, 43, 210, 214, 203, 109, 65, 157, 222, 93, 74, 209, 50, 11, 172, 247, 111, 80, 143, 70, 89]# comment these lines if not running under python2reload(sys)sys.setdefaultencoding('utf8')# Get the encoded flag and do the conversions in reverse orderans = ((base64.b64decode(sys.argv[1])).encode('utf8')).decode('utf8')# Create a list with length of character in ans (encoded flag)ans_list = list(ans)# Create empty inp listinp = ['' for i in range(len(ans))]for j in range(0, len(ans), 64):    for i in range(64):        # Try every printable ascii character and if the equation is satisfied, we've found one character of the initial input        for c in string.printable:            if (ans_list[j + P[i] - 1] == unichr(((ord(c) + S[i]) % 256))):                inp[j + i] = cinp = ''.join(inp)print(inp)

这里写图片描述

涨姿势点

IRC网络Wireshark从数据流中提取文件的方式不同版本的python编译后的 .pyc文件的magic number不同uncomple6反编译 .pyc文件,也有在线反编译的网站

备注

虽然文件是python 3.5的版本编译的,不过用uncompyle6反编译时的python版本为 2.7

原创粉丝点击