flare-on 7 break第三部分求解:一元线性同余方程
思考的结论:其实这种国际性的逆向比赛,肯定会考一些数学的知识,这个考的是比较基础了,无奈自己没有这个基础。
话说还是flare 7的break这道题,到了最后,第三步验证,函数竟然来到了0x08053B70,没办法,硬着头皮分析。
结果发现两个关键函数,一个是把用户输入的后24位与程序中预先设置的常量进行运算得到b,另一个是使用b与程序中预先设置的常量进行计算,得到的结果必须等于另一个常量。这里不详细写了,做过这道题的都知道。
使用一般的调试技巧,能分析出的也就是这样子了。按照一般的思路,应该是逆推出这两个函数,然后求解出用户输入的后24位。但是我看了一下,这两个函数又套了很多函数,分析的工作量不小,起码以我的水平,最怕的就是这个(逆向绕不开的算法分析,以前都是通过动态调试来猜)。
说到这里,就不得不提一下我看的这篇博文了,系统的讲了break如何系统的分析。每次我实在是做不下去或没思路的时候,就看一点,然后继续往下,(Flare-On 7 — 10 Break - explained.re)
按照博文里这部分的思路,这里是大数运算,并且博文还猜出了作者使用的大数运算c语言库(汗死)。
好吧,谁让咱的水平低,我等不才,比对着c库也理清了最开始提到的两个函数都是干什么的。原来就是形如(a*x)%b=c,已知a,b,c(余数),求x(x就是用户输入的最后24位)。无耐数学功底不行,这就是本篇要说的重头了,不知道这是一个一元线性同余方程,傻傻的只想着按照将商从0,1,2依次类推的方式去穷举计算x,结果机器跑了一会,也没跑出结果。最后,还是看了博文,才知道原来可以用一元线性同余方程的解法来求解。说起一元线性同余方程 - Howey - 博客园,可参考这篇链接。原来x的特解是可以直接求出来的。python的实现参考https://www.py4u.net/discuss/178110,以下是抄出来有用的篇章,笔记之。
If you have Python 3.8 or later, you can do everything you need to with a very small number of lines of code.
First some mathematics: I'm assuming that you want to solve ax = b (mod m)
for an integer x
, given integers a
, b
and m
. I'm also assuming that m
is positive.
The first thing you need to compute is the greatest common divisor g
of a
and m
. There are two cases:
if
b
is not a multiple ofg
, then the congruence has no solutions (ifax + my = b
for some integersx
andy
, then any common divisor ofa
andm
must also be a divisor ofb
)if
b
is a multiple ofg
, then the congruence is exactly equivalent to(a/g)x = (b/g) (mod (m/g))
. Nowa/g
andm/g
are relatively prime, so we can compute an inverse toa/g
modulom/g
. Multiplying that inverse byb/g
gives a solution, and the general solution can be obtained by adding an arbitrary multiple ofm/g
to that solution.
Python's math module has had a gcd function since Python 3.5, and the built-in pow function can be used to compute modular inverses since Python 3.8.
Putting it all together, here's some code. First a function that finds the general solution, or raises an exception if no solution exists. If it succeeds, it returns two integers. The first gives a particular solution; the second gives the modulus that provides the general solution.
def solve_linear_congruence(a, b, m):""" Describe all solutions to ax = b (mod m), or raise ValueError. """g = math.gcd(a, m)if b % g:raise ValueError("No solutions")a, b, m = a//g, b//g, m//greturn pow(a, -1, m) * b % m, m
And then some driver code, to demonstrate how to use the above.
def print_solutions(a, b, m):print(f"Solving the congruence: {a}x = {b} (mod {m})")try:x, mx = solve_linear_congruence(a, b, m)except ValueError:print("No solutions")else:print(f"Particular solution: x = {x}")print(f"General solution: x = {x} (mod {mx})")
Example use:
>>> print_solutions(272, 256, 1009)
Solving the congruence: 272x = 256 (mod 1009)
Particular solution: x = 179
General solution: x = 179 (mod 1009)
>>> print_solutions(98, 105, 1001)
Solving the congruence: 98x = 105 (mod 1001)
Particular solution: x = 93
General solution: x = 93 (mod 143)
>>> print_solutions(98, 107, 1001)
Solving the congruence: 98x = 107 (mod 1001)
No solutions
Answered By: oppressionslayer
那么好了,我们最终的计算代码就是:(注意需在python 3.8以上运行)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#python 3.8
import math
def solve_linear_congruence(a, b, m):
""" Describe all solutions to ax = b (mod m), or raise ValueError. """
g = math.gcd(a, m)
if b % g:
raise ValueError("No solutions")
a, b, m = a//g, b//g, m//g
return pow(a, -1, m) * b % m, m
def print_solutions(a, b, m):
print(f"Solving the congruence: {a}x = {b} (mod {m})")
try:
x, mx = solve_linear_congruence(a, b, m)
except ValueError:
print("No solutions")
else:
print(f"Particular solution: x = {x}")
print('%#x'%x)
print(f"General solution: x = {x} (mod {mx})")
print_solutions(0xc10357c7a53fa2f1ef4a5bf03a2d156039e7a57143000c8d8f45985aea41dd31, 0xd036c5d4e7eda23afceffbad4e087a48762840ebb18e3d51e4146f48c04697eb, 0xd1cc3447d5a9e1e6adae92faaea8770db1fab16b1568ea13c3715f2aeba9d84f)
计算结果:
Solving the congruence: 87302286152129012315768956895021811229194890355730814061380683967744348118321x = 94177847630781348927145754531427408195050340748733546028257255715312033503211 (mod 94894182982585115752273641869831161604229729487611399267972930833928751274063)
Particular solution: x = 2683341019241907426637994517385351720290552198150109556319
0x6d6f632e6e6f2d6572616c6640733369707075705f306e5f
General solution: x = 2683341019241907426637994517385351720290552198150109556319 (mod 94894182982585115752273641869831161604229729487611399267972930833928751274063)
翻译成对应的ASCII码就是“moc.no-eralf@s3ippup_0n_”。 因为机器是little_endian,所以字符串的顺序是反的,把它反过来就是flag的第三部分了。
篇外:回去翻了一下离散数学,发现数论部分只讲到了同余,还没讲同余方程。我脑子里以前也是印象中有同余这么个概念,具体说不上来怎么用。
另外,就是大数运算需要学习一下,没有识别出来是在做大数运算。
flare-on 7 break第三部分求解:一元线性同余方程相关推荐
- 如何使用最小二乘法来求解一元线性回归
如何使用最小二乘法来求解一元线性回归 本文通过使用最小二乘法来求解一元线性回归方程来解释一下为啥线性回归可以直接求解 一.什么是线性回归模型 线性回归是利用数理统计中回归分析,来确定两种或两种以上变量 ...
- 迷宫问题的三种求解方法(递归求解、回溯求解和队列求解)
目录 一.迷宫问题的三种求解方法 递归求解 回溯求解 队列求解 二.华为迷宫问题 一.迷宫问题的三种求解方法 在迷宫问题中,给定入口和出口,要求找到路径.本文将讨论三种求解方法,递归求解.回溯求解和队 ...
- Topk问题的三种求解方法
Topk问题的三种求解方法 什么是Topk问题 方法一:堆排序法 方法二:把N个数建堆,取出前k个 方法三:建一个k个数的堆 什么是Topk问题 其实顾名思义,这个问题也就是在N个数中找出前k个最值. ...
- ZZULIOJ 1076: 三位数求解
三位数求解 题目描述 已知xyz+yzz=n,其中n是一个正整数,x.y.z都是数字(0-9),编写一个程序求出x.y.z分别代表什么数字.如果无解,则输出"No Answer" ...
- 七参数坐标转换 matlab,利用三点法求解空间坐标系转换所需的七参数
同一个物体的点云在不同坐标系中的坐标表示不同,有时候需要将其进行转换到同一坐标系中进行处理,经典的方法为七参数法(7-parameters),用matlab实现如下: %PS.好久不用matlab了, ...
- Python编写程序求解一元二次方程,打印九九乘法表,判断三条边是否可以构成三角形,并求三角形面积
目录 求解一元二次方程题目总体要求如下: 打印九九乘法表题目总体要求如下: 判断三条边是否可以构成三角形题目要求如下: 求解一元二次方程题目总体要求如下: 编写程序,输入一元二次方程的三个系数a.b. ...
- 乘法逆元的三种求解方法
目录 乘法逆元小结 逆元的定义 求解逆元的方法 1. 快速幂 测试代码 2.拓展欧几里得 测试代码 3.线性算法 例题 AC代码 乘法逆元小结 参考自:点击此处 乘法逆元,一般用于求(a / b)(m ...
- break的三种用法
break的三种用法 1.switch中使用 /*** switch*/ System.out.println("----------switch"); switch (1) {c ...
- 求解线性同余方程--扩展欧几里得
资料来源:https://blog.csdn.net/ //求解ax=b(mod m) 返回0为无解,否则返回gcd(a,m)个mod m意义下的解,用X[]存 int mod(int a, int ...
最新文章
- Javascript实现表格的全选框
- 华数大数据平台解决方案
- 【模型迭代】模型迭代
- C# HttpRequest基础连接已经关闭: 接收时发生意外错误
- Laravel 错误处理
- Linux 下 VuePress 的安装使用
- boost::geometry::strategy::distance::cross_track用法的测试程序
- Divide by three, multiply by two(dfs)
- springboot + redis
- linux网卡绑定和漂移,LINUX修改、增加IP的方法,一张网卡绑定多个IP/漂移IP【转】...
- fabric.js 不同类型 不同控件_策略模式支持不同类型的消息队列
- 此页的状态信息无效,可能已损坏---应用程序中的服务器错误---
- 计算IO设备、CPU利用率
- 南开100题c语言计算机二级,3月计算机二级C语言题库南开100题.pdf
- 【计算广告】边际成本的妙用
- 玩转prometheus告警 alertmanger(二)之alertmanger 邮件 钉钉告警
- 以太网PHY寄存器分析
- ngrok私有服务搭建(docker交叉编译)
- uniapp适配ipad端平板端
- Vue实现二选一、菜单更多功能: