我最近得到了这个代码,我很难理解。我对整体编程很新,我还在学习。任何有关这方面的信息将不胜感激。这是出现的代码:
void enc(char* plaintxt, unsigned char key)
{
while(*plaintxt)
{
*plaintxt^ = (key=(key*13)+37);
*(plaintxt++) +=3;
}
}
输出:
0F A8 9F FE 7A D6 E2 08 AE 2B 5F 53 25 9A
答案 0 :(得分:6)
了解您拥有的具体问题会有所帮助。
简而言之,此代码使用字符串并使用键值对其进行加密/编码。这条线
*plaintxt^ = (key=(key*13)+37);
是一种非常密集的写作方式
*plaintxt = *plaintxt ^ (key * 13 + 37);
key = key * 13 + 37;
但需要注意的是,未指定更新key
和*plaintxt
的确切顺序(IOW,原始代码key
可能会在{{1}之前或之后更新更新)。
*plaintxt
运算符是按位XOR运算符; ^
中的每个位与*plaintext
中的每个位进行异或运算。
该行
key
是一种密集的写作方式
*(plaintxt++) +=3;
同样需要注意,未指定更新 *plaintxt = *plaintxt + 3;
plaintxt = plaintxt + 1;
和*plaintxt
的确切顺序。这一行将plaintxt
添加到3
,然后将指针前进到指向字符串中的下一个字符。
在C中,字符串是由*plaintext
终止的字符值序列。 0
是指向字符串第一个字符的指针。 plaintext
循环通过测试while
的值来检查我们是否未到达字符串的末尾; *plaintxt
与while ( *plaintext )
相同。
所以,我们假设while ( *plaintext != 0 )
指向字符串plaintext
1 :
"test"
并且 +---+ +----+
plaintext: | | ----> "test" | 74 | Assumes ASCII, all values in hex
+---+ +----+
| 65 |
+----+ +----+
key: | 1 | | 75 |
+----+ +----+
| 74 |
+----+
| 0 |
+----+
最初是1.
在循环开始时,key
指向plaintext
中的第一个t
(ASCII "test"
)。我们用0x74
的结果对此进行异或,结果为十进制50,或十六进制为0x32:
key * 13 + 37
我们将此值写回 0x74 ^ 0x32 == 0x46
,然后将3添加到它,给我们0x49。我们将0x32保存到*plaintext
。然后我们前进key
指向字符串中的下一个字符,给我们:
plaintext
现在我们对 +---+ +----+
plaintext: | | --+ "Iest" | 49 |
+---+ | +----+
+-------> | 65 |
+----+ +----+
key: | 32 | | 75 |
+----+ +----+
| 74 |
+----+
| 0 |
+----+
:
e
key = 50 * 13 + 37 == 687 % 255 == 177 == 0xb1
只能存储0到2 CHAR_BIT -1的值,这在大多数现代系统中都是255; 687太大而无法存储在unsigned char
中,因此它“回绕”回到177或0xb1 2 。
key
完成所有操作后,我们
0x65 ^ 0xb1 == 0xd4
0xd4 + 3 == 0xd7
泡沫,冲洗,重复。这将持续到 +---+ +----+
plaintext: | | --+ "I?st" | 49 |
+---+ | +----+
| | d7 |
+----+ | +----+
key: | b1 | +--------> | 75 |
+----+ +----+
| 74 |
+----+
| 0 |
+----+
指向包含0的存储器单元。
<小时/>
答案 1 :(得分:0)
我知道它有点晚了,无论你从那张卡上获得的任何安全会议都已经结束了(Raytheon Game Of Pwns)......但是让我为你省一些挫折感。 您不会找到比上面显示的代码更好的描述,但您根本不需要重新创建此代码来解决密码。 你甚至不需要知道C. 无论您选择哪种语言,都可以生成轻松破解此代码的密钥。 鉴于初始键只有256个可能的值(0-255),你可以强制它,但你可以通过有根据的猜测来解决这个问题,以获得键的第一个值。
Game of Pwns卡包含密钥,您可能会在解决解析为Key = 2EZ01的二进制编码ASCII消息时注意到这些密钥。你可以猜到第一个字符可能是一个大写的K(0x4B)。
关于XOR操作的有趣事实是它可以用来反转自身。
让我们假设第一个字符确实是K,我们已经知道第一个输出元素是0x0F(实际上是0x0C)。这告诉我们
Flag ^ key =(output-3)
诀窍是
(输出-3)^标志=键!
基于该假设,我们可以获得apply
的第一个结果,即0x0C ^ 0x4B = 0x47。
两个重要的注释,代码中的13和37确实是十进制值,而不是十六进制,并且在索引到数组中的下一个char之前,标志会增加3。
使用第一个键,您可以通过创建循环以您使用的任何语言生成其余的键,以便使用下一个13键
((key*13)+37)
%256模仿C中unsigned char的环绕行为。
当你有14个密钥时,只需将列表中的每个密钥与其对应的原始输出(-3)进行异或,以获得编码消息,这很清楚...它开始于Key =
如果你还从Raytheon得到了另一张具有相似外观代码的卡,那么该卡上的所有密码都以Flag =开头,所以你可以简单地应用你在这里学到的关于XOR的知识来轻松破解那个。