欢迎来到 无奈人生 安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

HCTF逆向题目详析

来源:未知 作者:wnhack 时间:2019-01-08 14:27 点击: 我要投稿
广告位API接口通信错误,查看德得广告获取帮助
很有水平的一场比赛,RE的几道题目质量都非常高。
由于自己的原因,只是看了题,没做,感觉就算认真做,也做不出来几题,毕竟太菜。哈哈!
下面就先从最简单的开始写!
 
seven
简单的签到题,只不过是放在了windows驱动里,从没接触过,稍微带来了一点麻烦,算法是很经典的吃豆子游戏,刚好看加解密时看到了,在键盘扫描码卡了很久。
关于驱动开发的一些API可以在MDSN上找到相关说明
如DriverEntry函数就是一个驱动程序的入口函数,过多的我就不班门弄斧了。

总之这个题就是有不认识的API,就直接在MDSN上找函数说明即可。
关于解题,还是搜索字符串,找到The input is the flag字样,交叉引用到sub_1400012F0函数,如果看过加解密的同学,应该能一眼看出这是吃豆子游戏(这可不是打广告),细看还真是!
就是如下这个矩阵

从o开始,沿着.走,一直走到7即可。
0x11 表示向上
0x1f 表示向下
0x1e 表示向左
0x20 表示向右

当时一直在想0x11和输入的关系,最后才知道原来是键盘的扫描码,分别对应wasd
OK那么此题轻易的解决了!我是不是很水!
(下面几题都算是复现,我是一个没有感情的杀手!)
 
LuckyStar
别看程序这么大只不是VS静态编译了而已。
其实也不难,一进来先搜索字符串,看到idaq.exe,x32dbg等常见调试器的字样,很明显有反调试,并且还看到一大段未识别的数据,感觉很像是自解码的部分,其实真正的加密部分就在这里。

关于反调试,不必紧张,动态调试时手动修改下寄存器即可。通过交叉引用找到TlsCallback_0函数,判断之前下断,绕过即可(直接patch比较方便)。
之后便是程序的自解密部分,最后便可以看到真正的加密的过程。


将00401780至00401939 undefine一下然后重新create function,IDA便可以识别,接下来的一段解密也是类似的,最后进行一个比较。有一点需要注意,在动调时候不知道什么情况,程序就蹦了,需要手动在401780函数处set ip然后跳转过去

加密部分其实就是变形的base64加上一个异或,类似的题目做的太多了,解密脚本如下:
table='''abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/'''
def mydecodeb64(enc):
    enc=enc.replace("=","")
    x="".join(map(lambda x:bin(table.index(x))[2:].zfill(6),enc))
    # print x
    for ap in range(8-(len(x)%8)):
        x+='0'
    # print x
    plain=[]
    for i in range((len(x))/8):
        plain.append(chr(eval('0b'+x[i*8:(i+1)*8])))
    return "".join(plain).replace("x00","")
def myencodeb64(plain):
    en=[]
    encode=[]
    for d in list(plain):
        en.append(bin(ord(d))[2:].zfill(8))
    plain="".join(en)
    for ap in range(6-(len(plain)%6)):
        plain+='0'
    # print enc
    for i in range((len(plain))/6):
        encode.append(table[eval('0b'+plain[i*6:(i+1)*6])])
    return "".join(encode)
in_base='D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3'
enc=[0x49, 0xE6, 0x57, 0xBD, 0x3A, 0x47, 0x11, 0x4C, 0x95, 0xBC, 0xEE, 0x32, 0x72, 0xA0, 0xF0, 0xDE, 0xAC, 0xF2, 0x83, 0x56, 0x83, 0x49, 0x6E, 0xA9, 0xA6, 0xC5, 0x67, 0x3C, 0xCA, 0xC8, 0xCC, 0x05]
rand=[0x4c,0xb2,0x7d,0xbe,0x04,0x3a,0x06,0x27,0x94,0xc1,0xdc,0x55,0x77,0xe5,0x8d,0x81,0x85,0xa6,0xf2,0x2d,0x83,0x1e,0x58,0xdc,0x96,0x81,0x1b,0x55,0xc8,0x8a,0xb5,0x0b]
f=[]
for i in range(32):
    f.append(chr(rand[i]^enc[i]^ord(in_base[i])))
a = "".join(f)
print a
flag=mydecodeb64(a)
print flag
 
PolishDuck
比赛的时候就简单看了一眼,只知道是个arduino程序。 很有水平的一场比赛,RE的几道题目质量都非常高。
由于自己的原因,只是看了题,没做,感觉就算认真做,也做不出来几题,毕竟太菜。哈哈!
下面就先从最简单的开始写!
 
seven copyright 无奈人生
简单的签到题,只不过是放在了windows驱动里,从没接触过,稍微带来了一点麻烦,算法是很经典的吃豆子游戏,刚好看加解密时看到了,在键盘扫描码卡了很久。
关于驱动开发的一些API可以在MDSN上找到相关说明
如DriverEntry函数就是一个驱动程序的入口函数,过多的我就不班门弄斧了。

www.wnhack.com


总之这个题就是有不认识的API,就直接在MDSN上找函数说明即可。
关于解题,还是搜索字符串,找到The input is the flag字样,交叉引用到sub_1400012F0函数,如果看过加解密的同学,应该能一眼看出这是吃豆子游戏(这可不是打广告),细看还真是!
就是如下这个矩阵

copyright 无奈人生


从o开始,沿着.走,一直走到7即可。
0x11 表示向上
0x1f 表示向下
0x1e 表示向左
0x20 表示向右
无奈人生安全网


当时一直在想0x11和输入的关系,最后才知道原来是键盘的扫描码,分别对应wasd
OK那么此题轻易的解决了!我是不是很水!
(下面几题都算是复现,我是一个没有感情的杀手!)

www.wnhack.com


 
LuckyStar
别看程序这么大只不是VS静态编译了而已。
其实也不难,一进来先搜索字符串,看到idaq.exe,x32dbg等常见调试器的字样,很明显有反调试,并且还看到一大段未识别的数据,感觉很像是自解码的部分,其实真正的加密部分就在这里。
内容来自无奈安全网
关于反调试,不必紧张,动态调试时手动修改下寄存器即可。通过交叉引用找到TlsCallback_0函数,判断之前下断,绕过即可(直接patch比较方便)。
之后便是程序的自解密部分,最后便可以看到真正的加密的过程。

内容来自无奈安全网

将00401780至00401939 undefine一下然后重新create function,IDA便可以识别,接下来的一段解密也是类似的,最后进行一个比较。有一点需要注意,在动调时候不知道什么情况,程序就蹦了,需要手动在401780函数处set ip然后跳转过去

加密部分其实就是变形的base64加上一个异或,类似的题目做的太多了,解密脚本如下:
table='''abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/'''

本文来自无奈人生安全网


def mydecodeb64(enc):
    enc=enc.replace("=","")
    x="".join(map(lambda x:bin(table.index(x))[2:].zfill(6),enc))
    # print x
    for ap in range(8-(len(x)%8)):
无奈人生安全网

        x+='0'
    # print x
    plain=[]
    for i in range((len(x))/8):
        plain.append(chr(eval('0b'+x[i*8:(i+1)*8])))

本文来自无奈人生安全网


    return "".join(plain).replace("x00","")
def myencodeb64(plain):
    en=[]
    encode=[]
    for d in list(plain):

本文来自无奈人生安全网


        en.append(bin(ord(d))[2:].zfill(8))
    plain="".join(en)
    for ap in range(6-(len(plain)%6)):
        plain+='0' 无奈人生安全网
    # print enc
    for i in range((len(plain))/6):
        encode.append(table[eval('0b'+plain[i*6:(i+1)*6])])
    return "".join(encode)
内容来自无奈安全网

in_base='D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3D3'
enc=[0x49, 0xE6, 0x57, 0xBD, 0x3A, 0x47, 0x11, 0x4C, 0x95, 0xBC, 0xEE, 0x32, 0x72, 0xA0, 0xF0, 0xDE, 0xAC, 0xF2, 0x83, 0x56, 0x83, 0x49, 0x6E, 0xA9, 0xA6, 0xC5, 0x67, 0x3C, 0xCA, 0xC8, 0xCC, 0x05]
rand=[0x4c,0xb2,0x7d,0xbe,0x04,0x3a,0x06,0x27,0x94,0xc1,0xdc,0x55,0x77,0xe5,0x8d,0x81,0x85,0xa6,0xf2,0x2d,0x83,0x1e,0x58,0xdc,0x96,0x81,0x1b,0x55,0xc8,0x8a,0xb5,0x0b]
f=[]

www.wnhack.com


for i in range(32):
    f.append(chr(rand[i]^enc[i]^ord(in_base[i])))
a = "".join(f)
print a
flag=mydecodeb64(a) copyright 无奈人生
print flag
 
PolishDuck
比赛的时候就简单看了一眼,只知道是个arduino程序。。 (责任编辑:wnhack)
【声明】:无奈人生安全网(http://www.wnhack.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱472701013@qq.com,我们会在最短的时间内进行处理。