好久没写博客了_(:з」∠)_回头有空补一下DEFCON的过程和题目复盘啥的…
8V
对照v8的bytecode.h很容易知道各个操作符的意义
花点时间看下来即可
主要是两个大循环,逐字节读取并异或
g4 = 88
s = b"\xd2\"\xf1\x8d\xb7\xe0\xd0MF\x87T?\x1fI\x1c\xe7\xcb\x07\xc3\x95z\xb3z\x0b\xbb\xdb\xa1I\xc5;"
output = []
for i in range(30):
d = g4 ^ s[i]
output.append(d)
g4 = (g4*65 + 66)&0xff
for i in range(29,-1,-1):
d = g4 ^ output[i]
output[i] = d
g4 = (g4*35-16)&0xff
print("".join([chr(i) for i in output]))
babyre
浏览一遍可以看出来很明显是一种压缩算法,简单搜了一下发现比较像LZ77,但是据说有很多变种,没找到什么好的实现就接着自己逆了
简单理解了一下原理,在buff内搜索与后17个字节相匹配的最大子串,如果有就记录下buff的下标和子串长度,没有则写入原始内容以供之后使用
简单来说就是所有数据仅出现一次,其他地方全部用偏移量表示
sub_d40函数分为两块,分别是写入和压缩
首先读入17个字节,作为写入缓冲区的初值
然后开始在buff里寻找与写入缓冲区相等的部分
如果找到匹配子串了则记录偏移和长度
并在下一次循环时写入偏移和长度
若没找到则写入一个原始字节
然后继续读入,使写入缓冲区补足17个字节
关于写入,题目使用了一个类和按位或和各种位移来实现,理解起来稍微有些复杂,但实际上就是按位写的操作
do_1代表仅写入一个位,arg2即是写入的值
do_n则是写入arg3个位,arg2是写入的值(取低位)
具体实现自行研究吧
这里的do_1即写入一个位区分接下来的若干位是原始字节还是偏移元组
算法理解后,解压缩就很容易了,照着恢复即可
话是这么说,不知道哪里没实现好,恢复出的图有很多噪点233 不过勉强还是能看出flag的
另外这个写法由于是作为字符串来处理,再加上是按位操作,所以效率奇低
wsl的python3速度要比win下的快很多,比较神奇…
# with open("test.out", "rb") as f:
with open("output.file", "rb") as f:
data = f.read()
b = ""
print(len(data))
for i in range(len(data)):
if i%0x100000==0:
print(i)
f = f"{data[i]:08b}"
b += f
n = 0
output = bytearray()
while n<len(b)-13:
# ori byte
if b[n]=="1":
n += 1
c = int(b[n:n+8],2)
output += bytes((c,))
n += 8
# compress
else:
n += 1
global_idx = int(b[n:n+12], 2)-1
n += 12
buffer_idx = int(b[n:n+4], 2)+2
n += 4
# print((global_idx, buffer_idx))
if global_idx > len(output):
output += b"\x00"*buffer_idx
else:
for i in range(buffer_idx):
output += output[global_idx+i:global_idx+i+1]
with open("flag", "wb") as f:
f.write(output)
# print(output)
BDOnline
观察修改日期可以发现应该往system.img上去关注
解包后同样根据修改日期可以找到两个bin,分别是nmae
和libstamina.so
对nmae进行逆向可知该binary起了socket监听端口,将接受到的内容分成13和5字节,前者调用了上述so的undefined
函数,后者则与某个数组进行比较检查
[外链图片转存失败(img-TTvXKqpz-1566748494332)(https://raw.githubusercontent.com/whklhh/local/master/img/20190825232607.png)]
根据数组交叉引用找到赋值的地方,解密可得后5位
undefined里就是个常规的多元一次方程组了,以"|"分隔即可
[外链图片转存失败(img-JBXjkknD-1566748494333)(https://raw.githubusercontent.com/whklhh/local/master/img/20190825232806.png)]
z3求解可得
from z3 import *
input_ = [BitVec("a%d"%i, 16) for i in range(13