cracking_game

本文通过分析一个名为cracking_game的ELF文件,详细介绍了如何利用汇编代码和爆破方法找到三段式的密钥(flag)。文章包括从权限设置、保护机制检查到IDA静态分析的过程,并分享了一个实际的爆破脚本。

D:+++++++++\2018.8.7比赛\cracking_game

查看二进制码,发现是个ELF文件,先放到Linux环境运行一波,首先给权限chmod 777 cracking_game

发现回车之后还让我们输入,接着输,完了之后,还让输,直到三段之后,输出了Hmm…

由此最后可能有三个key,或者flag由三段组成

我们看一下他开了什么保护:checksec cracking_game

我去全开了,第一次遇见,平常都是有一个NX保护,我们先用ida静态看一下反编译的代码

到这里看到了flag的标志,果然是由三段组成的,点击进去看看代码:

果然,那么多保护不是白开的,反编译不了,凉了一半,有没有,打破了往常做题的一贯套路,那怎么办呢?看汇编代码呗

找到了关键的汇编代码:

分析,找到了关键的输入函数,在call 函数之前,参数先由右往左进栈,所以var_20为参数1,var20为参数2,var20为参数3

再输入函数下面分别将这三个参数(输入的flag)地址给了寄存器eax ebx edx,我们刚才说了var_28为参数1,先看参数1都进行了什么操作,

可以看到又将eax+376DA237地址给了esi,之后就关注esi寄存器做了什么操作

可以看到黄条的都是对esi寄存器做的修改,异或,加,

发现只要ecx不为0,就会跳转到Hmm的地方,那么只要保证ecx==0就行了,现在思路理清了,第一段key,经过一系列运算,最后让ecx==0,我们可以根据汇编代码写出来破解脚本

脚本有两种写法:1 逆向推理 2 爆破

发现逆向推理会有溢出现象,我们选择爆破的方式:

爆破首先要确定爆破的范围,其次是爆破需要的条件,由于ecx是32位寄存器,所以爆破范围0xffffffff,每一步加上与0xffffffff相与,是因为在加的过程中会出现比32位大的高位,在程序32位寄存器中会丢弃,所以每一步和0xffffffff相与:

注:由于爆破范围太大,可以把一层循环的32位0xffffffff分成两层循环,一层八位0xff,二层24位0xffffff,二层循环做左移位,然后和一层相或,这样可以将二层循环的高两位剔除,换成一层循环的低两位,会快一点,也可以用一层循环,但是每次都要改循环范围,逐步缩小,这样的话必须一段一段来爆破了,很麻烦,也有可能会错失key

bool_flag=0
for j in range(0xff):
    for i in range(0xffffff):
        if((((((((((((i<<8)|j)&0xffffffff)+0x376DA237)&0xffffffff)^0x5039B3AD)+0x197C0136)&0xffffffff)^0x1363F241)-0x74D86A5E)&0xffffffff)==0):
            print ("eax=key[0]="+hex((i<<8)|j))
            bool_flag=1
            break
    if bool_flag==1:
        break

按照汇编可以写出第一部分的脚本

第二、三部分跟第一部分程序一样,最终的脚本:

bool_flag=0
for j in range(0xff):
    for i in range(0xffffff):
        if((((((((((((i<<8)|j)&0xffffffff)+0x376DA237)&0xffffffff)^0x5039B3AD)+0x197C0136)&0xffffffff)^0x1363F241)-0x74D86A5E)&0xffffffff)==0):
            print ("eax=key[0]="+hex((i<<8)|j))
            bool_flag=1
            break
    if bool_flag==1:
        break
#eax=0xe698830d
bool_flag=0
for j in range(0xff):
    for i in range(0xffffff):
        if(((((((((((((((((((((((((((((((((i<<8)|j)&0xffffffff)+0x5A46BABC)&0xffffffff)^0x58E7773A)-0x3617A80B)&0xffffffff)^0x74A4134B)+0x4D6F9F5A)&0xffffffff)^0x2A3457E6)+0x4B8BF8B9)&0xffffffff)^0x0BB5D6AFF)+0x3EB308B5)&0xffffffff)
       ^ 0x3C5A9BE1)-0x4EF22DAE)&0xffffffff)^0x9D91B40F)-0x42596E22)&0xffffffff)^0x5D8ACD6E)+0x57794904)&0xffffffff)^0x481EE77)-0x2CF219D2)&0xffffffff)^0x5702EC35)
    +0x67B243DF)&0xffffffff)^0x80CAFC7B==0):
            print ("ebx=key[1]="+hex((i<<8)|j))
            bool_flag = 1
            break
    if bool_flag==1:
        break
#ebx=0x8dd70651
bool_flag=0
for j in range(0xff):
    for i in range(0xffffff):
        if(((((((((((((((((((((((((((((((i<<8)|j)&0xffffffff)^0x63074EB7)-0x0F5DED87)&0xffffffff)^0x3D898713)-0x1EBAD7B8)&0xffffffff)^0x0D4A1204D)-0x126E5E14)&0xffffffff)
        ^0x0DB034E6B)-0x68C8F0D3)&0xffffffff)^0x85AEAF52)+0x20E21188)&0xffffffff)^0x0CDC4D471)+0x6492A3E9)&0xffffffff)^0x5BF4CECF)
        +0x28EF6935)&0xffffffff)^0x97C13118)-0x7624D9FB)&0xffffffff)^0x5B589A)
    +0x64B87E0E)&0xffffffff)^0x0DF2FFB19==0):
            print ("edx=key[2]="+hex((i<<8)|j))
            bool_flag = 1
            break
    if bool_flag==1:
           break
#edx=0xc1ecd292

由于爆破的范围有点大,所以程序运行很长时间才有结果,大概运行了有一个小时,是不是很扯^_^

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值