首页
社区
课程
招聘
[原创]看雪CTF·TSRC团队赛第五题-交响曲
2018-12-10 10:47 2373

[原创]看雪CTF·TSRC团队赛第五题-交响曲

2018-12-10 10:47
2373
(有些地方比较详细,大佬请绕过~)
先跑起应用,大概了解下题目思路
还是惯例,要求输入一串字符,通过程序计算比对,输出比对结果。
接下来,查看程序逻辑,将apk文件拖入jeb进行反编译:

可以看到该apkdex文件结构很简单,只包含了一个自定义类,右键decompile,查看代码逻辑:
①打开后可以发现dex经过了Proguard混淆,所以需要变分析边修改函数及变量名,以便于帮助分析。
②熟悉Android看法的都应该知道,按钮的点击监听函数,command+F搜索“click”关键字,目的是找到“验证”按钮的onClick方法,如下图所示:
③可以发现目标方法并不是native方法,只需要逆向java代码就OK。接着抽丝剥茧,一步步理清代码逻辑

输入函数getInput(),获取EditText输入,对前八位分段处理,前四位,中两位,后两位分别转成int,复制給成员变量sub2Int_1、sub2Int_2、sub2Int_3。并且根据限定条件可以推出三个数的取值范围:sub2Int_1 ->(1983,2007),sub2Int_2 ->[1,12],sub2Int_3 ->[1,31]

tansform1()函数对三个数的值进行一次变换:

sub2Int_1_t_m()、sub2Int_2_t_m()、sub2Int_3_t_m()对三个数的值进行二次变换,并以变换后的值作为数组下标,分别取int数组d,c,b中的值

transform2()函数对剩余的字符串进行约束即是否在String数组_to_Arr中,并返回以_to_Arr的下标取int数组a中的值。(在此就可以大概推出sub2Int_2_t的值为2,返回k的值是有限个)

i34()进行最后的计算和输出,可以推出传入的参数I的值==34,即sub2Int_1_t_m + sub2Int_2_t_m + sub2Int_3_t_m + transform2 == 34

④总结一下:
"""
已知:
sub2Int_1 = str(mStr[0:4])
sub2Int_2 = str(mStr[4:6])
sub2Int_3 = str(mStr[6:8])

sub2Int_1 ->(1983,2007)
sub2Int_2 ->[1,12]
sub2Int_3 ->[1,31]

transform1()变换Int_1,sub2Int_2,sub2Int_3,且由transform2()可知变换后的sub2Int_2的值应该为2

sub2Int_1_t_m + sub2Int_2_t_m + sub2Int_3_t_m + transform2 == 34;

transform2()返回的是以剩余字符串早to_arr[]数组中下标取a[]中的值

求:sub2Int_1,sub2Int_2,sub2Int_3,a[]下标

"""
⑤编写代码,跑出结果
class Getoutofloop(Exception):
    pass


mStr = ''


def sub2Int_1_t_m(sub2Int_1_t):
    return d[(sub2Int_1_t - 1900) % 60]


def sub2Int_2_t_m(sub2Int_2_t):
    return c[(sub2Int_2_t - 1)]


def sub2Int_3_t_m(sub2Int_3_t):
    return b[(sub2Int_3_t - 1)]


def transform2():
    subStr = mStr[8:len(mStr)]  # 除去前8位
    i = 0
    kk = 0
    while (True):
        if (i >= len(to_arr)):
            break
        elif (subStr == to_arr[i]):  # 除'11to13'
            if (sub2Int_2_t == 2 and subStr == to_arr[6]):
                return 63
            kk = a[i]
        else:
            i = i + 1
    return kk


def transform1(sub2Int_1, sub2Int_2, sub2Int_3):
    if (sub2Int_1 == 1989 or sub2Int_1 == 2004):
        sub2Int_3 = 31

    if (sub2Int_2 == 1 or sub2Int_2 == 4 or sub2Int_2 == 5 or sub2Int_2 == 7 or
        sub2Int_2 == 10 or sub2Int_2 == 11 or sub2Int_2 == 12):
        sub2Int_1 = 1999

    if (sub2Int_1 <= 1994 and (sub2Int_2 == 2 or sub2Int_2 == 6 or sub2Int_2 == 8)):
        sub2Int_2 = 3

    if (sub2Int_1 >= 1996 and (sub2Int_2 == 2 or sub2Int_2 == 6 or sub2Int_2 == 8)):
        sub2Int_2 = 9

    if (sub2Int_1 == 1995 and (sub2Int_3 > sub2Int_2 + 2 or sub2Int_2 == sub2Int_3)):
        sub2Int_2 = 6
    return sub2Int_1, sub2Int_2, sub2Int_3


if __name__ == '__main__':
    print('d.length=',len(d))
    print('c.length=', len(c))
    print('b.length=',len(b))
    print('to_arr.length=',len(to_arr))
    result = []

    # tmp = [1983,1984,1985,1986,1987,1988,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2005,2006]

    try:
        for i in range(1984,2007): #sub2Int_1
            for j in range(1, 13): #sub2Int_2
                for k in range(1, 32): #sub2Int_3
                    for m in range(len(a)):
                        sub2Int_1_t, sub2Int_2_t, sub2Int_3_t = transform1(i, j, k)
                        if sub2Int_3_t == 31:
                            break
                        m1 = (sub2Int_1_t - 1900) % 60
                        m2 = sub2Int_2_t - 1
                        m3 = sub2Int_3_t - 1
                        print(m1,m2,m3)
                        if (d[m1] + c[m2] + b[m3] + a[m]) == 34:
                            print(d[m1],c[m2],b[m3],a[m])
                            print('i=',i,'j=',j,'k=',k,'to=',m)
                            result.append((i,j,k,m))

    except Getoutofloop:
        pass

    print(result)
得到结果:[(1995, 2, 3, 3), (1995, 2, 3, 6)],排除第二个结果,将第一取对应字符串拼接得到结果:1995020305to07

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 3
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回