灰帽黑客 第二章 编程技能
本章主要介绍了一些先修知识,思维导图如下
c和Python大家应该都不陌生,我主要学习记录下中间部分的笔记和感受
计算机内存
稍微解释下shellcode
shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制的机器码,因为经常让攻击者获得shell而得名。shellcode常常使用机器语言编写。
可在暂存器eip溢出后,塞入一段可让CPU执行的shellcode机器码,让电脑可以执行攻击者的任意指令。
缓冲区溢出的详解可以参看[2],这本书后面章节貌似也很会介绍,到时候再补上。(*^_^*)
Intel处理器
主要介绍处理器内常用的寄存器
汇编语言基础
这个在计算机体系结构与计算机系统还有一些其他的课,如嵌入式系统,并行计算系统中都有提到与学习,我就不仔细地列指令了。就列下以前就觉得有问题但是一直没有解决的
如
mov eax,12h ----->(1) movl $12h,%eax ------>(2)
(1)(2)都是对的,以前总是很迷,因为不知道为什么源操作数和目的操作数的位置不一样,而当时也不求甚解....菜鸡+懒逼无疑了....
为什么呢?因为汇编语法主要有两种形式:AT&T和Intel,而他们的目的操作数和源操作数位置完全不同。
AT&T
主要由GNU汇编器(GAS,包含在gcc编译器套件之中)使用,Linux开发人员常用此形式
Intel
采用Intel语法形式的汇编器之中,最常用的是NASM,常用于Windows,虽然这两种格式生成的机器语言完全相同,但在风格和格式上有些差异
不想打字了,直接拍照~
使用gdb进行调试
这个基本忘了....上次了解还是在计算机系统里.
调试一个非常简单的c程序
meet.c
#include<stdio.h> #include<string.h> void greeting(char* temp1,char* temp2) { char name[400]; strcpy(name,temp2); printf("Hello %s %s\n",temp1,name); } void main(int argc,char* argv[]) { greeting(argv[1],argv[2]); printf("Bye %s %s\n",argv[1],argv[2]); }
运行 gcc -ggdb -mpreferred-stack-boundary=2 -fno-stack-protector -o meet1 meet.c
其具体含义参看上面图中表2-3
但是我在ubuntu18.04 64位上报错
查原因[3]后发现,这是因为在64位计算机中,地址字段的宽度从4个字节增加到8个字节。因此,由于2 ^ 2 = 4个字节,它无法在堆栈边界= 2处写入单个块。其默认值为4,即在2^4=16字节,每个函数在输入后立即将其堆栈指针对准16字节边界
运行 gcc -ggdb -mpreferred-stack-boundary=4 -fno-stack-protector -o meet1 meet.c
生成mee1,
运行
gdb -q ./meet1 //-q代表不输出提示信息 Reading symbols from ./meet1...done. (gdb) run csz cy //使用给定参数开始调试程序 Starting program: /home/hadoop/桌面/MPI/meet1 csz cy Hello csz cy Bye csz cy [Inferior 1 (process 5959) exited with code 013] (gdb) b main //设置断点 Breakpoint 1 at 0x5555555546f0: file meet.c, line 12. (gdb) run csz cy Starting program: /home/hadoop/桌面/MPI/meet1 csz cy Breakpoint 1, main (argc=3, argv=0x7fffffffde28) at meet.c:12 12 greeting(argv[1],argv[2]); (gdb) n //单步运行,若调用函数也直接运行完成,若是s则会进入调用函数内 Hello csz cy 13 printf("Bye %s %s\n",argv[1],argv[2]); (gdb) n Bye csz cy 15 }(gdb) p argv[1] //打印参数值 $1 = 0x7fffffffe1d8 "csz" (gdb) p argv[2] $2 = 0x7fffffffe1dc "cy" (gdb) p argc $3 = 3 (gdb) info b //输出断点信息 Num Type Disp Enb Address What 1 breakpoint keep y 0x00005555555546f0 in main at meet.c:12 breakpoint already hit 1 time (gdb) info reg //查看寄存器值 rax 0xb 11 rbx 0x0 0 rcx 0x0 0 rdx 0x0 0 rsi 0x555555756260 93824994337376 rdi 0x1 1 rbp 0x7fffffffdd40 0x7fffffffdd40 rsp 0x7fffffffdd30 0x7fffffffdd30 r8 0x0 0 r9 0x2 2 r10 0xfffffffe 4294967294 r11 0x246 582 r12 0x555555554580 93824992232832 r13 0x7fffffffde20 140737488346656 r14 0x0 0 r15 0x0 0 rip 0x55555555473b 0x55555555473b <main+90> eflags 0x206 [ PF IF ] cs 0x33 51 ss 0x2b 43 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0
使用gdb进行反汇编
set disassembly-flavor <intel/att> //选择汇编代码格式,默认使用AT&T disassemble <function name> //反汇编指定函数
运行实例
hadoop@shun-virtual-machine:~/桌面/MPI$ gdb -q ./meet1 Reading symbols from ./meet1...done. (gdb) disassemble greeting Dump of assembler code for function greeting: 0x000000000000068a <+0>: push %rbp 0x000000000000068b <+1>: mov %rsp,%rbp 0x000000000000068e <+4>: sub $0x1a0,%rsp 0x0000000000000695 <+11>: mov %rdi,-0x198(%rbp) 0x000000000000069c <+18>: mov %rsi,-0x1a0(%rbp) 0x00000000000006a3 <+25>: mov -0x1a0(%rbp),%rdx 0x00000000000006aa <+32>: lea -0x190(%rbp),%rax 0x00000000000006b1 <+39>: mov %rdx,%rsi 0x00000000000006b4 <+42>: mov %rax,%rdi 0x00000000000006b7 <+45>: callq 0x550 <strcpy@plt> 0x00000000000006bc <+50>: lea -0x190(%rbp),%rdx 0x00000000000006c3 <+57>: mov -0x198(%rbp),%rax 0x00000000000006ca <+64>: mov %rax,%rsi 0x00000000000006cd <+67>: lea 0xf0(%rip),%rdi # 0x7c4 0x00000000000006d4 <+74>: mov $0x0,%eax 0x00000000000006d9 <+79>: callq 0x560 <printf@plt> 0x00000000000006de <+84>: nop 0x00000000000006df <+85>: leaveq 0x00000000000006e0 <+86>: retq End of assembler dump. (gdb) set disassembly-flavor intel (gdb) disassemble greeting Dump of assembler code for function greeting: 0x000000000000068a <+0>: push rbp 0x000000000000068b <+1>: mov rbp,rsp 0x000000000000068e <+4>: sub rsp,0x1a0 0x0000000000000695 <+11>: mov QWORD PTR [rbp-0x198],rdi 0x000000000000069c <+18>: mov QWORD PTR [rbp-0x1a0],rsi 0x00000000000006a3 <+25>: mov rdx,QWORD PTR [rbp-0x1a0] 0x00000000000006aa <+32>: lea rax,[rbp-0x190] 0x00000000000006b1 <+39>: mov rsi,rdx 0x00000000000006b4 <+42>: mov rdi,rax 0x00000000000006b7 <+45>: call 0x550 <strcpy@plt> 0x00000000000006bc <+50>: lea rdx,[rbp-0x190] 0x00000000000006c3 <+57>: mov rax,QWORD PTR [rbp-0x198] 0x00000000000006ca <+64>: mov rsi,rax 0x00000000000006cd <+67>: lea rdi,[rip+0xf0] # 0x7c4 0x00000000000006d4 <+74>: mov eax,0x0 0x00000000000006d9 <+79>: call 0x560 <printf@plt> 0x00000000000006de <+84>: nop 0x00000000000006df <+85>: leave 0x00000000000006e0 <+86>: ret End of assembler dump.
gdb调试技巧可以看这个大佬的blog[4]
[1]https://baike.baidu.com/item/shellcode/4051847?fr=aladdin
[2]https://www.cnblogs.com/clover-toeic/p/3737011.html
[3]https://stackoverflow.com/questions/10251203/gcc-mpreferred-stack-boundary-option
[4]https://www.cnblogs.com/Forever-Kenlen-Ja/p/8631663.html