没想到SCU拿美国卡耐基梅隆大学的平时作业当咱的期末考项目,考完了以后上传一个writeup供大家参考。当时两个安全项目和游戏项目可是把戴安娜折腾惨了,第一次感受到了大学期末周的问候。好了话不多说,上题解!
题面:
项目名称
Lab1-Decode
项目环境
表1** **项目开发环境
硬件环境
CPU
Intel Core i5-1135G7,2.4 GHZ
内存
8G
操作系统
Windows
10,Professional版本
开发IDE
VisualStudio
2022版本
项目过程和结果的描述
2023年12月31日&1月1日
下面展示思路:
- 对程序进行解读,并详细做了注释
****2.****16进制转字符串
图1:Intel是小端序列,因此自己在DEV里面写了一个decode代码
图2:得到以下信息:
3.对得到的密文进行解密:
图4:研究extract_message1(int start, int stride)函数可知,它传入一个start和stride,将data数组转换成字符串
extract_message1这个函数的功能是,从 data 数组的首地址偏移 start + 1 地址开始,每转换 stride -1 个字符后,就跳过一个字符不转换,重复执行这样的操作直到转换到最后一个字符.
已知明文最开始为:From: 可利用其来倒推出start=09和stride=03。解读代码可知Start09是dummy的int型4字节里面最低的8位,stride03是次低的8位。
- 自学数制知识。由3可知,dummy应该等于=0x....0309=777
由process_keys12函数可知,令地址key1偏移key1为dummy来定位dummy,key2来为dummy赋值。
注意:因此打断点打在主函数,extract1函数里面的int*key1是局部变量,不存在于主函数里面。So,取地址是取&key1而非key1。
5.调试看key1和dummy的地址:并计算偏移量
derta=916-316=-96,
易知:key1=-96/4=-24.即令key1=24可使dummy地址=key1。再令*key2=777,使得dummy为0x00000309,成功使start为9,stride为3。
总结:key1=-24;key2=777.
6.输入到程序里面:
显示正确,并得到关于key3,4提示:要选择key3key4来调用extract2并且避免调用extract1。
观察extract2函数:从 data 数组的首地址偏移 start 地址开始,每读入一个字符,就跳过stride-1个字符,直到转换到最后一个字符
由7可知start=9,stride=3,不用修改start和stride的值。
下面研究main函数:
图8 main函数
易知,只有当*msg1==‘\0’时,才会输出msg2
所以我们现在想怎么让*msg1==‘\0’。
- 让*msg1==‘\0’:
由题,
extract1函数 cccccccccabcdefghijk从第10个字符开始读
Bc ef hi
Extract2函数 cccccccccabcdefghijk从第9个字符开始读
A d g j
若让第10个字符==‘\0’就可以在不影响extract2函数输出结果的情况下得到msg2.
由ASCII码和十六进制编译准则,如图
目标即修改data【2】为0x72004663;
- 如何修改data【2】为0x72004663?
接下来我们又看到了key3key4;
void**** process_keys34(int* key3, int* key4) {****
(((int*)&key3) + *key3) += key4;** //key4为△derta.****
}
于是仿造dummy被key1移动地址来定位,*key2来赋值的做法。
我们用&key3偏移key3的量对data【2】定位。将key4用来对data【2】改值,这里72004663-72464663=-4587520,key4传入-4587520即可。
调试监视查看&key3和&data【2】:
名称
值
类型
◢
&dummy
0x000000852751f7a4 {1}
int *
名称
值
类型
◢
&key1
0x000000852751f804 {-858993460}
int *
名称
值
类型
◢
&key3(断点打extract34里面)
(注意这个&key3☞外部函数里的&key3)
0x000000000014fbf0 {0x000000000014fcb4 {2147483647}}
int * *
名称
值
类型
◢
&data[2]
Project1.exe!0x000000014001e088 {1919174243}
int *
△=*key3
上网计算可知:*key3=-5367456920/4=1341864230
综上,
*key1=-24,
*key2=777.
*key3=5367456920/4=1341864230
*key4=-4587520
在属性-->调试-->命令参数里面输入:
-24 777 1341864230 -4587520
显示正确,下班! ******** (开心)
源码:
#include <stdio.h>
#include <stdlib.h>
int prologue [] = {
0x5920453A, 0x54756F0A, 0x6F6F470A, 0x21643A6F,
0x6E617920, 0x680A6474, 0x6F697661, 0x20646E69,
0x63636363, 0x63636363, 0x72464663, 0x6F6D6F72,
0x63636363, 0x63636363, 0x72464663, 0x6F6D6F72,
0x2C336573, 0x7420346E, 0x20216F74, 0x726F5966,
0x7565636F, 0x20206120, 0x6C616763, 0x74206C6F,
0x20206F74, 0x74786565, 0x65617276, 0x32727463,
0x594E2020, 0x206F776F, 0x79727574, 0x4563200A
};
int data [] = {
0x63636363, 0x63636363, 0x72464663, 0x6F6D6F72,
0x466D203A, 0x65693A72, 0x43646E20, 0x6F54540A,
0x5920453A, 0x54756F0A, 0x6F6F470A, 0x21643A6F,
0x594E2020, 0x206F776F, 0x79727574, 0x4563200A,
0x6F786F68, 0x6E696373, 0x6C206765, 0x796C656B,
0x2C336573, 0x7420346E, 0x20216F74, 0x726F5966,
0x7565636F, 0x20206120, 0x6C616763, 0x74206C6F,
0x20206F74, 0x74786565, 0x65617276, 0x32727463,
0x6E617920, 0x680A6474, 0x6F697661, 0x20646E69,
0x21687467, 0x63002065, 0x6C6C7861, 0x78742078,
0x6578206F, 0x72747878, 0x78636178, 0x00783174
};
int epilogue [] = {
0x594E2020, 0x206F776F, 0x79727574, 0x4563200A,
0x6E617920, 0x680A6474, 0x6F697661, 0x20646E69,
0x7565636F, 0x20206120, 0x6C616763, 0x74206C6F,
0x2C336573, 0x7420346E, 0x20216F74, 0x726F5966,
0x20206F74, 0x74786565, 0x65617276, 0x32727463
};
char message[100];
void usage_and_exit(char * program_name) {
fprintf(stderr, "USAGE: %s key1 key2 key3 key4\n", program_name);
exit(1);
}
void process_keys12 (int * key1, int * key2) {
*((int *) (key1 + *key1)) = *key2;
}
void process_keys34 (int * key3, int * key4) {
*(((int *)&key3) + *key3) += *key4;
}
char * extract_message1(int start, int stride) {
int i, j, k;
int done = 0;
for (i = 0, j = start + 1; ! done; j++) {
for (k = 1; k < stride; k++, j++, i++) {
if (*(((char *) data) + j) == '\0') {
done = 1;
break;
}
message[i] = *(((char *) data) + j);
}
}
message[i] = '\0';
return message;
}
char * extract_message2(int start, int stride) {
int i, j;
for (i = 0, j = start;
*(((char *) data) + j) != '\0';
i++, j += stride)
{
message[i] = *(((char *) data) + j);
}
message[i] = '\0';
return message;
}
int main (int argc, char *argv[])
{
int dummy = 1;
int start, stride;
int key1, key2, key3, key4;
char * msg1, * msg2;
key3 = key4 = 0;
if (argc < 3) {
usage_and_exit(argv[0]);
}
key1 = strtol(argv[1], NULL, 0);
key2 = strtol(argv[2], NULL, 0);
if (argc > 3) key3 = strtol(argv[3], NULL, 0);
if (argc > 4) key4 = strtol(argv[4], NULL, 0);
process_keys12(&key1, &key2);
start = (int)(*(((char *) &dummy)));
stride = (int)(*(((char *) &dummy) + 1));
if (key3 != 0 && key4 != 0) {
process_keys34(&key3, &key4);
}
msg1 = extract_message1(start, stride);
if (*msg1 == '\0') {//*msg1 == '\0'
process_keys34(&key3, &key4);
msg2 = extract_message2(start, stride);
printf("%s\n", msg2);
}
else {
printf("%s\n", msg1);
}
return 0;
}
版权归原作者 d14na 所有, 如有侵权,请联系我们删除。