题目链接:https://buuoj.cn/challenges#SimpleRev
公众号文章链接:BUU reverse做题记录Day02
SimpleRev
IDA打开,查看关键函数:
分析前面逻辑,key1和key3跟进去可以找到对应的值
涉及到的知识点:
函数strcpy与strcat
了解函数用法的佬们可以跳过这了
strcpy函数原型:
char*strcpy(char*dest,const char*src)// 将src复制到dest字符数组中,返回的是第一个参数的值
// 用法示例
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "Hello reverse";
char str2[40];
char str3[40];
strcpy(str2, str1);
strcpy(str3, "copy successful");
printf("str1: %s\nstr2: %s\nstr3: %s\n", str1, str2, str3);
return 0;
}
// str1: Hello reverse
// str2: Hello reverse
// str3: copy successful
strcat函数原型:
char *strcat(char *dest, const char *src) // 该函数会将src字符串拼接在dest字符串的末尾,并返回dest
#include <stdio.h>
#include <string.h>
int main()
{
char str1[100] = "Hello reverse";
char str2[] = ",join successful";
strcat(str1, str2);
printf("str1: %s", str1);
return 0;
}
// str1: Hello reverse,join successful
数据存储的两种模式:大端模式和小端模式
首先要明白的是:读数据永远是从低地址开始的!!
-
Little-Endian(小端模式)就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端
-
Big-Endian(大端模式)就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端
比如32bit宽的数0x12345678,内存地址从0x4000开始
内存地址 大端 小端
0x4000 0x12 0x78
0x4001 0x34 0x56
0x4002 0x56 0x34
0x4003 0x78 0x12
注:在内存中存放的时候是以一个存储单元为单位来存放(8bit=1Byte为一个存储单元)
所以我们可以得到:
text = "killshadow"; key = "ADSFKNDCLS";
继续看下面的逻辑:
逻辑很容易,如果key[v3 % len(key)]对应的是大写字母,则将其转换为小写
key1 = 'ADSFK'
key3 = 'kills'
text = key3 + 'hadow'
key = key1 + 'NDCLS'
v3 = 0
key_len = len(key)
new_key = ""
for i in range(key_len):
index = v3 % key_len
if 65 <= ord(key[index]) <= 90: # 判断是否是大写字母(利用ASCII码范围)
new_key += chr(ord(key[index]) + 32)
else:
new_key += key[index]
v3 += 1
print(new_key)
# key值:adsfkndcls
继续向下分析:
关键逻辑:(v1 - 39 - key[v3 % key_len] + 97) % 26 + 97;
处理后得到的数据与text值进行比对看是否一致
直接写脚本进行爆破,python代码:
text = 'killswodah'
key = 'adsfkslcdn'
flag = ''
for i in range(len(key)):
for j in range(65,122):
if ord(text[i]) == (j - 39 - ord(key[i % len(key)]) + 97) % 26 + 97:
flag += chr(j)
break
print(flag)
# KLDQCOZFDU
c代码:
#include<stdio.h>
int main()
{
char key[] = "adsfkndcls";
char text[] = "killshadow";
int v3 = 10;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 123; j++)
{
if (j < 'A' || j > 'z' || j > 'Z' && j < 'a')
{
continue;
}
if ((j - 39 - key[v3 % sizeof(key)] + 97) % 26 + 97 == text[i])
{
printf("%c", j);
v3++;
break;
}
}
}
}
// KLDQCOZFDU