DASCTF2024金秋十月复现
CRYPTO
ez_RSA
- 题目附件如下:
1 | from Crypto.Util.number import * |
- 我们先来看第三部分,如果是解题为目的的话,只需要解这一部分就可以了,解这一部分即可得到
flag。可以直接使用gcd得到。推导过程的话会一些同余的运算性质即可。
1 | q1 = getPrime(512) |
推导过程如下:
exp如下:
1 | leak1= 82301473255013183706458389946960254392188270550712533886416705365418418731488346328643954589202172816597173052792573628245245948345810581701878535280775967863966009605872386693838526935762655380705962833467046779524956212498594045378770790026387120339093736625186401934354434702063802537686761251873173518029 |
- 再来看第一部分,主要先来介绍一下
RealField():RealField()是实现任意精度的浮点数,一般浮点数都是采用IEEE754标准,精度会有限制。而RealField(),是实现任意精度的浮点数,而代码中的设定了1050精度的浮点数。- 在该精度下实现俩个素数相除,并且得到
1050精度大小的小数。
1 | num1 = getPrime(512) |
- 此时我们就要通过小数来还原
分子和分母这俩个素数。而我们的小数可以使用连分数展开,展开之后我们可以将连分数化为正常的分数形式,这样俩个素数就已经还原回来了。 - 这时我们再检查一下这俩个素数是否正确就行了。用到的连分数相关的定理目前我还没具体了解,等了解后就贴出(先填一个坑)。
- 在
sagemath中可以使用如下几个函数对小数进行转换:continued_fraction函数:将一个小数转换成连分数的形式,返回的是一个类似于列表形式。numerator方法:这个方法是对返回的连分数进行操作,该方法是传递的参数是获取指定第n个收敛子对应的分子denominator方法:这个方法同numberator,但是它是获取指定第n个收敛子对应的分母。- 但是我们并不知道要对应的是第几个收敛子的分子,所以我们要爆破和做判断从而解出
num1和num2
1 | num3 = "1.36557212221826657073387899060669771982679822943621690677450888408226656788387273887547841291114809989272635809810564202247340711087479554863446719786359395466961253205133910506682801159622545780721946115442033391600881399634390008053822158098121985270501317972263356522400827768601773721146954464269212959784543085" |
- 接下去我们查看第二步,第二步与共模攻击比较像,但是由于是加密俩个不同的
m,所以不是共模攻击。
1 | n2 = getPrime(512) * getPrime(512) |
- 稍微查看了一下思路,这一部分的思路还是运用方程的思想,将
c1和c2转换为模n2下关于p的两个方程。 - 这时我们先用其中一个方程进行求解,查看是否能解出来,我们发现无论使用
c1还是c2这个方程,都不能解出来
1 | num1 = 9234477875452540050907055680812175733211030585401847024956094109885380715661662501110233684131338074697772834745898452222070551975818702828913932925854661 |
- 我们只能再寻找其他方式,注意到我们有俩个方程,并且这是俩个多项式方程。先将这俩个方程列出来,不妨设
p为未知数x:
- 我们将这个多项式展开后就得到,得到俩个不同项数的多项式方程。
- 这时我们就可以使用辗转相除法,在多项式中的运用,先举一个例子,现在有俩个多项式
- 我们很快就反映出来这俩个多项式有一个公因式为:$x-1$也就是我们可以把$x^2-1$因式分解成$(x+1)(x-1)$,但是像$f_1、f_2$这样的很长的多项式,就很难对其进行因式分解就像大整数难以找因数这样。
- 而我们可以使用多项式的辗转相除法,如果寻找到俩个多项式的公因式,就可以说明这俩个多项式因式分解后必然有我们求得的公因式。
- 这样我们就将$f_1、f2$这样的多项式简化为这俩个公因式,使用这两个的公因式去再去求解方程,这次就可以求解成功了。在
sagemath中没有实现Zmod(n)下的多项式辗转相除法。我们要手动实现gcd。这时我们可以得到一个关于x的一次多项式,这时我们就可以解出该方程的解。 - 所以exp如下,其中
-f2.monic()[0]将多项式的首项系数变为负数,从而得到正数解,接下来就是RSA的解密了:
1 | num1 = 9234477875452540050907055680812175733211030585401847024956094109885380715661662501110233684131338074697772834745898452222070551975818702828913932925854661 |
easy_xor
PWN
sixbytes
分析1
- 先来查看一下保护机制,发现保护全开

- 接下来逆向分析一下程序,先来查看一下
main函数:主要调用了sub_134A、sub_142C、sub_13B8、sub_12A9、v3()

- 接下来我我们就来查看一下这些函数,查看
sub_134A发现是一个输入输出初始化的函数,我们将其命名为init函数

- 接下来我们查看
sub_142C就会发现这个函数会将flag读取出来放入bss段中,并且会返回bss段上的地址

- 查看
sub_13B8发现,这里就是开辟一个可读可写可执行的内存段,然后允许我们写入6字节

- 查看
sub_12A9发现,这个函数起到一个开启沙箱的作用

- 之后我们就会执行我们写入的那
6个字节。
分析2
- 这题是一个写
shellcode类型,还开启了沙箱,现在来查看一下沙箱的禁用。我们发现这个沙箱是一个黑名单,将系统调用号小于0x40000000都给禁用了,所以这题应该需要侧信道

- 我们先了解清楚,我们在调用
v3这个函数的时候寄存器布局和栈布局如下,这样更有利于我们写shellcode。我们发现flag存储存放的地址值在RDI有直接给出。

- 一开始想不出来怎么构造
6字节侧信道,看了wp之后才发现能这样构造。接下来就是一些接收和异常处理了。 - 构造的
shellcode如下,如果大于的时候就会执行loop循环
1 | loop: |
- 当程序执行循环的时候,如果我们进行接收,就会出现如下的报错。

- 但是当没进入循环的时候程序会直接结束,我们接收时并不会抛出异常。

- 利用这个特点,我们从低字节爆破到高字节,这样当一个flag位第一次出现异常的时候,我们就知道,这个位的flag值就被爆破出来了。我们就可以接下去爆破下一个flag的位。最终我们就能爆破出flag的值。(爆破的有点慢,先做其他题去)

- exp如下:
1 | from pwn import * |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 iyheart的博客!

