某文件被加密了(基于时间的随机种子破解)

2024-01-20 20:50

本文主要是介绍某文件被加密了(基于时间的随机种子破解),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 某文件被加密了

某文件被加密了

最后修改时间是2019/04/11 22:10:34。 猜测大概2019/04/11
22点11分之前,某一刻用户运行了genprik,生成了密钥加密文件。
加密算法已知,通过分析密文,只能得出密钥第1个字节是0x25第2个字节是0x61。 求完整的16个字节的密钥。

刚开始用IDA打开,IDA会提示exe的入口点在其他的位置,应该是有壳,先对它进行查壳脱壳:
在这里插入图片描述

再用IDA打开:
在这里插入图片描述

int __cdecl main(int argc, const char **argv, const char **envp)
{__time32_t v3; // ST40_4@1DWORD Seed; // ST38_4@1int v5; // eax@2signed int v7; // [sp+24h] [bp-34h]@1v3 = time32(0i64);        //0i64表示int64_t类型的0,time3()表示返回自1970年1月1日午夜起经过的秒数,或者在出现错误时返回-1Seed = GetCurrentProcessId() ^ v3;   //获取当前进程的唯一标识srand(Seed);v7 = 0;do{v5 = rand();printf(Format, (v5 >> 7) & 0xFF);++v7;}while ( v7 < 16 );return 0;
}

这就是代码的关键部分,获取当前系统时间和进程号,来进行运算生产16字节的密钥,所以我们将时间调整到2019/04/11 22:10:34之前进行爆破,因为我们是进行爆破,所以时间不用太准确,只要在这之前都行,当然这里的2019/04/11 22:10:34可能是老师给的hint:设置密钥的正确事件。我将当前时间设为了2019/04/11 22:10:00开始,先将它转换成从1970年1月1日以来持续时间的秒数:
源代码:time.c

#include<stdio.h>
#include<time.h>
/**
struct tm {int tm_sec;// 秒 - 取值区间为[0,59] /int tm_min; // 分 - 取值区间为[0,59] /int tm_hour; / 时 - 取值区间为[0,23] /int tm_mday; / 一个月中的日期 - 取值区间为[1,31] /int tm_mon; / 月份 (从一月开始,0代表一月) - 取值区间为[0,11] /int tm_year; / 年份,其值等于实际年份减去1900 /int tm_wday; / 星期 - 取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 /int tm_yday; / 从每年的1月1日开始的天数 - 取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推 /int tm_isdst; / 夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的时候,tm_isdst为0;不了解情况时,tm_isdst()为负. /
};
*/
int main(void)
{//获取时间差struct tm tnNormal;///开始的时间:2019/04/11 22:10:00tnNormal.tm_year = 2019-1900;tnNormal.tm_mon = 4-1;tnNormal.tm_mday = 11;tnNormal.tm_hour = 22;tnNormal.tm_min = 10;tnNormal.tm_sec = 0;tnNormal.tm_isdst = 0;time_t tmNormal;tmNormal = mktime(&tnNormal);///开始的时间:2019/04/11 22:10:00转化为的秒数:1554991800printf("开始的时间:2019/04/11 22:10:00转化为的秒数:%d\n",tmNormal);return 0;
}

运行结果:
在这里插入图片描述

将2019/04/11 22:10:00转化为的秒数是:1554991800。接下来从1554991800开始递加,当前进程ID从0到100000循环,爆破直到得出的密钥第1个字节是0x25第2个字节是0x61:
下面是源代码:key.c

#include<stdlib.h>
#include <stdio.h>
/**
0~100000和0~500的第一个解
0x25 0x61 0x6c 0xd5 0x1d 0xd3 0x4b 0xcb 0xe7 0x34 0x97 0x93 0xa4 0x92 0x53 0x1f
当前时间:1554991800,当前进程:32375
*/
int main()
{///开始的时间:2019/04/11 22:09:00__time32_t v3 = 1554991800; // ST40_4@1long Seed; // ST38_4@1int v5; // eax@2signed int v7; // [sp+24h] [bp-34h]@1int i;int flag = 0;int id;__time32_t now;///0x25和0x61__int8 v4,v6;///时间递加for(i = 0; i< 500; i++){now = v3+i;///获取当前进程的唯一标识GetCurrentProcessId()for(id = 0 ; id < 100000 ; id++){Seed = id ^ now;///设置时间种子srand(Seed);v7 = 0;__int8 temp = 0;do{///根据时间种子生成随机数v5 = rand();temp = (v5 >> 7) & 0xFF;///第一个数是0x25if( v7 ==0 && 0x25 == temp){v4 = 0x25;///第一个数不是0x25}else if(v7 == 0 && temp !=0x25){v4 = 0;break ;}///第二个数是0x61if(v7 == 1 && 0x61 == temp){v6 = 0x61;printf("0x25 ");///第二个数不是0x61}else if(v7 == 1 && 0x61 != temp){v4 = 0;v6 = 0;break;}///如果找到结果if(v4 == 0x25 && v6 ==0x61){printf("0x%x ",temp & 0xFF);}++v7;}while( v7 < 16 );if(v7 == 16){///输出正确答案printf("\n当前时间:%d,当前进程:%d\n",now,id);flag = 1;break;}}if(flag == 1){printf("flag\n");break;}}return 0;
}

运行结果:
在这里插入图片描述

最后破解的16字节密钥为:0x25 0x61 0x6c 0xd5 0x1d 0xd3 0x4b 0xcb 0xe7 0x34 0x97 0x93 0xa4 0x92 0x53 0x1f。
到这破解的密钥已经得到的,但是我们发现当前时间:1554991800,当前进程:32375,因为随机种子是由当前时间和当前进程异或得到的,所以随着当前时间和当前进程递增,会出现多个时间和进程的异或结果相同,然后它们都最终得到这同一个密钥:0x25 0x61 0x6c 0xd5 0x1d 0xd3 0x4b 0xcb 0xe7 0x34 0x97 0x93 0xa4 0x92 0x53 0x1f。
我们来输出一下增加的时间0500以内和进程ID在0100000以内的所有解:
源代码:

#include<stdlib.h>
#include <stdio.h>int main()
{///开始的时间:2019/04/11 22:10:00__time32_t v3 = 1554991800; // ST40_4@1long Seed; // ST38_4@1int v5; // eax@2signed int v7; // [sp+24h] [bp-34h]@1int i;int flag = 0;int id;__time32_t now;///0x25和0x61__int8 v4,v6;///时间递加for(i = 0; i< 500; i++){now = v3+i;///获取当前进程的唯一标识GetCurrentProcessId()for(id = 0 ; id < 100000 ; id++){Seed = id ^ now;///设置时间种子srand(Seed);v7 = 0;__int8 temp = 0;do{///根据时间种子生成随机数v5 = rand();temp = (v5 >> 7) & 0xff;///第一个数是0x25if( v7 ==0 && 0x25 == temp){v4 = 0x25;///第一个数不是0x25}else if(v7 == 0 && temp !=0x25){v4 = 0;break ;}///第二个数是0x61if(v7 == 1 && 0x61 == temp){v6 = 0x61;printf("0x25 ");///第二个数不是0x61}else if(v7 == 1 && 0x61 != temp){v4 = 0;v6 = 0;break;}///如果找到结果if(v4 == 0x25 && v6 ==0x61){printf("0x%x ",temp & 0xff);}++v7;}while( v7 < 16 );if(v7 == 16){///输出正确答案printf("\n当前时间:%d,当前进程:%d,异或的结果随机种子:%d\n",now,id,now^id);v4 = 0;v6 = 0;}}}return 0;
}

运行结果:
在这里插入图片描述

这是因为源文件算法中异或这个限制条件不够苛刻,又没有其他的条件来限制多解,才会出现这样的情况,题目的主要用意也是让我们明白以当前系统时间作为随机种子并不是安全的。

这篇关于某文件被加密了(基于时间的随机种子破解)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/627301

相关文章

如何利用Java获取当天的开始和结束时间

《如何利用Java获取当天的开始和结束时间》:本文主要介绍如何使用Java8的LocalDate和LocalDateTime类获取指定日期的开始和结束时间,展示了如何通过这些类进行日期和时间的处... 目录前言1. Java日期时间API概述2. 获取当天的开始和结束时间代码解析运行结果3. 总结前言在J

修改若依框架Token的过期时间问题

《修改若依框架Token的过期时间问题》本文介绍了如何修改若依框架中Token的过期时间,通过修改`application.yml`文件中的配置来实现,默认单位为分钟,希望此经验对大家有所帮助,也欢迎... 目录修改若依框架Token的过期时间修改Token的过期时间关闭Token的过期时js间总结修改若依

Go Mongox轻松实现MongoDB的时间字段自动填充

《GoMongox轻松实现MongoDB的时间字段自动填充》这篇文章主要为大家详细介绍了Go语言如何使用mongox库,在插入和更新数据时自动填充时间字段,从而提升开发效率并减少重复代码,需要的可以... 目录前言时间字段填充规则Mongox 的安装使用 Mongox 进行插入操作使用 Mongox 进行更

对postgresql日期和时间的比较

《对postgresql日期和时间的比较》文章介绍了在数据库中处理日期和时间类型时的一些注意事项,包括如何将字符串转换为日期或时间类型,以及在比较时自动转换的情况,作者建议在使用数据库时,根据具体情况... 目录PostgreSQL日期和时间比较DB里保存到时分秒,需要和年月日比较db里存储date或者ti

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Python 标准库time时间的访问和转换问题小结

《Python标准库time时间的访问和转换问题小结》time模块为Python提供了处理时间和日期的多种功能,适用于多种与时间相关的场景,包括获取当前时间、格式化时间、暂停程序执行、计算程序运行时... 目录模块介绍使用场景主要类主要函数 - time()- sleep()- localtime()- g

Java中的密码加密方式

《Java中的密码加密方式》文章介绍了Java中使用MD5算法对密码进行加密的方法,以及如何通过加盐和多重加密来提高密码的安全性,MD5是一种不可逆的哈希算法,适合用于存储密码,因为其输出的摘要长度固... 目录Java的密码加密方式密码加密一般的应用方式是总结Java的密码加密方式密码加密【这里采用的

使用C#如何创建人名或其他物体随机分组

《使用C#如何创建人名或其他物体随机分组》文章描述了一个随机分配人员到多个团队的代码示例,包括将人员列表随机化并根据组数分配到不同组,最后按组号排序显示结果... 目录C#创建人名或其他物体随机分组此示例使用以下代码将人员分配到组代码首先将lstPeople ListBox总结C#创建人名或其他物体随机分组

如何用Java结合经纬度位置计算目标点的日出日落时间详解

《如何用Java结合经纬度位置计算目标点的日出日落时间详解》这篇文章主详细讲解了如何基于目标点的经纬度计算日出日落时间,提供了在线API和Java库两种计算方法,并通过实际案例展示了其应用,需要的朋友... 目录前言一、应用示例1、天安门升旗时间2、湖南省日出日落信息二、Java日出日落计算1、在线API2

使用Python制作一个PDF批量加密工具

《使用Python制作一个PDF批量加密工具》PDF批量加密‌是一种保护PDF文件安全性的方法,通过为多个PDF文件设置相同的密码,防止未经授权的用户访问这些文件,下面我们来看看如何使用Python制... 目录1.简介2.运行效果3.相关源码1.简介一个python写的PDF批量加密工具。PDF批量加密