>
>
CTFshow-萌新赛-Re Writeup
fffdy
数学不及格
逻辑清楚,比较简单
先传入 4 个参数,第 4 个参数减去 25923 传入 f()
f(a) 功能就是返回斐波拉契数列第 a 项
然后满足四个方程,解开就 ok 了
解出来
V4=58
V9=591286729879
v10=439904987003
v11=474148725349
v12=435392374130
然后把四个参数转成 16 进制拼在一起得到
666c61677b6e65776265655f686572657d
转成 str 就是 flag
s='666c61677b6e65776265655f686572657d'
flag=''
for i in range(0,len(s),2):
flag+=chr(int(s[i:i+2],16))
print flag
@condor2048 大佬用的
bytes.fromhex(s)
ps:本来是涉及取模运算,存在多解,所以群主改了,有取模的话可能还要好玩一点
flag白给
先用 Wine 运行一下查看特征
随便输入,弹出 错误
IDA 打开发现有 UPX 壳,命令行 upx -d 脱壳后 IDA 重新载入
shift+f12 查看字符表,没看到有用的东西
虽然这种题一般都不会找到有用的字符串
从导入表里找到 GetWindowTextA
跟进,一路回溯到一个名叫 TForm1_Button1Click
至于为什么找他,因为他的名字就很有鬼
两个 str___[1] 一个是 成功 ,一个是 错误
然后看看这个函数逻辑,判断 v6 是不是等于 str_HackAv[1]
str_HackAv[1] 是 HackAv
,盲猜 v6 就是输入
这个题可能动态调试要快很多,但是
签退
开始的时候用的在线的反编译,效果非常糟糕,原来的 uncompyle2 又迷之不能用
只好装了一个
pip install uncompyle
uncompyle6 re3.pyc > re3.py
得到源码
# uncompyle6 version 3.6.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.17 (default, Jan 19 2020, 19:54:54)
# [GCC 9.2.1 20200110]
# Embedded file name: re3.py
# Compiled at: 2020-03-06 17:43:28
import string
c_charset = string.ascii_uppercase + string.ascii_lowercase + string.digits + '()'
flag = 'BozjB3vlZ3ThBn9bZ2jhOH93ZaH9'
def encode(origin_bytes):
c_bytes = [ ('{:0>8}').format(str(bin(b)).replace('0b', '')) for b in origin_bytes ]
resp = ''
nums = len(c_bytes) // 3
remain = len(c_bytes) % 3
integral_part = c_bytes[0:3 * nums]
while integral_part:
tmp_unit = ('').join(integral_part[0:3])
tmp_unit = [ int(tmp_unit[x:x + 6], 2) for x in [0, 6, 12, 18] ]
resp += ('').join([ c_charset[i] for i in tmp_unit ])
integral_part = integral_part[3:]
if remain:
remain_part = ('').join(c_bytes[3 * nums:]) + (3 - remain) * '0' * 8
tmp_unit = [ int(remain_part[x:x + 6], 2) for x in [0, 6, 12, 18] ][:remain + 1]
resp += ('').join([ c_charset[i] for i in tmp_unit ]) + (3 - remain) * '.'
return rend(resp)
def rend(s):
def encodeCh(ch):
f = lambda x: chr((ord(ch) - x + 2) % 26 + x)
if ch.islower():
return f(97)
if ch.isupper():
return f(65)
return ch
return ('').join(encodeCh(c) for c in s)
# okay decompiling re3.pyc
有个 flag 字符串,多半就是加密后的 flag
流程就是 flag 经过 encode() 加密后再传给 rend() 经过 encodeCh() 加密
这个 encode() 看着挺复杂的,但结合 //3
%3
等等特征可以猜测他是 base64 加密
为验证我的猜想,输出字符集 c_charset 查看
c_charset = string.ascii_uppercase + string.ascii_lowercase + string.digits + '()'
print c_charset
#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789()
其实就是把 base64 字符集的最后两位 +/
换成 ()
,而且没有用到
之后就简单的写个脚本爆破一下,再 base64 解码就搞定了
#python2.7
import string
import base64
c_charset = string.ascii_uppercase + string.ascii_lowercase + string.digits + '()'
flag = 'BozjB3vlZ3ThBn9bZ2jhOH93ZaH9'
print c_charset
print len(c_charset)
def encodeCh(ch):
f = lambda x: chr((ord(ch) - x + 2) % 26 + x)
if ch.islower():
return f(97)
if ch.isupper():
return f(65)
return ch
trueflag=''
for i in flag:
for j in c_charset:
if(encodeCh(j)==i):
trueflag+=j
break
print trueflag
print base64.b64decode(trueflag)
ps:无法理解为啥 python3 不向下兼容,有时候难受死了
condor2048
大佬牛逼,讲解清晰
admin
师傅牛批
yuchoxuuan
膜拜大佬
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论