0


SCU【C】程序设计基础期末安全项目lab1-Decode-writeup(附题目&源码)

没想到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日

下面展示思路:

  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位。

  1. 自学数制知识。由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。

  1. 观察extract2函数:从 data 数组的首地址偏移 start 地址开始,每读入一个字符,就跳过stride-1个字符,直到转换到最后一个字符

  2. 由7可知start=9,stride=3,不用修改start和stride的值。

  3. 下面研究main函数:

    图8 main函数

易知,只有当*msg1==‘\0’时,才会输出msg2

所以我们现在想怎么让*msg1==‘\0’。

  1. 让*msg1==‘\0’:

由题,

extract1函数 cccccccccabcdefghijk从第10个字符开始读

Bc ef hi

Extract2函数 cccccccccabcdefghijk从第9个字符开始读

                  A  d  g  j

若让第10个字符==‘\0’就可以在不影响extract2函数输出结果的情况下得到msg2.

由ASCII码和十六进制编译准则,如图

目标即修改data【2】为0x72004663;

  1. 如何修改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;

}

标签: c语言 开发语言

本文转载自: https://blog.csdn.net/2301_79586491/article/details/136094955
版权归原作者 d14na 所有, 如有侵权,请联系我们删除。

“SCU【C】程序设计基础期末安全项目lab1-Decode-writeup(附题目&源码)”的评论:

还没有评论