PWN-堆基础之Safe Unlink
Safe Unlink简介
Safe Unlink增加了两个检测机制。
首先,检测大小是否一致,即检查next_chunk的prev_size和当前chunk的size域是否相等。
然后,检测双向链表完整性,即检查chunk.fd -> bk == chunk、chunk.bk -> fd == chunk。
条件
可以泄露保存chunk指针的数组地址。
存在堆溢出漏洞可以修改next_chunk的size域 或 存在UAF漏洞。
可以泄露libc地址。
利用
为方便描述,下文称chunk指针数组 = m_array。
在当前chunk数据段伪造一个fake_chunk,使得fake_chunk的fd指向&m_array - 0x18,bk指向
&m_array - 0x10。(绕过双向链表检测)
将next_chunk的prev_size修改为当前chunk大小,然后将size域中prev_inuse置0。(绕过大小
检查,prev_size用于程序定位到fake_chunk) ...
PWN-堆基础之Unsafe Unlink
Unsafe Unlink1.unsorted bin首先介绍unsorted bin,unsortedbin 是一个双向链表的结构,因此a中这两个指针分别是bk和fd,分别指向前一个和后一个chunk;free时,若该chunk没有紧邻top chunk,则不会与top chunk进行合并,它首先被链入unsorted bin中,被首次分配时,unsorted bin会扫描各chunk并根据大小链入不同bin中。
2.Unsafe Unlink简介
Unsafe Unlink指的是早期unlink,没有大小检查、双向链表完整性检查,并且没有NX保护
当进行unlink时,会执行如下操作:
12this->fd->bk = this->bk;this->bk->fd = this->fd;
因此,如果我们能够伪造fd和bk的指向,就可以实现任意地址写入,而要进行unlink操作我们需要修改next_chunk的pre_inuse为0,这是free掉next_chunk会使这两个chunk进行合并。
条件
未开启NX保护。
程序存在堆溢出漏洞 ...
PWN-堆基础之FastBin_Attack
FastBin_AttackFastBin_dup1.FastBinfastbin采用LIFO的单链表方式管理空闲chunk,fastbin不会修改空闲chunk的prev_inuse标志位,也不会进行堆块合并。
fastbin的大小范围为0x20-0x80,共7个单链表数组(只有fd指针,即单向链表)。每个链表数组依次递增0x10大小。相同大小的chunk会被分配到同一个链表数组中。
当某个堆块被释放后,它的fd指针会指向下一个空闲chunk,arena会保存每个链表头部chunk的地址。
注:free释放堆块后,会将堆块链入到main_arena对应大小的bin中,可以用dq &main_arena 20查看main_arean中存放的各个bin的头结点。从上到下分别对应main_arean布局中的不同大小的chunk块。
Double Free简介
Double Free即两次释放同一个chunk,可以伪造该chunk的fd指针,在fastbin链表中增加一个fake_chunk地址,实现任意地址写。
由于libc中加入了double free缓解机制,即会检查当 ...
PWN-堆基础之House of Force
House of Force攻击1.top_chunk:在学校House of force之前,先来学习top_chunk:
top chunk是一块很大的chunk块,不属于任何Bin,在arena中属于最高地址。每次程序初始化后会调用sbrk函数创建一块大小为(0x21000) 的区域作为top_chunk,每次malloc时,首先从各种bins种寻找,没有其它空闲块时,top_chunk就会被用于分配。
堆内布局如下:
每次malloc时,top_chunk指针向高地址移动(原理堆基地址),同时size变小(但如果我们更改size字段,top_chunk指针不动)
这里说明一下malloc:首次的malloc从top_chunk处申请,返回申请的指针指向申请的data字段,并不指向pre_size控制字段。
申请规则如下:malloc申请到的chunk大小(特指我想要的数据长度大小)会比实际申请的大小多0x10。(因为多0x10的控制字段,32位同理会多0x8)
12345678#include <stdlib.c> int mian(){ mal ...
Crypto-常用工具
密码学常用工具引自crypto常用工具 | Lazzaro (lazzzaro.github.io)
1.gmpy212345678910from gmpy2 import *mpz(n) #初始化一个大整数mpfr(x) # 初始化一个高精度浮点数xd = invert(e,n) # 求逆元,de = 1 mod nc = powmod(m,e,n) # 幂取模,结果是 c = m^e mod nis_prime(n) #素性检测gcd(a,b) #欧几里得算法,最大公约数gcdext(a,b) #扩展欧几里得算法iroot(x,n) #x开n次根
2.sympy12345678from sympy import *prime(n) #第n个素数isprime(n) #素性检测primepi(n) #小于n的素数的总数nextprime(n) #下一个素数prevprime(n) #上一个素数nthroot_mod(c,e,p,all_roots=True) #有限域开方
3.Sage123456R.<X> = PolynomialR ...
Crypto-多项式环链表求解
多项式环上求解问题:引自 Lazzaro @ https://lazzzaro.github.io
1.对于一些模n运算的求解,我们可以将问题转化为模n多项式环上求解答问题1234567R.<X> = PolynomialRing(Zmod(n))#Zmod(n):指定模,定义界限为n的环;Z表示整数;指定模是划定这个环的界限,就是有效的数字只有从0到n,其他的都通过与n取模来保证在0~n这个范围内;Zmod代表这是一个整数域中的n模环#ZZ:整数环;QQ:有理数环;RR:实数环;CC:复数环#R:只是一个指针,指向用polynomialring指定的那个环(可以使用任意字符)#PolynomialRing:这个就是说建立多项式环#.<X>:指定一个变量的意思(可以用任意字符)
现在,观察如下方程式,
12n = p * qy ** 2 = x ** 3 + a * x + b mod(n)
其中 y,a,b已知,根据常规方程我们是无法求出x的解的,因为对于第二个方程,我们未知的变量有x和n,单个方程无法解决二元变量求解问题,因此我们需要将改方程转换到模n多 ...
Crypto-格初识
一、格的概述
格是离散的Rn加子群。每个格都是一些线性无关的向量产生的集合,称之为基。
二、格基规约任意格都有无数个基,LLL 算法就是在格上找到一组基:其长度尽可能最小,并于基中其他矢量尽可能正交。即对应方程组中找到一组满足等式的最优解。
规约算法过程太过复杂,此处省略。。。
三、格基规约简单使用1.对二元单方程的求解题目:
12t = 44,P,Q已知,求解p,qt=(p*P-58*P+q)%Q
格的构造:
LLL规约:
12345678M = Matrix(ZZ, [[1, P], [0, Q]]) //在ZZ整数环上定义一个二维矩阵[[1,P],[0,Q]]v = M.LLL()[0] //LLL规约p, q = -vp = p + 58q = -q + 44
2.求解矩阵相乘运算中某一未知矩阵题目描述
题目基于矩阵乘法AM=C,其中这三个均为n×n方阵,M为消息矩阵且较小。
给出矩阵C,并且将A中的随机n个元素毁坏,得到Ac并给出。
试求M。
题目分析:
M为消息矩阵且较小,这意味着我们或许可以 ...
Crypto-DSA非对称加密
一、数字签名
二、DSA介绍DSA是用于数字签名的算法,基于模算数和离散对数的复杂度。DSA是Schnorr和ElGamal签名方案的变体。
DSA 算法包含了四种操作:密钥生成、密钥分发、签名、验证
1、密钥生成密钥生成包含两个阶段。第一阶段是算法参数的选择,可以在系统的不同用户之间共享,而第二阶段则为每个用户计算独立的密钥组合。
2、密钥分发签名者需要透过可信任的管道发布公钥 y,并且安全地保护 x 不被其他人知道。
3、签名流程
4、验证签名
三、DSA解密1.已知 k:如果知道了随机密钥 k,那么我们就可以根据
s ≡ (H(m)+xr)k−1modq 计算私钥 x。
这里一般情况下,消息的 hash 值都会给出。
x≡r−1(ks−H(m))modq
2.k 共享如果在两次签名的过程中共享了 k,我们就可以进行攻击。
假设签名的消息为 m1,m2,显然,两者的 r 的值一样,此外
s1≡(H(m1)+xr)k−1modq
s2≡(H(m2)+xr)k−1modq
这里我们除了 x 和 k 不知道剩下的均知道,那么
s1k≡H(m1)+xr
s2k≡H(m2)+xr
两式相减 ...
Crypto-rsa因子相近解析
RSA因子相近分析:我们假定 n = p * q
如果q和p很相近,一般表示为:
123p = getPrime(512)q = gmpy2.next_prime(p)n = p * q
对于这种形式,应该怎么去分析呢?
首先,第一种方法,可以通过yafu分解,yafu分解适用于p,q相近或相差很大时。
直接使用yafu工具分解即可。
除此之外,还有什么方法能求出p和q呢?
没错,就是爆破~~~~
这里讲以下爆破流程:
12345678910111213def factor(n): factor_list = [] a,f = iroot(n,2) while(True): a += 1 try: b,f = iroot(a*a - n, 2) except: pass if f: # b*b == a*a - n return a-b,a+b
爆破原理:
a首先好说,a是n的整数平方根,这很好理解,但是b的产生是什么鬼?其中还有个令人费解的式 ...
Crypto-sagemath常用函数
常用sagemath函数(代数系统篇)1.同余运算1R.<x> = Zmod(module)[]
其中,x作为求解的未知数,module表示同余的模数。
12f = x^3 + ... //将所有式移到f右边f.roots()
例题:
需要求解
n ≡ p ^3 + a ∗ p ^ 2 + b ∗ p (mod n)
那么在sage中写
123R.<p> = Zmod(moudle)f = p^3 + a*p^2 + b*p - n^2 f.roots()
那么p的所有满足该同余式的解就会返回出来
2.有限域2.1 P元有限域有限域 p7 (所有模7的完全剩余类)
1k1=GF(7)
操作有限域上的元素
123a=k1(5)print(a,a^6,a^-1)#5 1 3
求解x ** 5 ≡ 2(mod7)
12print(k1(2).nth_root(5))# 4