190825 reverse-ogeek初赛

这篇博客详细介绍了四个逆向工程挑战:8V涉及字节异或解密,babyre是类似LZ77的压缩算法,BDOnline需要解包和解密数组,而ReverseMe包含Java Native接口的解密和哈希检查。作者分享了解题思路和过程,包括如何解密字符串和绕过检查点。
摘要由CSDN通过智能技术生成

好久没写博客了_(:з」∠)_回头有空补一下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,分别是nmaelibstamina.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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值