这次比赛周五9点开始,但是我们周五满课,所以一直到晚上才开始做。这次比赛难度较小,我们队独立解出十几道题目。这里我主要写一下我做出来的题目。主要是逆向,此外还一道USB流量分析,以及一道拓展凯撒。
顺便说个彩蛋:
虽然在前三十,但是每个学校只能出一只队伍,呜呜呜~学长TQL~~
easyelf
流程大致如上图:
输入后,先对所有的异或一次,再分别对59,1115加密,这两段比较简单,直接**即可。
17~30也是异或,但是不是很好观察。不过倒着运算即可。
以上都比较清晰。一个新的思路需要注意,之前我做题碰到的都是可逆运算,所以直接逆运算求flag,但是今天这个复杂的不好逆运算,所以可以直接枚举所有的数据,暴力破解。如果某一个数据经过这些复杂的运算后,得到了已知的数据,那么这个数据就是我们要求的数据。
之后是花费我比较长时间的a17_30
其实看懂了之后并没有很麻烦,关键在于知道最后的哪个等式是哪个,初始的等式是哪个。然后倒着运算一次就可以了。
1 | ''' |
EasyRE
奇数时取左边一位字符,偶数时取右边一位字符。
1 | s = 'lfgaL{teU__stsr4_t3R3vSr}e' |
比较简单,不多赘述。有意思的是,这题150,而上面的那道是100分。
EASYReverse
主函数:
加密函数sub_401000:
a是已知的s = ‘IVaQIg]:DfDcL7=VN64bF3TfEE=WCCDh<c@fM3ADHCPgME9ANGd ‘
加密的字符串4个一组,字符串a三个一组。
第二个大if是对长度不能整除的,字符串的最后几个字符进行处理。
1 | s = 'IVaQIg]:DfDcL7=VN64bF3TfEE=WCCDh<c@fM3ADHCPgME9ANGd ' |
凯撒2
题目明示键值空间从26拓展到128,改一改凯撒的脚本即可。
但是要注意,如何以转换成字节流保存至文件中。strcut.pack
了解一下。
https://www.jianshu.com/p/5a985f29fa81
struct模块中最重要的三个函数是pack(), unpack(), calcsize()
1 | # 按照给定的格式化字符串,把数据封装成字符串(实际上是类似于c结构体的字节流) |
struct中支持的格式如下表:
| Format | C Type | Python | 字节数 |
| —— | —————— | —————— | —— |
| x | pad byte | no value | 1 |
| c | char | string of length 1 | 1 |
| b | signed char | integer | 1 |
| B | unsigned char | integer | 1 |
| ? | _Bool | bool | 1 |
| h | short | integer | 2 |
| H | unsigned short | integer | 2 |
| i | int | integer | 4 |
| I | unsigned int | integer or lon | 4 |
| l | long | integer | 4 |
| L | unsigned long | long | 4 |
| q | long long | long | 8 |
| Q | unsigned long long | long | 8 |
| f | float | float | 4 |
| d | double | float | 8 |
| s | char[] | string | 1 |
| p | char[] | string | 1 |
| P | void * | long | |
1 | import struct |
偏移60,得到一个文本,最后一个单词即为flag
USB
参考:
- https://www.cnblogs.com/hackxf/p/10670844.html
- https://blog.csdn.net/qq_36609913/article/details/78578406
- https://blog.csdn.net/u013771867/article/details/51465193
USB协议的数据部分在Leftover Capture Data域之中,在Mac和Linux下可以用tshark命令可以将 leftover capture data单独提取出来 命令如下:tshark -r capture.pcapng -T fields -e usb.capdata > usbdata.txt
(capture.pcapng改成相应的文件名)
数据即导出至usbdata.txt中。 - *tshark可以在linux直接使用。在windows要在wireshark的所在路径下进入cmd,并运行tshark.exe(注意是命令行)**
- USB流量分为键盘流量和鼠标流量。**
键盘数据包的数据长度为8个字节,击键信息集中在第3个字节,每次key stroke都会产生一个keyboard event usb packet。
鼠标数据包的数据长度为**4个字节,第一个字节代表按键,当取0x00时,代表没有按键、为0x01时,代表按左键,为0x02时,代表当前按键为右键。第二个字节可以看成是一个signed byte类型,其最高位为符号位,当这个值为正时,代表鼠标水平右移多少像素,为负时,代表水平左移多少像素。第三个字节与第二字节类似,代表垂直上下移动的偏移。
提取数据,发现只有两行,坑死我了。
你使劲滑鼠标,发现后面还有 - *鼠标流量数据包转换脚本**生成的mouse.txt如图(部分):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20nums = []
keys = open('usbdata.txt','r')
posx = 0
posy = 0
for line in keys:
if len(line) != 12 :
continue
x = int(line[3:5],16)
y = int(line[6:8],16)
if x > 127 :
x -= 256
if y > 127 :
y -= 256
posx = x
posy = y
btn_flag = int(line[0:2],16) # 1 for left , 2 for right , 0 for nothing
if btn_flag == 1 :
with open('mouse.txt', 'a ')as f:
f.write('%d %d\n'%(posx,posy))
keys.close()
然后可以用gnuplot将坐标画出来。
PS将图片水平翻转 180度旋转即可看到flag。
不过有点坑,flag是CTF{tHe_CAT_is_the_CULpRiT},大小写太坑了,以及第一个the. - *另附键位的对应数值**
1 | 第一列10进制键值,第二列16进制键值,第四列是按键 |