作者因为之前电脑丢了导致中间两个月断更,最近会把之前的很多都补回来。言归正传,这次比赛总体来说不太理想,没有达到预期。

比赛情况总结

我,学姐,学长分别出一题,最终得分350,排名在42。而我是出了一道密码题,pwn题没出,因为pwn题一道shellcode题当时分析没有考虑\0截断的这个特性,以为所有shellcode都要满足这个特性,觉得手撕汇编撕不过,就放弃了,没想到竟是一个\0绕过,这波,属实大意了闪了。

部分题目writeup

Crypto-Easy Railfence

观察加密方式,发现这个加密只进行了位置对换,并且开头特意提醒flag的形式为 flag{} ,那么先根据 已有长度写出参数

1
m='flag{_________________________________________________________}'

现在Rail和offset不确定,但是 flag的格式确定,因此对参数进行爆破,然后观察发现l和g还有{}在整个 给的加密结果中只有一个并且位置已经确定,那么根据这个特性写出如下脚本。

1
2
3
4
5
#encrypt函数将结尾的print (d)改成了return d
for Rail in range(2,20):
for Offset in range(0,30):
if encrypt(m, Rail , Offset)[23:25]=='}l':
print(Rail,Offset)

得到两个结果 13 5和13 29,填充位位数多了应该有一定的规律,因此offset取5即可。

由于这个加密方式只交换位置,因此我在某一位多的一个字符必然会在另一个位置一模一样的出现,将 已匹配的字符数作为该为有没有匹配的条件逐位爆破即可,以下为完整脚本。

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
31
32
33
34
35
36
37
38
39
40
# -*- coding: utf-8 -*-
import hashlib
target='reetdrvhns0eutbftafmeon}linnd=a1cOh!gcedos{neuwkYav0irOceytounw'
def encrypt(c,rails,offset):
c = '$' * offset + c
length = len(c)
result = {x: "" for x in range(rails)}
for a in range(length):
width = rails * 2 - 2
num = a % width
if (num < rails):
result.update({num: result[num] + c[a]})
else:
ll = 2 * rails - 2 - num
result.update({ll: result[ll] + c[a]})
d = ""
for k in range(rails):
d = d + result[k]
d = d.replace('$','')
return d
def compare(str1,str2):
ans=0
for i in range(len(str2)):
if(str1[i]==str2[i]):ans+=1
return ans
Rail=13
Offset=5
m='flag{_________________________________________________________}'
'''
for Rail in range(2,20):
for Offset in range(0,30):
if encrypt(m, Rail , Offset)[23:25]=='}l':
print(Rail,Offset)
'''
for i in range(5,63):
for j in range(33,127):
m=m[:i]+chr(j)+m[i+1:]
if compare(target,encrypt(m, Rail , Offset))==i+2:
break
print(m)

得到flag

1
flag{YOucanc1imb0verthefenceeveny0udOnotunderstandhowitworks!=}

再放工具md5即可。

可能是固定的算法思维吧,就只想到这个,忘了有工具这种东西了。参数解出来放在CyberChef中可以直接一把梭。

pwn-sx

分析文件是一道shellcode 题目,然后输入的shellcode经过传参到这个函数来判断是否合法,我以为都要满足,然后小算了一下发现限制很多,分组限制,当时我挺绝望的,想着这谁能做啊。可是结束之后我才想到可以\0字节绕过判断后面直接跟上shellcode ,只要保证前面能正确执行指令满足那些条件就可以。这里需要用到CyberChef工具中的disassemble,可以直接根据字节码转出来汇编指令,只要执行不产生异常,不让它指令偏移那就都可以放上来。

小算一波,发现下标%3=0的字节只能在[0xc0-0xff]范围内,%3=1和%3=2的则在0x80-0xbf的范围内。那就一个个指令尝试过去,最后发现一个很合适的。

执行完之后刚好能在最后一个00字节之后,后面填上shellcode直接打就结束了,下面附上本地运行结果。

经过本次比赛,也意识到自己的不足应该是这些基础知识,算法优势应当好好利用起来去破密码试试看。总之,初赛过去,就得看向决赛了,争取在决赛上能一鸣惊人,加油!