网络安全作业5

得分:10/10

C程序homework08.c的主函数如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
int main(int argc, char * argv[]) {
init_buf(Lbuffer, LEN);
switch(argc)
{
case 1: f00(); break;
case 2: f01(); break;
case 3: f02(); break;
default: f00(); break;
}
puts("Done.\nThe program exited normally.");
return 0;
}
  • 在32位的ubuntu16.04系统中用gcc -fno-stack-protector 编译该程序,得到的可执行程序见附件,通过gdb调试,对f00()、f01()和f02()进行分析:

(1) 函数f00()、f01()和f02()是否导致段错误。

  • 如果没有命令行参数(argc 等于 1,因为程序名本身也算一个参数),则执行函数 f00()。
  • 如果有一个命令行参数(argc 等于 2),则执行函数 f01()。
  • 如果有两个命令行参数(argc 等于 3),则执行函数 f02()。
  • 如果有三个或更多的命令行参数,还是执行函数 f00()。 ![[Pasted image 20231122231415.png]]

函数foo(), 和 foo01() 都会导致段错误。

如果函数f00()、f01()和f02()导致段错误,计算出被攻击的缓冲区首地址与函数的返回地址所在的栈地址的距离(即偏移OFFSET),给出溢出后函数的返回地址(用16进制数表示)。

f00()

![[Pasted image 20231121150016.png]]

image

打断点 image

image

函数入口处的堆栈指针esp指向的栈(地址为0xffffd1dc)保存了 函数f00()返回到调用函数(main)的地址(0x080485a8),即“函数的返回地址”

记录堆栈指针esp的值,在此以A标记:A=$esp = 0xffffd1dc

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
(gdb)  x/x $esp
0xffffd1dc:     0x080485a8
(gdb) c
Continuing.

Breakpoint 2, 0x080484e9 in f00 ()
1: x/i $eip
=> 0x80484e9 <f00+24>:  call   0x8048320 <strcpy@plt>
(gdb) x/x $esp
0xffffd140:     0xffffd155
(gdb) 
0xffffd144:     0x0804a060
(gdb) x/x 0x0804a060
0x804a060 <Lbuffer>:    0x44434241

令B = 0xffffd155,则offset=A-B=0xffffd1dc - 0xffffd155 =0x87=135

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
(gdb) c
Continuing.

Breakpoint 3, 0x080484f3 in f00 ()
1: x/i $eip
=> 0x80484f3 <f00+34>:  ret    
(gdb) x/x $esp
0xffffd1dc:     0x49484746
(gdb) x/s $esp
0xffffd1dc:     "FGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVW"...

执行ret之前的堆栈的内容可以推断执行ret后将跳到地址0x49484746去执行

f01

执行程序

1
azureuser@MyServer:~/hw$ gdb homework08

main

 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
(gdb) disas main
Dump of assembler code for function main:
   0x0804856c <+0>:     lea    0x4(%esp),%ecx
   0x08048570 <+4>:     and    $0xfffffff0,%esp
   0x08048573 <+7>:     pushl  -0x4(%ecx)
   0x08048576 <+10>:    push   %ebp
   0x08048577 <+11>:    mov    %esp,%ebp
   0x08048579 <+13>:    push   %ebx
   0x0804857a <+14>:    push   %ecx
   0x0804857b <+15>:    mov    %ecx,%ebx
   0x0804857d <+17>:    sub    $0x8,%esp
   0x08048580 <+20>:    push   $0x400
   0x08048585 <+25>:    push   $0x804a060
   0x0804858a <+30>:    call   0x804846b <init_buf>
   0x0804858f <+35>:    add    $0x10,%esp
   0x08048592 <+38>:    mov    (%ebx),%eax
   0x08048594 <+40>:    cmp    $0x2,%eax
   0x08048597 <+43>:    je     0x80485aa <main+62>
   0x08048599 <+45>:    cmp    $0x3,%eax
   0x0804859c <+48>:    je     0x80485b1 <main+69>
   0x0804859e <+50>:    cmp    $0x1,%eax
   0x080485a1 <+53>:    jne    0x80485b8 <main+76>
   0x080485a3 <+55>:    call   0x80484d1 <f00>
   0x080485a8 <+60>:    jmp    0x80485be <main+82>
   0x080485aa <+62>:    call   0x80484f4 <f01>
   0x080485af <+67>:    jmp    0x80485be <main+82>
   0x080485b1 <+69>:    call   0x8048530 <f02>
   0x080485b6 <+74>:    jmp    0x80485be <main+82>
   0x080485b8 <+76>:    call   0x80484d1 <f00>
   0x080485bd <+81>:    nop
   0x080485be <+82>:    sub    $0xc,%esp
   0x080485c1 <+85>:    push   $0x8048660
   0x080485c6 <+90>:    call   0x8048330 <puts@plt>
   0x080485cb <+95>:    add    $0x10,%esp
   0x080485ce <+98>:    mov    $0x0,%eax
   0x080485d3 <+103>:   lea    -0x8(%ebp),%esp
   0x080485d6 <+106>:   pop    %ecx
   0x080485d7 <+107>:   pop    %ebx
   0x080485d8 <+108>:   pop    %ebp
   0x080485d9 <+109>:   lea    -0x4(%ecx),%esp
   0x080485dc <+112>:   ret    
End of assembler dump.

f01()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
(gdb) disas f01
Dump of assembler code for function f01:
   0x080484f4 <+0>:     push   %ebp
   0x080484f5 <+1>:     mov    %esp,%ebp
   0x080484f7 <+3>:     sub    $0x508,%esp
   0x080484fd <+9>:     sub    $0x8,%esp
   0x08048500 <+12>:    push   $0x400
   0x08048505 <+17>:    lea    -0x4fe(%ebp),%eax
   0x0804850b <+23>:    push   %eax
   0x0804850c <+24>:    call   0x804846b <init_buf>
   0x08048511 <+29>:    add    $0x10,%esp
   0x08048514 <+32>:    sub    $0x8,%esp
   0x08048517 <+35>:    lea    -0x4fe(%ebp),%eax
   0x0804851d <+41>:    push   %eax
   0x0804851e <+42>:    lea    -0xfe(%ebp),%eax
   0x08048524 <+48>:    push   %eax
   0x08048525 <+49>:    call   0x8048320 <strcpy@plt>
   0x0804852a <+54>:    add    $0x10,%esp
   0x0804852d <+57>:    nop
   0x0804852e <+58>:    leave  
   0x0804852f <+59>:    ret    
End of assembler dump.

设置断点

1
2
3
4
5
6
(gdb) b*(f01+0)
Breakpoint 1 at 0x80484f4
(gdb) b*(f01+49)
Breakpoint 2 at 0x8048525
(gdb) b*(f01+59)
Breakpoint 3 at 0x804852f
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
(gdb) display/i $eip
1: x/i $eip
<error: No registers.>
(gdb) x/i $eip
No registers.
(gdb) run 1
Starting program: /home/azureuser/hw/homework08 1

Breakpoint 1, 0x080484f4 in f01 ()
1: x/i $eip
=> 0x80484f4 <f01>:     push   %ebp
(gdb) x/x $esp
0xffffd1cc:     0x080485af

记录堆栈指针esp的值,在此以A标记:A=$esp = 0xffffd1cc

继续执行到下一个断点

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
(gdb) c
Continuing.

Breakpoint 2, 0x08048525 in f01 ()
1: x/i $eip
=> 0x8048525 <f01+49>:  call   0x8048320 <strcpy@plt>
(gdb) x $esp
0xffffccb0:     0xffffd0ca
(gdb) 
0xffffccb4:     0xffffccca
(gdb) x/x 0xffffccca
0xffffccca:     0x44434241

B=0xffffd0ca。

offset=A-B= 0xffffd1cc - 0xffffd0ca =0x102=258

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
(gdb) c
Continuing.

Breakpoint 3, 0x0804852f in f01 ()
1: x/i $eip
=> 0x804852f <f01+59>:  ret    
(gdb) x/x $esp
0xffffd1cc:     0x42415a59
(gdb) x/s $esp
0xffffd1cc:     "YZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOP"...
(gdb) si
0x42415a59 in ?? ()
1: x/i $eip
=> 0x42415a59:  <error: Cannot access memory at address 0x42415a59>
(gdb) x/s $esp
0xffffd1d0:     "CDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRST"...

返回地址变 为 0x42415a59

其他(本次实验的一些其它尝试)

  1. 由于这个可执行文件是ubuntu16.04编译的,本身我的虚拟机系统是ubuntu18.04,一开始执行文件老是报错:
1
2
~$ ./homework08 
-bash: ./homework08: No such file or directory

查询之后发现不是文件不存在,是缺少需要的依赖,因为Ubuntu18.04默认去掉了32bit的library。

解决方法

1
sudo apt-get install lib32z1

之后就可以执行了。

  1. 本身自己的电脑是mac m2芯片,一开始没尝试使用虚拟机而是docker在容器内去pull ubuntu的镜像来尝试实验:% docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -it --platform linux/386 -v "/Users/agq/Downloads/srcToStudent:/srcToStudent" --name=hw6 i386/ubuntu /bin/bash

发现能运行文件,并且可以显示段错误:

但由于qemu天生不支持ptrace系统调用,而gdb正是依赖这个系统调用,所以无法进行调试(QEMU’s user-mode emulation does not support the ptrace system call)所以第二题就做不了,遂作罢。