Dragon CTF 2018 Fast Storage Writeup
周末随意看了 Dragon CTF 2018 的题,主要看了两个 Pwn。两个都挺有意思的,但是这个题有个冷门知识。所以想稍微记录下。
0x01 abs(0x8000000) == 0x8000000
首先,我们先了解下 abs
这个函数。
1 | NAME |
我们可以知道, abs 返回的参数是 inter。
我们也知道 inter 的范围如下表:
类型 | 字节 | 范围 |
---|---|---|
short int | 2byte(word) | 0 |
unsigned short int | 2byte(word) | 0 |
int | 4byte(dword) | 0 |
unsigned int | 4byte(dword) | 0 |
long int | 8byte(qword) | 正: 0 |
unsigned long int | 8byte(qword) | 0~0xffffffffffffffff |
int 的表示范围为 02147483647(00x7fffffff) -2147483648-1(0x800000000xffffffff) , 以 常理而言, abs
这个取绝对值的函数,返回的应该是正数吧…
然后这里的 asb(0x80000000) == 0x80000000 这是为什么? (inter : 0x80000000 == -2147483648)
**Why? **
单纯从二进制来看:
bin(0x80000000)
‘0b10000000000000000000000000000000’
0x80000000 == 10000000000000000000000000000000
但是 32bit的 整型数实际上只以 31 位表示,最高位表示符号。换一句话说,0x80000000 溢出,覆盖到了 符号位。在 32bit 整型中,如果是负整数的话,则要将后面的31个二进制位取反加1之后才是其绝对值。
换一句话说 ~0 +1 == 0 。那么 abs(0x8000000)==0x8000000 并不是没有道理。
0x02 利用思路
1 | _DWORD *__fastcall calculation(__int64 data, __int64 value) |
如果 abs(v1 ) 返回 0x8000000 ,那么取模后, v4 的值实际上等于 -2
1 | .bss:0000555555756040 ; _DWORD name_arrary[64] |
这样我们可以 bitmap 和 list 重合。
0x3 code exploit
首先,我们得先得到一个 0x8000000。
1 |
|
所以,我这里字符串 取 \xa1\xf8\xe6\xa9
剩下的利用 参考 https://xz.aliyun.com/t/2831#toc-2