【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方向,C语言不免荒废。所幸还会一点指针相关的知识,故第一个安全项目做的挺顺利的,…...
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,全名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有点绕,很多博客画各…...
vscode如何开发微信小程序?JS与TS的主要区别?
要在 VS Code 中编写微信小程序代码并同步到 Git,需要安装以下插件: 1. 微信小程序插件(WeChat Mini Program):此插件提供了微信小程序的语法高亮、代码提示、调试、上传等功能。 2. Git 插件(GitLens、…...
产品入门第五讲:Axure交互和情境
目录 一.Axure交互和情境的介绍 1.交互介绍 概念 常见的Axure交互设计技巧 2.情境介绍 概念 常见的Axure情境设计技巧: 二.实例展示 1.ERP登录页到主页的跳转 2.ERP的菜单跳转到各个页面 📚📚 🏅我是默,一个…...
Python 自动化之收发邮件(一)
imapclient / smtplib 收发邮件 文章目录 imapclient / smtplib 收发邮件前言一、基本内容二、发送邮件1.整体代码 三、获取邮件1.整体代码 总结 前言 简单给大家写个如何用Python进行发邮件和查看邮件教程,希望对各位有所帮助。 一、基本内容 本文主要分为两部分…...
Flutter开发笔记 —— sqflite插件数据库应用
前言 今天在观阅掘金大佬文章的时候,了解到了该 sqflite 插件,结合官网教程和自己实践,由此总结出该文,希望对大家的学习有帮助! 插件详情 Flutter的 SQLite 插件。支持 iOS、Android 和 MacOS。 支持事务和batch模式…...
OxLint 发布了,Eslint 何去何从?
由于最近的rust在前端领域的崛起,基于rust的前端生态链遭到rust底层重构,最近又爆出OxLint,是一款基于Rust的linter工具Oxlint在国外前端圈引起热烈讨论,很多大佬给出了高度评价;你或许不知道OxLint,相比ES…...
第一次使用ThreadPoolExecutor处理业务
通过对业务逻辑的分析,进行编码,先把第一条sql查出来的数据进行分组,然后分别使用不同的线程去查询数据返回,并添加到原来的数据中。 总感觉哪里写的不对,但是同事们都没用过这个,请大家指教一下ÿ…...
Sharding-Jdbc(6):Sharding-Jdbc日志分析
1 修改配置 将配置文件中的开启分片日志从false改为true Sharding-JDBC中的路由结果是通过分片字段和分片方法来确定的,如果查询条件中有 id 字段的情况还好,查询将会落到某个具体的分片;如果查询没有分片的字段,会向所有的db或者是表都会查…...
centos安装了curl却报 -bash: curl: command not found
前因 我服务器上想用curl下载docker-compress,发现没有curl命令,就去下载安装,安装完成之后,报-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博文目录 诸神缄默不语的论文阅读笔记和分类 论文名称:REALM: Retrieval-Augmented Language Model Pre-Training 模型名称:Retrieval-Augmented Language Model pre-training (REALM) 本文是2020年ICML论文,作者来自…...
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管理的类中的方法 这种情况是指:没有在类上添加Service、Repository、Component等注解将类交由Spring管理,然后该类中还有加上了Transactional注解 例如: 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 连接,ClickHouse 使用了一个独立程序 clickhouse-odbc-bridge. 如果ODBC驱动程序是直接从 clickhouse-server中加载的,那…...
网络攻击(一)--安全渗透简介
1. 安全渗透概述 目标 了解渗透测试的基本概念了解渗透测试从业人员的注意事项 1.1. 写在前面的话 在了解渗透测试之前,我们先看看,信息安全相关的法律是怎么样的 中华人民共和国网络安全法 《中华人民共和国网络安全法》由全国人民代表大会常务委员会…...
视频号小店资金需要多少?
我是电商珠珠 视频号团队于22年7月发展了自己的电商平台-视频号小店,相比于抖音电商来讲,可以有效的将公域流量转化为私域,对于商家来说,是一件利好的事情。 可以有效的提高客户的黏性,增加店铺回头客。 有很多想要…...
机器学习项目精选 第一期:超完整数据科学资料合集
大噶吼,不说废话,分享一波我最近看过并觉得非常硬核的资源,包括Python、机器学习、深度学习、大模型等等。 1、超完整数据科学资料合集 地址:https://github.com/krishnaik06/The-Grand-Complete-Data-Science-Materials Pytho…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
