Lingze's blog Lingze's blog
timeline
about
friends
categories
tags

lingze

bin不是垃圾桶的意思!
timeline
about
friends
categories
tags
  • ctf_wp
  • hgame
lingze
2020-03-01

week3

# hgame week re

hgame week3 的re, 链接: https://pan.baidu.com/s/1jdYHLzhz3ygEtW0NPgqQsw 密码: w03a

@[toc]

# hidden

首先搜索字符串找到输出正误的函数,然后查看调用找到check函数:

程序逻辑比较清晰,就是在encode函数中加密,然后查看是否和两个值相等,

然后进入函数后看到对函数的处理只在后半段,前面只是处理数据,但是我们动调会发现函数会莫名的在前面这个函数中间跑飞:

动调时最关键的在于这个函数内部的这个调用:

步入调用内部,然后似乎还是一个比较完整的函数,一直找到后面的ret位置,然后按P, 分析为函数,还可以f5

得到一个加密的位置,而且最后调用的函数为我们直接输出正误的那个函数,所以这个程序前面静态看到的都是假的,真正的流程是运行到这个位置,然后直接判定了flag正误, 我们前面动调在这里推出也是因为程序已经运行完了。

然后看下程序的逻辑中间的几个运算基本可以直接反着写, 动调发现需要注意一个&0xff的操作,然后key是flag最后的两位,直接断到判定位置发现flag的加密是19×2的形式,避开了最后两位,所以我们后面的data中的对应flag位置就是key, 可以直接取出来。

然后就得到解密脚本:

key = [0x7d,0x65]
cipher_data = [8896099409227384902, 5221214014029134222, 5439652918615309179, 9331866693134944349, 9035724225678832282]
cipher = [(cipher_data[i] >> 8 * j) & 0xff  for i in range(5) for j in range(8)]
for i in range(19):
	for j in range(2):
		cipher[i + 19] ^= cipher[i]
		cipher[i + 19] += 0x67
		cipher[i + 19] &= 0xff
		cipher[i] -= key[j]
		cipher[i] &= 0xff
		cipher[i] ^= cipher[i + 19]
for i in range(40):
	print(chr(cipher[i]), end='')
1
2
3
4
5
6
7
8
9
10
11
12
13

注意倒这些,但是key需要注意下要反过来,或者写for j in range(1,-1,-1)

就得到flag:hgame{h1dden_1n_mem0ry_15_excited_2eeee}

# ollvm

简单动调看了下程序的运行,主要的加密就只有这个位置: 主要的判定位置是: table2[i] = ~flag[i] & (i + table1[i]) | ~(i + table1[i]) & flag[i] 由于是位运算, 我们看下这个运算时数据的二进制,然后得到一个这样的规矩: 所以这个加密对应的解密方式是一个异或关系而已, 直接在ida中解密出来,

addr1 = 0x602050
addr2 = 0x602080
arr1 = []
arr2 = []
for  i in range(34):
    arr1.append(Byte(addr1 + i))
    arr2.append(Byte(addr2 + i))
print(arr1)
print(arr2)
s = ''
for i in range(34):
    s += chr(arr2[i] ^ (arr1[i]+i))
print(s)
1
2
3
4
5
6
7
8
9
10
11
12
13

得到:

上次更新: 7/12/2020, 2:57:24 AM
Theme by Vdoing | Copyright © 2019-2021 lingze | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式