关于CTF逆向中的模运算的逆向

意识流写文,看不明白的可以之间看看结尾的结论,第一次写求轻喷

这次在写花指令的时候碰到了这样一条加密语句:

for ( i = 0; i < 29; ++i )

Str1[i] = (Str1[i] + Str1[(i * i + 123) % 21]) % 96 + 32;

if ( !j_strcmp(Str1, "~4G~M:=WV7iX,zlViGmu4?hJ0H-Q*") )

puts("right!");

else

puts("nope!");

很显然,语句Str1[i] = (Str1[i] + Str1[(i * i + 123) % 21]) % 96 + 32;就是该加密程序的主体,但在我自己尝试编写逆向程序的时候却发现了一个问题:%96这一步运算该如何逆向呢?

%运算也叫模运算,原理是取除法运算的余数,只取余数的性质导致了该运算在进行时必然会导致原文信息的丢失,比如我们知道某数与5进行模运算后的结果为3,我们只能知道该数为k · n + 3,其中k、n均未知,这也就是“丢失的信息”

卡在这里了,AI也写不出逆向脚本,搜了一下密文找到了原题WP,人居然写出了逆向脚本,不得不说AI果然永远无法取代人类~

enc = '~4G~M:=WV7iX,zlViGmu4?hJ0H-Q*'
print(len(enc))
print()
arr = []
for i in range(len(enc)):
    arr.append(ord(enc[i]))
for i in range(len(arr) - 1, -1, -1):

    arr[i] = arr[i] - 32 - arr[(i * i + 123) % 21]
    if arr[i] < 96:
        arr[i] += 96
for i in range(len(enc)):
    while arr[i] < 32 or arr[i] > 128:
        arr[i] += 96
        arr[i] %= 128
for i in range(len(arr)):
    print(chr(arr[i]), end='')
print()
print(arr)

下面来逐步分析一下逆向过程:

enc = '~4G~M:=WV7iX,zlViGmu4?hJ0H-Q*'
print(len(enc))
print()

arr = []

这三条语句测定了密文的长度,格式化了一下控制台的输出,并且定义了一个名为arr的数组用于解密

for i in range(len(enc)):
arr.append(ord(enc[i]))

这里进行一个循环,将密文中的字符逐个转化为ASCII码值并存入数组arr中

for i in range(len(arr) - 1, -1, -1):
arr[i] = arr[i] - 32 - arr[(i * i + 123) % 21]
if arr[i] < 96:
arr[i] += 96

这里再进行一个循环,range(len(arr) - 1, -1, -1) ,从len(arr) - 1(即列表的最后一个元素的索引)开始,到-1(即列表的第一个元素的索引)结束,步长为-1,意味着每次迭代都会减少1 ,下面是一个执行例子:

也就是说这样的循环主要时起一个反向遍历的作用

关于为什么range函数的第二个参数是-1却指向数组arr的第一个元素:

首先我们来了解一下range函数的几个参数:

range(start, stop, step)

其中start参数是包括在内的第一个数,stop参数是包括在内的最后一个数,step参数是两个数之间的差,即步长,stop参数本身是range结束的条件,而不是结束的索引,所以将start设置为len(arr)-1令开始range的数组索引为数组长度-1,即数组尾元素的索引,步长为-1,每次返回一个索引值后-1,也就是说,遍历至1时返回1,减1后为0,返回0,减1后为-1,满足stop条件,结束遍历(也就是判断stop条件的优先级是比返回值的优先级是要高的),我们也可以据此写出等价的C语言语句来帮助理解:

int i;

for(i=strlen(arr);i>-1;i--){

······································

}

我们继续脚本的分析:

arr[i] = arr[i] - 32 - arr[(i * i + 123) % 21]

这里是对加密主体的逆向,我们对比原加密语句:

Str1[i] = (Str1[i] + Str1[(i * i + 123) % 21]) % 96 + 32;

原语句的计算详解:

计算i*i+123,结果与21取余(确保值不超过21)作为处理对象的数组索引,再与索引为i的数组元素相加(指ASCII码值相加),结果与96取余(确保值不超过96),再加上32,最后存入索引为i的数组元素

逆向计算详解:

对已经转换为ASCII码值的数组,从最后一个对象开始,先计算i*i+123%21的值,再依次以该对象作为被减数,减去32和arr[i*i+123%21]的ASCII码值

为什么这么做:

我们注意到,原加密语句是对特定索引对象的值的运算加密,并没有更换了这个索引的值,也就是说,我们可以通过密文值的索引知悉与他进行运算的对象的索引值,即arr[i]总是与arr[i*i+123%21]进行运算

减去32,逆向至Str1[i] = (Str1[i] + Str1[(i * i + 123) % 21]) % 96

减去arr[(i * i + 123) % 21]:

这里引入一下模运算的特殊性质:

令:@符为+-*/中的任意一种

则有:

(a @ b) % n = (a % n @ b % n) % n

再来回顾我们的解密思路:

逆向至Str1[i] = (Str1[i] + Str1[(i * i + 123) % 21]) % 96这一步,我们期望能够逆向“%96”这个运算,但实际上并不存在这样一种运算

我们假设存在运算#,它是%运算的逆运算,那么它将具有%运算的性质

那么我们想要的语句即为:

arr[i] = arr[i] # 96 - arr[(i * i + 123) % 21]

同时我们应注意到的是:

在大多数编程语言中,包括Python、Java、C、C++等,数学运算符(如加法+、减法-、乘法*、除法/等)的优先级高于百分比运算符%。这意味着当一个表达式中同时包含这些运算符时,数学运算符会首先被计算。

注意到:

在原加密中(Str1[i] + Str1[(i * i + 123) % 21]) % 96 + 32;

加法部分是被括起来的(不影响优先级),而我们的期望逆向语句中:

arr[i] = arr[i] # 96 - arr[(i * i + 123) % 21]

是没有括号的,也就是说在这条语句的实际执行情况下,是会先计算

- arr[(i * i + 123) % 21]部分的,也就是#部分的逆向我们可以后置不管

继续我们的分析:

if arr[i] < 96:
arr[i] += 96

这里的if语句判断我们计算后的结果是否小于96,否则加96,以确保接下来对%96的逆向过程正常进行

for i in range(len(enc)):
while arr[i] < 32 or arr[i] > 128:
arr[i] += 96
arr[i] %= 128

这里是解密的关键部分,for条件设置为遍历数组的长度(即i的值从1到字符串的长度值之间递增)

对于while部分:如果arr[i]的值小于32或者大于128,则将其加96或与128取余, 以确保每个 ASCII 值在可打印字符的范围内(32 至 128)

总的来说,对于取模运算的逆向,在没有逆运算符存在的情况下,我们需要利用模运算的特点,即取余出来的这个数一定是原数的“特征”,这个“特征数”加上n个模数一定能够得到原数,利用这一特点进行逆向即可

如何防止得不到原数?就是上面的while语句的作用

  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
大学生在线租房平台管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、报修评价管理、字典管理、房东管理、房屋管理、房屋收藏管理、房屋留言管理、房屋租赁管理、租房论坛管理、公告信息管理、留言板管理、用户管理、管理员管理。用户的功能等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 大学生在线租房平台管理系统可以提高大学生在线租房平台信息管理问题的解决效率,优化大学生在线租房平台信息处理流程,保证大学生在线租房平台信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理大学生在线租房平台信息,包括房屋管理,培训管理,报修管理,薪资管理等,可以管理公告。 房屋管理界面,管理员在房屋管理界面可以对界面显示,可以对房屋信息的房屋状态进行查看,可以添加新的房屋信息等。报修管理界面,管理员在报修管理界面查看报修种类信息,报修描述信息,新增报修信息等。公告管理界面,管理员在公告管理界面新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值