一.[Zer0pts2020]easy strcmp
[Zer0pts2020]easy strcmp 分析与加法-CSDN博客
BUUCTF之[Zer0pts2020]easy strcmp(详细教程)-CSDN博客
无壳,进入ida看到了,大致看了看
“CENSORED”通常表示某些内容被审查、屏蔽或删除了。在不同的语境中,其具体含义可能有所不同,但总体上是指对信息、媒体或通信等进行限制或控制,以隐藏某些被认为不合适、敏感或违反规定的内容。
我们一直找,看到了关键处,这里只分析代码的写法
在密码学和数据处理中,当我们讨论块相加(如64位块)和逐字节相加时,是否需要进位取决于具体的操作和上下文。以下是两种情况的详细解释:
1. 块相加(如64位块)
在处理64位块时,通常不需要显式考虑进位,因为64位加法是按照模 264 进行的。这意味着当加法结果超过64位能表示的最大值时,结果会自动回绕(wrap around)。这种操作称为模 264 加法,常见于加密算法中,如AES。
例如,如果你有两个64位的数 A 和 B,它们的和 S=A+B 如果超过了 264−1(64位能表示的最大值),则结果 S 会回绕到 Smod264。
2. 逐字节相加
当逐字节进行加法时,通常需要考虑进位。这是因为每个字节是8位的,最大能表示的值是255(28−1)。如果两个字节相加的结果超过了255,就需要将超出的部分进位到下一个更高的字节。
例如,考虑两个字节 a 和 b,它们的和 s=a+b。如果 s>255,则需要将 s 减去256,并将1进位到下一个更高的字节。
所以在得到了两个数组的时候,我们可以块相加写代码,分析逻辑
#include <stdio.h>
#include<stdint.h>
#include<string.h>
int main() {
char fake[] = { "zer0pts{********CENSORED********}" };
unsigned char flag[50];
uint64_t key[] = { 0LL, 4686632258374338882LL, 796841318371695088LL, 5695428477452625963LL, 0LL };
for (int i = 0; i < strlen(fake) / 8; i++)
{
*(uint64_t*)&(fake[i * 8]) += key[i];
}
printf("%s", fake);
return 0;
}
块相加操作逻辑
-
循环处理:
-
for (int i = 0; i < strlen(fake) / 8; i++)
:循环遍历fake
数组,每次处理8个字节(64位)。循环次数由fake
的长度决定,除以8是因为每次处理64位(8字节)。
-
-
类型转换和加法操作:
-
*(uint64_t*)&(fake[i * 8]) += key[i];
:这行代码执行以下操作:-
&(fake[i * 8])
:获取fake
数组中第i * 8
个字节的地址。 -
(uint64_t*)
:将该地址转换为uint64_t
类型的指针。 -
*(uint64_t*)&(fake[i * 8])
:解引用该指针,获取指向的64位整数。 -
+= key[i]
:将key
数组中对应索引的值加到这个64位整数上。
-
-
也可以单个相加,但是要加上进位
#include <stdio.h>
#include <string.h>
int main()
{
char flag[] = "********CENSORED********"; // È·±£Õâ¸ö×Ö·û´®ÖÁÉÙÓÐ24¸ö×Ö·û
int enc[] = { 0x42, 0x09, 0x4A, 0x49, 0x35, 0x43, 0x0A, 0x41, 0xF0, 0x19, 0xE6, 0x0B, 0xF5, 0xF2, 0x0E, 0x0B, 0x2B, 0x28, 0x35, 0x4A, 0x06, 0x3A, 0x0A, 0x4F };
int t = 0;
for (int j = 0; j < 24; ++j)
{
int sum = (flag[j] + enc[j] + t) % 256; // È·±£½á¹ûÔÚ0-255·¶Î§ÄÚ
flag[j] = sum;
t = (flag[j] + enc[j]+t) / 256; // ¼ÆËã½øλ
printf("%c", flag[j]);
}
return 0;
}
单个相加循环逻辑
-
循环条件:
for (int j = 0; j < 24; ++j)
。循环24次,每次处理flag
和enc
数组中的一个字符。 -
字符相加:
-
int sum = (flag[j] + enc[j] + t) % 256;
:将flag
数组中的第j
个字符、enc
数组中的第j
个值和进位值t
相加,然后取模256。这确保了结果在0到255的范围内,即有效的ASCII字符范围内。 -
flag[j] = sum;
:将计算结果存储回flag
数组的第j
个位置。
-
-
进位计算:
-
t = (flag[j] + enc[j]+t) / 256;
:计算进位值。如果flag[j] + enc[j]+t
的和大于255,则进位值为((flag[j] + enc[j]+t) / 256)
的整数部分。
-
二.[BJDCTF2020]BJD hamburger competition
是unity逆向,需要用到ILSpy
关键处
\TPH\TPH_Data\Managed\Assembly-CSharp.dll
我们用ILSpy打开
之后根据游戏查找关键函数处
合理猜测是正确的配方才可以得到flag
这个函数名"生成水果按钮"和右面的Md5和Sha1是和hash函数有关的,我们分析一下
是有一个密文,通过Sha-1和已知哈希值相等,让后把密文进行Md5操作转成字符串当做result即flag
我们找网站解决
但是我这个sha-1的哈希值也用md5的解密出来了,挺巧的,不管了,我们再得到Md5哈希值
得到了字符串,我们尝试提交flag但是不对,我们仔细查看代码分析
其中的Md5代码中
ToString("X2")
方法将字节转换为两位十六进制字符串,并且因为是大写的"X"所以结果是大写的Substring(0, 20)
方法截取前20个字符作为结果。MD5 哈希值通常表示为32个字符的十六进制字符串,但这里只截取了前20个字符
因为我们知道他正常是32字符所以不会出现0XA转成0X0A这样的,所以我们直接取前20位即可
flag{B8C37E33DEFDE51CF91E}