当前位置: 首页 > news >正文

【C语言】SCU安全项目1-FindKeys

目录

前言

 命令行参数

16进制转字符串

extract_message1

process_keys12

extract_message2

main

process_keys34


前言

因为这个学期基本都在搞CTF的web方向,C语言不免荒废。所幸还会一点指针相关的知识,故第一个安全项目做的挺顺利的,也把思维切换切换,接触点新东西。

贴出源码

#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') {process_keys34(&key3, &key4);msg2 = extract_message2(start, stride);printf("%s\n", msg2);}else {printf("%s\n", msg1);}return 0;
}

 命令行参数

在C语言程序中,主函数main()可以有两个参数,用于接收命令行参数。带有参数的函数main()习惯上书写为:

(颇有pearcmd的感觉哈哈哈)

int main(int argc,char *argv[])
{
...
}

argc和argv是函数main()的形参(argc和argv分别是argument count和argument vector的缩写)。用命令行的方式运行程序时,函数main()被调用,与命令行有关的信息作为实参传递给两个形参。

第一个参数argc接收命令行参数(包括命令)的个数;第二个参数argv接受以字符串常量形式存放的命令行参数(包括命令本身也作为一个参数)。字符指针数组argv[]表示各个命令行参数(包括命令),其中argv[0]指向命令,argv[1]指向第1个命令行参数,argv[2]指向第2个命令行参数......argv[argc-1]指向最后一个命令行参数。

审一下源码的这部分

其实就是让我们最少传2个参数(第0个参数为程序名),否则就会exit

16进制转字符串

这里显然只有data数组有用,只需要转换data数组即可

如果直接用16进制转字符串的网站,会发现转换结果并不正确

于是跟着代码逻辑自己写一版16进制逐字节解码程序

#include <stdio.h>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};void decode1(int* data){for (int i = 0; ; i++) {char c = *(((char*)data) + i);putchar(c);if (c == '\0') break;}}int main(){decode1(data);return 0;}

运行结果

两者的差异是什么原因呢?

因为Intel处理器是小端,所以数组里每个int的低位存储在内存的低地址处,即先被转化

例如

int 0x5A33723479(Z3r4y)

在内存中:

79 34 72 33 5A(y4r3Z)

所以我们把data的数据先预处理一下再放入16进制转字符串在线网站即可(虽然没有必要)

接下来看一些关键代码

extract_message1

传入一个start和stride,将data数组转换成字符串

这个函数的功能是,从 data 数组的首地址偏移 start + 1 地址开始,每转换 stride -1 个字符后,就跳过一个字符不转换,重复执行这样的操作直到转换到最后一个字符

已知明文最开始为:From: ,可利用其来倒推出start和stride

这里显然是从第10个字符开始(从0开始计数),每次转换两个字符,故start=9,stride=3

 再发现start和stride是由dummy得来的

将dummy最低的字节赋值给start(要等于9),将dummy第二低的字节赋值给stride(要等于3)

即dummy为0x????0309

记录一下低2位转10进制是777

process_keys12

 访问以 key1 变量的地址为初始地址,偏移 *key1 的值×sizeof(int) 即4字节的地址,赋成*key2的值。

这里就可以操纵key1地址将其偏移到dummy的地址,再操纵*key2来控制dummy的值

调试看key1和dummy的地址

(左为key1,右为dummy)

计算地址差值

24➗4=9 ,所以只要令*key1=9即可偏移到dummy的地址

再令*key2=777,使得dummy为0x00000309,成功使得start为9,stride为3

回显正确

提示我们要选择key3key4来调用extract2并且避免调用extract1

extract_message2

其实和extract_message1大同小异

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

可见start=9,stride=3 (刚好就是msg1对应的数据,故key1,key2传的值不用改)

main

 通过代码审计,发现只要让extract_message1返回一个空字符串就可以打印出msg2

我们接着看,怎么操纵msg1='\0'

extract1 最初会访问第10个字符(从0开始计数),而第10个字符恰好会在 extract2 (从第9个字符开始,每隔2个取一个)中被忽略不会影响答案。
所以我们可以直接尝试改变 data 数组,使其表示的第10个字符为 \0 ,即将data[2]=0x72464663转变成 0x72004663 。
可以借助 process_keys34 来操纵data[2]

process_keys34

 这个函数就是把指向key3指针的地址偏移*key3的值×sizeof(int)即4个字节的地址,将其解引用,自增一个*key4的值

那么我们就可以将指向key3指针的地址偏移到data[2]上,然后利用*key4改变data[2]的值,这里72004663-72464663=-4587520,key4传入-4587520即可

调试观察&key3和data[2]的地址

 2597600/4=649400

所以key3传入649400

综上,key1,key2,key3,key4分别传入9 777 649400 -4587520

运行回显正确

实验1还是比较友好的,做的时候没有太坐牢,对于一个C语言小白这种难度刚刚好QWQ

相关文章:

【C语言】SCU安全项目1-FindKeys

目录 前言 命令行参数 16进制转字符串 extract_message1 process_keys12 extract_message2 main process_keys34 前言 因为这个学期基本都在搞CTF的web方向&#xff0c;C语言不免荒废。所幸还会一点指针相关的知识&#xff0c;故第一个安全项目做的挺顺利的&#xff0c…...

IDA pro软件 如何修改.exe小程序打开对话框显示的文字?

环境: Win10 专业版 IDA pro Version 7.5.201028 .exe小程序 问题描述: IDA pro软件 如何修改.exe小程序打开对话框显示的文字? 解决方案: 一、在IDA Python脚本中编写代码来修改.rdata段中的静态字符串可以使用以下示例代码作为起点(未成功) import idc# 定义要修…...

Ubuntu22.04切换用户

一、只有一个用户时没有切换用户菜单项 1、用户信息 cat /etc/passwd 2、系统菜单 二、添加用户 添加新用户ym&#xff0c;全名yang mi 三、有两个及以上的用户时出现切换用户菜单项 1、用户信息 cat /etc/passwd 2、系统菜单 四、切换用户 1、点击上图中Switch User …...

torch.gather(...)

1. Abstract 对于 pytorch 中的函数 torch.gather(input, # (Tensor) the source tensordim, # (int) the axis along which to indexindex, # (LongTensor) the indices of elements to gather*,sparse_gradFalse,outNone ) → Tensor有点绕&#xff0c;很多博客画各…...

vscode如何开发微信小程序?JS与TS的主要区别?

要在 VS Code 中编写微信小程序代码并同步到 Git&#xff0c;需要安装以下插件&#xff1a; 1. 微信小程序插件&#xff08;WeChat Mini Program&#xff09;&#xff1a;此插件提供了微信小程序的语法高亮、代码提示、调试、上传等功能。 2. Git 插件&#xff08;GitLens、…...

产品入门第五讲:Axure交互和情境

目录 一.Axure交互和情境的介绍 1.交互介绍 概念 常见的Axure交互设计技巧 2.情境介绍 概念 常见的Axure情境设计技巧&#xff1a; 二.实例展示 1.ERP登录页到主页的跳转 2.ERP的菜单跳转到各个页面 &#x1f4da;&#x1f4da; &#x1f3c5;我是默&#xff0c;一个…...

Python 自动化之收发邮件(一)

imapclient / smtplib 收发邮件 文章目录 imapclient / smtplib 收发邮件前言一、基本内容二、发送邮件1.整体代码 三、获取邮件1.整体代码 总结 前言 简单给大家写个如何用Python进行发邮件和查看邮件教程&#xff0c;希望对各位有所帮助。 一、基本内容 本文主要分为两部分…...

Flutter开发笔记 —— sqflite插件数据库应用

前言 今天在观阅掘金大佬文章的时候&#xff0c;了解到了该 sqflite 插件&#xff0c;结合官网教程和自己实践&#xff0c;由此总结出该文&#xff0c;希望对大家的学习有帮助&#xff01; 插件详情 Flutter的 SQLite 插件。支持 iOS、Android 和 MacOS。 支持事务和batch模式…...

OxLint 发布了,Eslint 何去何从?

由于最近的rust在前端领域的崛起&#xff0c;基于rust的前端生态链遭到rust底层重构&#xff0c;最近又爆出OxLint&#xff0c;是一款基于Rust的linter工具Oxlint在国外前端圈引起热烈讨论&#xff0c;很多大佬给出了高度评价&#xff1b;你或许不知道OxLint&#xff0c;相比ES…...

第一次使用ThreadPoolExecutor处理业务

通过对业务逻辑的分析&#xff0c;进行编码&#xff0c;先把第一条sql查出来的数据进行分组&#xff0c;然后分别使用不同的线程去查询数据返回&#xff0c;并添加到原来的数据中。 总感觉哪里写的不对&#xff0c;但是同事们都没用过这个&#xff0c;请大家指教一下&#xff…...

Sharding-Jdbc(6):Sharding-Jdbc日志分析

1 修改配置 将配置文件中的开启分片日志从false改为true Sharding-JDBC中的路由结果是通过分片字段和分片方法来确定的,如果查询条件中有 id 字段的情况还好&#xff0c;查询将会落到某个具体的分片&#xff1b;如果查询没有分片的字段&#xff0c;会向所有的db或者是表都会查…...

centos安装了curl却报 -bash: curl: command not found

前因 我服务器上想用curl下载docker-compress&#xff0c;发现没有curl命令&#xff0c;就去下载安装&#xff0c;安装完成之后&#xff0c;报-bash: curl: command not found 解决方法 [rootcentos ~]# rpm -e --nodeps curl warning: file /usr/bin/curl: remove failed: …...

Re58:读论文 REALM: Retrieval-Augmented Language Model Pre-Training

诸神缄默不语-个人CSDN博文目录 诸神缄默不语的论文阅读笔记和分类 论文名称&#xff1a;REALM: Retrieval-Augmented Language Model Pre-Training 模型名称&#xff1a;Retrieval-Augmented Language Model pre-training (REALM) 本文是2020年ICML论文&#xff0c;作者来自…...

java的json解析

import com.alibaba.fastjson.*; public class JsonParser { public static void main(String[] args) { String jsonStr "{\"name\":\"John\", \"age\":30}"; // JSON字符串示例 // 将JSON字符串转换为JSONObject对象 JSONObje…...

Spring事务失效的几种情况

Spring事务失效的几种情况 1、未被Spring管理的类中的方法 这种情况是指&#xff1a;没有在类上添加Service、Repository、Component等注解将类交由Spring管理&#xff0c;然后该类中还有加上了Transactional注解 例如&#xff1a; Service //如果没有添加Service这个注解…...

filter的用法与使用场景:筛选数据

//this.allCollectorList:后台给定的所有可供选择数据 //this.collectorData:目前已经存在选中列表中的数据//目前已经存在选中列表中的数据id getSelIdList() {let eIdList = []this.collectorData.forEach(row => {eIdList.push(row.id)})return eIdList },//在中的数据…...

ClickHouse(18)ClickHouse集成ODBC表引擎详细解析

文章目录 创建表用法示例资料分享参考文章 ODBC集成表引擎使得ClickHouse可以通过ODBC方式连接到外部数据库. 为了安全地实现 ODBC 连接&#xff0c;ClickHouse 使用了一个独立程序 clickhouse-odbc-bridge. 如果ODBC驱动程序是直接从 clickhouse-server中加载的&#xff0c;那…...

网络攻击(一)--安全渗透简介

1. 安全渗透概述 目标 了解渗透测试的基本概念了解渗透测试从业人员的注意事项 1.1. 写在前面的话 在了解渗透测试之前&#xff0c;我们先看看&#xff0c;信息安全相关的法律是怎么样的 中华人民共和国网络安全法 《中华人民共和国网络安全法》由全国人民代表大会常务委员会…...

视频号小店资金需要多少?

我是电商珠珠 视频号团队于22年7月发展了自己的电商平台-视频号小店&#xff0c;相比于抖音电商来讲&#xff0c;可以有效的将公域流量转化为私域&#xff0c;对于商家来说&#xff0c;是一件利好的事情。 可以有效的提高客户的黏性&#xff0c;增加店铺回头客。 有很多想要…...

机器学习项目精选 第一期:超完整数据科学资料合集

大噶吼&#xff0c;不说废话&#xff0c;分享一波我最近看过并觉得非常硬核的资源&#xff0c;包括Python、机器学习、深度学习、大模型等等。 1、超完整数据科学资料合集 地址&#xff1a;https://github.com/krishnaik06/The-Grand-Complete-Data-Science-Materials Pytho…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...