-
-
KCTF2019Q4 第三题 街机少年
-
2019-12-7 11:16 3621
-
1. base64
字符集: 0x3A-0x7A
src: 00aaaaaa 00bbcccc 00eedddd 00ffffff
dst: aaaaaabb ccccdddd eeffffff
2. F5的结果抠出来爆破
对sn的每个字节, 设置好条件, 每次得到的结果都是唯一的
3. 脚本
def hex2bin(s): return s.decode('hex') def bin2hex(s): return s.encode('hex').upper() def load_file(filename): f = open(filename, 'rb') s = f.read() f.close() return s def save_file(filename, s): f = open(filename, 'wb') f.write(s) f.close() return def b64_encode(s): r = '' for i in range(0, len(s), 3): ss = s[i:i+3] src_len = len(ss) src = [0] * 3 dst = [0] * 4 for j in range(src_len): src[j] = ord(ss[j]) dst[0] = src[0] >> 2 dst[1] = ((src[0] & 3) << 4) | (src[1] >> 4) dst[2] = (src[1] & 0x0F) | ((src[2] >> 6) << 4) dst[3] = src[2] & 0x3F if src_len == 1: dst[2] = 0x40 dst[3] = 0x40 if src_len == 2: dst[3] = 0x40 for j in range(4): r += chr(dst[j] + 0x3A) return r def b64_decode(s): r = '' for i in range(0, len(s), 4): dst_len = 3 src = [0] * 4 dst = [0] * 3 for j in range(4): v = ord(s[i+j]) if v == 0x7A: dst_len -= 1 src[j] = v - 0x3A # src: 00aaaaaa 00bbcccc 00eedddd 00ffffff # dst: aaaaaabb ccccdddd eeffffff dst[0] = ((src[0] << 2) & 0xFC) | (src[1] >> 4) dst[1] = ((src[1] << 4) & 0xF0) | (src[2] & 0x0F) dst[2] = ((src[2] << 2) & 0xC0) | src[3] for j in range(dst_len): r += chr(dst[j]) return r def sort_ascending(a, b): if a <= b: return a, b else: return b, a def fn1(v, bound=None): buf_const_416000 = [ 0x00, 0x03, 0x02, 0x05, 0x04, 0x07, 0x06, 0x09, 0x08, 0x0B, 0x0A, 0x0D, 0x0C, 0x0F, 0x0E, 0x11, 0x00, 0x02, 0x0C, 0x0E, 0x08, 0x0A, 0x14, 0x05, 0x07, 0x01, 0x03, 0x0D, 0x0F, 0x09, 0x0B, 0x00, 0x05, 0x06, 0x08, 0x0D, 0x0E, 0x03, 0x04, 0x19, 0x0B, 0x0C, 0x01, 0x02, 0x07, 0x00, 0x13, 0x17, 0x1B, 0x1F, 0x12, 0x16, 0x1A, 0x1E, 0x11, 0x15, 0x19, 0x1D, 0x00, 0x05, 0x09, 0x0E, 0x03, 0x18, 0x0C, 0x01, 0x06, 0x0A, 0x0F, 0x04, 0x00, 0x0A, 0x0C, 0x01, 0x0B, 0x0D, 0x06, 0x08, 0x12, 0x07, 0x09, 0x00, 0x0A, 0x03, 0x0D, 0x06, 0x1F, 0x09, 0x02, 0x0C, 0x05, 0x00, 0x09, 0x01, 0x0E, 0x06, 0x0F, 0x07, 0x0C, 0x04, 0x00, 0x08, 0x03, 0x0B, 0x02, 0x0A, 0x1D, 0x05, 0x00, 0x07, 0x0E, 0x04, 0x0B, 0x01, 0x08, 0x00, 0x0F, 0x05, 0x03, 0x0E, 0x04, 0x00, 0x0B, 0x07, 0x02, 0x0D, 0x00, 0x1C, 0x18, 0x14, 0x00, 0x0F, 0x0A, 0x00, 0x06, 0x00 ] v51 = v end = 16 if bound is None else int(bound) while True: v38 = v51 for i in range(1, end): v_smaller, v_bigger = sort_ascending(v38, v51) idx = v_bigger - v_smaller + (v_smaller - 1) * (34 - v_smaller) / 2 v38 = ((v_smaller * v_smaller) % 17) ^ buf_const_416000[idx] if v38 == 1 and i != (end - 1) and bound is None: v51 = (v51 + 1) % 16 + 1 v38 = 0 break if bound is not None: return v38 elif v38 == 1: return v51 def t1(v, low, high): v = fn1(v, low) low = v v = fn1(v) v = fn1(v, high) high = v v = fn1(v) return v, low, high base_dir = 'D:\\work\\2019\\pediy_Q4\\3\\' buf_const_416188 = [0] * 4096 buf_const_417288 = [0] * 65536 buf_const_427288 = [0] * 256 def fn_402090(a, b, c): v = 0 v |= (b & 3) << 10 v |= (c & 3) << 8 v |= ((c >> 2) & 3) << 6 v |= (a & 0x0F) << 2 v |= (b >> 2) & 3 v ^= 0x2C7 return v def fn2(buf_user_417188, buf_var_416088, low, high): low_1 = low - 1 v48 = high * buf_var_416088[(buf_user_417188[low_1] - high)] v48 &= 0xFF for n in range(low_1 + 1, 128): v5 = buf_const_416188[fn_402090(buf_user_417188[low_1], buf_user_417188[n], high)] if buf_user_417188[n] == 0: v5 += 1 v5 *= v48 v5 &= 0xFF v48 = ((v5 + 1) & (v5 != 0)) + v5 v48 &= 0xFF if (v48 % 2) == 0: buf_user_417188[low_1] += high buf_user_417188[low_1] &= 0xFF return False else: buf_user_417188[low_1] -= high buf_user_417188[low_1] &= 0xFF return True def init_consts(new=False): s = load_file(base_dir + 'buf_const_416188.txt') for i in range(len(s)): buf_const_416188[i] = ord(s[i]) s = load_file(base_dir + 'buf_const_417288.txt') for i in range(len(s)): buf_const_417288[i] = ord(s[i]) s = load_file(base_dir + 'buf_const_427288%s.txt' % ('_new' if new else '')) for i in range(len(s)): buf_const_427288[i] = ord(s[i]) return def is_ary_all_zero(ary, n): for i in range(n): if ary[i] != 0: return False return True def const_65536_map(a, b, c): idx = 0 idx |= (c + b + a) & 0x0F idx |= c << 4 idx |= b << 8 idx |= a << 12 v = buf_const_417288[idx] return v def save_buf_const_427288_new(): init_consts() s = '' for i in range(256): v = buf_const_427288[i] if (v & 1) == 0: s += chr(0xFF) else: s += chr(v >> 1) save_file(base_dir + 'buf_const_427288_new.txt', s) return def init_buf_user(buf_user_417188, username): for i in range(len(username)): v = ord(username[i]) if i < 7: buf_user_417188[i] = 7 - (v % 7) elif i < 10: buf_user_417188[i] = 8 + (v % 8) elif i < 13: buf_user_417188[i] = 7 - (v % 7) else: buf_user_417188[i] = 8 + (v % 8) return def test0(): init_consts(new=True) username = 'f3a25f8b29bb9cbc' sn = b64_decode('JXg@vwrpfoLbRcxvdYrvv[kyRSso') # username = 'KCTF' # sn = b64_decode('IRrBJtrsJi@dBWnwvyppwIpswIygxJzz') buf_user_417188 = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x05, 0x06, 0x07, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ] init_buf_user(buf_user_417188, username[1:]) buf_var_416088 = [ 0x09, 0x1A, 0x0D, 0x04, 0x1F, 0x3E, 0x28, 0x47, 0x4B, 0x6F, 0x7D, 0x85, 0xA5, 0xCE, 0xFF, 0x05, 0x24, 0x4B, 0x6A, 0x8C, 0xA7, 0xE6, 0x19, 0x56, 0x6B, 0xB6, 0xC0, 0x04, 0x48, 0x8B, 0xC4, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ] v51 = fn1(ord(username[0]) % 16 + 1) v44 = 5 print(buf_user_417188[:15]) for i_sn in range(len(sn)): low = (ord(sn[i_sn]) & 0x0F) + 1 high = ((ord(sn[i_sn]) >> 4) & 0x0F) + 1 # print('v51: %d, low: %d, high: %d' % (v51, low, high)) v51, low, high = t1(v51, low, high) if fn2(buf_user_417188, buf_var_416088, low, high): print('sub [%02Xh], %d' % (low-1, high)) else: # never goes here print('add [%02Xh], %d' % (low-1, high)) print(buf_user_417188[:15]) if is_ary_all_zero(buf_user_417188, 128): print('ok') return low = ((ord(sn[i_sn]) >> 4) & 0x0F) + 1 high = (ord(sn[i_sn + 1]) & 0x0F) + 1 idx = low >> 1 # only affects 1:1+8 bytes buf_var_416088[idx] += high buf_var_416088[idx] = buf_var_416088[idx] % 127 + 1 v = buf_user_417188[0] for i in range(1, 15, 2): v = const_65536_map(v, buf_user_417188[i], buf_user_417188[i + 1]) if v: # never goes here for i in range(15): k = buf_const_427288[(buf_user_417188[i] << 4) | v] if k != 0xFF: print('mov [%02Xh], %d' % (i, k)) buf_user_417188[i] = k break else: while True: v = v44 v44 = (v44 + 4) % 15 if buf_user_417188[v] == 1: print('dec [%02Xh]' % v) buf_user_417188[v] -= 1 break if buf_user_417188[v] > 1: v2 = (v * v + 1) % buf_user_417188[v] + 1 print('sub2 [%02Xh], %d' % (v, v2)) buf_user_417188[v] -= v2 break print(buf_user_417188[:15]) return def probe_calc(username, sn, buf_user_417188, buf_var_416088): v51 = fn1(ord(username[0]) % 16 + 1) init_buf_user(buf_user_417188, username[1:]) v44 = 5 for i_sn in range(len(sn)): low = (sn[i_sn] & 0x0F) + 1 high = ((sn[i_sn] >> 4) & 0x0F) + 1 v51, low, high = t1(v51, low, high) fn2(buf_user_417188, buf_var_416088, low, high) if (i_sn + 1) >= len(sn): break low = ((sn[i_sn] >> 4) & 0x0F) + 1 high = (sn[i_sn + 1] & 0x0F) + 1 idx = low >> 1 buf_var_416088[idx] += high buf_var_416088[idx] = buf_var_416088[idx] % 127 + 1 while True: v = v44 v44 = (v44 + 4) % 15 if buf_user_417188[v] == 1: buf_user_417188[v] -= 1 break if buf_user_417188[v] > 1: v2 = (v * v + 1) % buf_user_417188[v] + 1 buf_user_417188[v] -= v2 break return v51, v44 def probe_once(username, sn): for low in range(1, 17): for high in range(1, 17): tmp_user = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x05, 0x06, 0x07, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ] tmp_var = [ 0x09, 0x1A, 0x0D, 0x04, 0x1F, 0x3E, 0x28, 0x47, 0x4B, 0x6F, 0x7D, 0x85, 0xA5, 0xCE, 0xFF, 0x05, 0x24, 0x4B, 0x6A, 0x8C, 0xA7, 0xE6, 0x19, 0x56, 0x6B, 0xB6, 0xC0, 0x04, 0x48, 0x8B, 0xC4, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ] v51, v44 = probe_calc(username, sn, tmp_user, tmp_var) if is_ary_all_zero(tmp_user, 128): return False if len(sn) > 0: next_low = (sn[-1] >> 4) + 1 next_high = low idx = next_low >> 1 tmp_var[idx] += next_high tmp_var[idx] = tmp_var[idx] % 127 + 1 while True: v = v44 v44 = (v44 + 4) % 15 if tmp_user[v] == 1: tmp_user[v] -= 1 break if tmp_user[v] > 1: v2 = (v * v + 1) % tmp_user[v] + 1 tmp_user[v] -= v2 break new_v, new_low, new_high = t1(v51, low, high) if fn2(tmp_user, tmp_var, new_low, new_high): v = tmp_user[0] for i in range(1, 15, 2): v = const_65536_map(v, tmp_user[i], tmp_user[i + 1]) if v == 0: print('[%d]: %X%X' % (len(sn), high - 1, low - 1)) sn.append((high - 1 << 4) | (low - 1)) return True return False def probe(): init_consts(new=True) sn = [] username = 'f3a25f8b29bb9cbc' username = 'KCTF' while True: if not probe_once(username, sn): break s = '' for i in range(len(sn)): s += chr(sn[i]) s = b64_encode(s) print s return def test(): # test0() probe() return test()
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
赞赏
他的文章
KCTF2022春季赛 第三题 石像病毒
8257
KCTF2022春季赛 第二题 末日邀请
15382
KCTF2021秋季赛 第二题 迷失丛林
17916
KCTF2020秋季赛 第十题 终焉之战
8088
KCTF2020秋季赛 第九题 命悬一线
5816
看原图