版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiangshangbashaonian/article/details/83546086
这道题比赛时就看到了名字 没下载到
一直在找题目附件 发现52破解上yechen123师傅发了帖子
就下载下来分析了一波 现在来记录一下
IDA载入静态分析可知
关键代码就在main()
程序与我们拿到flag有关的步骤就是
0x01:判断my_str_len(ps:就是我们输入的字符串的长度)是否小于32 正确的输入最后算出来正好等于32 所以将会继续向下执行
0x02:sub_91100()将我们得输入my_str中的字母进行替换
0x03:通过sub_91360()与sub_91440()他俩配合的变种base64(ps:分析可知,只是替换了编码表而已) 进行编码
0x04:得到的串需要等于"TRLT5amLBoLT5Z6Fa5LqN6mkTomqR66Da4LqX5mgBwkkP5wmTZ6D===="
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax
int v4; // [esp+30h] [ebp-28h]
int v5; // [esp+34h] [ebp-24h]
printf(std::cout, "please input your flag:");
scanf(std::cin, my_str);
if ( strlen(my_str) < 32 ) // 我们的输入 my_str长度必须小于32
goto LABEL_14;
sub_91100(my_str); // 这里将my_str中的小写字母进行替换
v5 = strcmp(my_str, "guvf_vf_n_snxr_synt_____________");
if ( v5 )
v5 = -(v5 < 0) | 1;
if ( v5 )
{
LABEL_14:
sub_91360(); // 替换了base32编码的密码表
sub_91440(strlen(my_str), my_str, a0); // 进行变种base32编码 用32个字符表示256个ASC字符,也就是说5个ASC字符一组可以生成8个Base字符
v4 = strcmp(a0, "TRLT5amLBoLT5Z6Fa5LqN6mkTomqR66Da4LqX5mgBwkkP5wmTZ6D====");// 用变种base32加密后 与这个串进行比较
if ( v4 )
v4 = -(v4 < 0) | 1;
if ( v4 )
printf(std::cout, "soooooooooorry\n");
else // 如果v4等于0 则输出"Congratulations!!!"
printf(std::cout, "Congratulations!!!\n");
system("pause");
result = 0;
}
else
{
printf(std::cout, "try harder!\n");
result = 0;
}
return result;
}
IDA动态调试时
F7进入sub_91360()可以看到 地址0009507C开始存放着这么一个字符串byte_9507C
这个就是要使用的密码表
NoPqRsTuVwXyZaBcDeFgHiJkLm765432
有了编码表之后 可以很容易求得编码之前的串
import string
import base64
my_base64table = "NoPqRsTuVwXyZaBcDeFgHiJkLm765432"
std_base64table ="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
s = "TRLT5amLBoLT5Z6Fa5LqN6mkTomqR66Da4LqX5mgBwkkP5wmTZ6D===="
s = s.translate(string.maketrans(my_base64table,std_base64table))
print base64.b32decode(s)
#10n78ppn3ro00o70r2opop5s3roqq937
但是这里就可以发现 长度正好是32位
那就肯定经过了0x02这个步骤
signed int __thiscall sub_91100(const char *this)
{
const char *v1; // edi
unsigned int i; // esi
char v3; // cl
v1 = this;
i = 0;
if ( strlen(this) ) //this 就是我们的my_str
{
do
{
v3 = v1[i];
if ( (v3 - 0x61) <= 0x19u ) //如果有小写字母就进行这种操作
v1[i] = (v3 - 0x54) % 26 + 0x61;
if ( (v3 - 0x41) <= 0x19u ) //如果有大写字母就进行这种操作
v1[i] = (v3 - 0x34) % 26 + 0x41;
++i;
}
while ( i < strlen(v1) );
}
return 1;
}
因为base32解码之后只有小写字母
那我们只要把它们逆一下即可
这里是yechen123师傅的脚本
先生成密码表
然后对应下标即可(ps:又get到一个姿势)
key = "10n78ppn3ro00o70r2opop5s3roqq937"
asciis = []
g = []
for i in range(97,123):
asciis.append(chr(((i-84)%26)+97))#生成移位之后的表
for i in range(0,32):
if (97<=ord(key[i])<=122):#小写才用改 数字就算了
temp = ord(key[i])-97
g.append(asciis[temp])
continue
g.append(key[i])
flag = ""
for i in g:
flag += i
print (flag)
#10a78cca3eb00b70e2bcbc5f3ebdd937
推荐大家看师傅写的 非常详细
https://www.52pojie.cn/forum.php?mod=viewthread&tid=813470&extra=page%3D1&page=1