编程语言
首页 > 编程语言> > CTF-REVERSE练习之算法分析2

CTF-REVERSE练习之算法分析2

作者:互联网

目录

预备知识

一、相关实验

本实验要求您已经认真学习和完成了《CTF REVERSE练习之算法分析1》。

二、异或运算

异或运算是一种数学运算,英文为Exclusive OR,常常缩写成XOR。异或运算针对二进制0和1而言,其数学符号为⊕,异或运算的法则如下:

0⊕0=0
1⊕0=1
0⊕1=1
1⊕1=0

除了二进制以外,异或运算可以扩展到任意数据类型。因为我们所接触的任何数据都可以使用二进制来表示,所以可以对二进制里面的所有位上的数据都进行两两的异或操作,如15的二进制表示为1111,而100的二进制表示为1100100,因此15⊕100的计算过程如下:
在这里插入图片描述
异或运算的性质:

1)A ⊕ B = B ⊕ A
2)A ⊕ A = 0
3)A ⊕ 0 = A
4)A ⊕ B ⊕ A = 0 ⊕ B = B

在编程语言中,通常使用^符号来表示异或运算,比如C和Python都使用这一符号。

实验目的

1)掌握异或运算的特性。
2)掌握IDA的基本操作,学会使用IDA进行静态分析。
3)学会编写简单的注册机(Keygen)程序。

实验环境

在这里插入图片描述
服务器:Windows XP,IP地址:随机分配
辅助工具:PEiD,IDA

实验步骤一

题目描述:
主机C:\Reverse\5目录下有一个CrackMe5.exe程序,运行这个程序的时候会提示输入用户名和注册码进行注册,当输入正确的用户名和注册码时,会弹出成功提示的消息框,请对CrackMe5.exe程序进行逆向分析和调试,尝试编写一个注册机程序。
考察意图:
这个CrackMe程序要求输入一个用户名以及注册码进行注册,注册码通过用户名经过一定的算法变换得到,主要考察逆向分析中简单的算法分析过程,以及如何通过IDA提取关键数据。
通过API交叉引用快速定位关键代码:
运行这个程序后要求输入一个用户名和注册码进行注册,当注册失败的时候,程序将弹出一个消息框提示不正确,如图所示:
在这里插入图片描述
那么我们可以通过IDA的交叉引用功能来定位这一块的代码。使用IDA载入CrackMe5.exe程序,待分析结束后,通过Imports TAB页面找到MessageBoxA,双击来到反汇编视图,在MessageBoxA按下X按键对其进行交叉引用查找,经过一个一个进行分析,我们发现sub_401490就是我们所要找的关键函数,我们通过F5得到这个函数的伪代码。通过对伪代码添加注释,以及对变量进行重命名操作,我们得到如下的代码片段:
在这里插入图片描述
由于IDA Hex-Rays Decompiler插件的原因,上述伪代码中计算字符串长度的地方仍然存在一些问题。
通过上面的伪代码的分析,我们发现只do while循环这里的代码的功能不是很清楚。程序要求用户名和注册码的长度必须相等,且长度必须大于0且小于等于33。

实验步骤二

分析关键算法:
通过实验步骤一的分析,我们发现一个do while循环对字符串进行了处理,代码如下:

v1 = 0;
do
{
    if ( ((unsigned __int8)*(&szUsername + v1) ^ (unsigned __int8)byte_423678[v1]) != *(&szPassword + v1) )
        break;
    ++v1;
}while ( v1 < _dwNameLen );
if ( v1 != _dwNameLen )
{
    // 错误
}
else
{
    // 正确
}

仔细分析上面循环过程中的代码,其中*(&szUsername + v1)实际上相当于szUsername[v1],相应的,*(&szPassword + v1)实际上相当于szPassword[v1],因此这里if语句的条件判断可以简化为:szUsername[v1] ^ byte_423678[v1] == szPassword[v1],根据异或运算的性质,上述条件可以转换为:szPassword [v1] ^ byte_423678[v1] == szUsername [v1],也就是不断的从注册码中取出一个字符,和byte_423678中对应下标的字符进行异或运算,看是否和用户名中对应的字符一致,需要全部匹配才表明注册是成功的。
在IDA中双击byte_423678,切换到IDA View视图,就可以看到内容了,如图所示:
在这里插入图片描述
我们需要把byte_423678的内容提取出来,为:
1,2,3,4,1,5,1,5,1,3,6,5,4,8,5,3,1,2,3,4,5,3,5,7,2,3,2,4,8,2,5,6,4。
这就是我们找到的XOR密钥数组。

实验步骤三

编写注册机:
现在我们已经将程序的注册算法分析清楚了,下面就可以编写一个注册机了。程序的注册算法为:将用户名的每一个字符与XOR密钥数组中的对应下标的字符进行异或运算,产生注册码字符串对应的字符。用户名的长度不能超过33个字符。
我们编写这样一段Python脚本即可:(代码位于C:\Reverse\5\Keygen.py)

def crack(username):
    key = [1, 2, 3, 4, 1, 5, 1, 5, 1, 3, 6, 5,
    4, 8, 5, 3, 1, 2, 3, 4, 5, 3, 5, 7,
    2, 3, 2, 4, 8, 2, 5, 6, 4]
    pwd = []
    for i in xrange(0, len(username)):
        pwd.append(chr(ord(username[i]) ^ key[i]))
    return "".join(pwd)
if __name__ == "__main__":
    while True:
        username = raw_input("input username:")
        serial = crack(username)
        print "serial: %s" % serial

我们输入用户名Wins0n,就可以得到注册码为Vkmw1k,输入程序可以成功注册,如图所示:
在这里插入图片描述

标签:运算,用户名,REVERSE,CTF,v1,算法,异或,注册码,IDA
来源: https://blog.csdn.net/ChuMeng1999/article/details/121605067