1.栈溢出
通过栈溢出修改局部变量
修改函数返回地址
缓冲区溢出执行代码植入
2.shellcode:用来统称缓冲区溢出攻击的植入代码
2.1 exploit:针对特定漏洞开发的代码,关心如何淹没返回地址,获取进程的控制权
2.2 使用jmp esp覆盖对应的返回地址,使用jmp esp 相当于将eip的值设置成esp的值,由于esp寄存器在函数返回之后不会被溢出数据所干扰,且始终指向放回地址之后的位置(由于esp在返回时仍然指向栈区,jmp esp之后,处理器会返回到栈区函数返回地址之后的地方)。以我们可以通过跳板的方法动态定位shellcode。可以不止shellcode在淹没函数返回地址之后,继续淹没一片栈空间,将缓冲区前边一段地方的数据用任意数据填充,把shellcode恰好摆在返回地址之后,这样jmp esp指令执行之后会恰好跳进shellcode(缓冲区溢出没有修改过esp的值).
2.2 缓冲区的组织一般使用x09090来填充缓冲区,即使不能跳转到正确的位置,跳转到nop指令也能正常执行到shellcode处,淹没返回地址的数据,跳转指令的地址,shellcode的地址,还可以是一个近似的地址。把shellcode布置在缓冲区之后就不用担心被压栈数据破坏。可以通过抬高栈顶保护shellcode.
2.3可以使用其它跳转指令,比如mov eax,esp ;jmp eax等指令也可以进入,也可以不使用跳转指令,增大shellcode面积,提高命中率。
2.4 shellcode编码:有时候shellcode会受到限制,首先字符串会对null字节进行限制其次函数还要求所有的shellcode 必须为可见的ascll字符或者unicode字符,基于特征的ids(入侵检测)也会对shellcode进行检查,先精心设计逻辑,然后对shellcode进行编码,使其内容达到限制要求。
3.漏洞测试平台msf(metasploit frame work)简介
触发漏洞,选取shellcode,重要参数设定,选用编码,解码算法。msf时一种框架,它对漏洞利用几个相对独立的过程进行了很好的封装,把一次入侵过程简化为多若干模块的选择与组装,对各个环节进行了封装,模块化,标准化。
4.堆溢出利用
4.1 堆与栈的区别:
栈空间由系统维护,栈变量在使用的时候不需要额外的申请系统。堆是在运行的时候动态分配的。用堆指针来操作申请得到相应的堆空间,使用完成后要释放相应的堆,否则会造成内存泄露。
4.2 堆溢出的利用
double shoot技术:利用精心构造的数据取溢出下一个堆块的块首,改写块首中前向指针和后向指针,然后再分配,释放,合并等操作发生时获得一次向内存任意地址写入任意数的机会。把向任意地址写入任意数据的机会称为dword shoot,不但可以控制相应的目标,还可以劫持进程,运行shellcode.
常用的目标:内存变量,代码逻辑,函数返回地址,攻击异常处理机制,函数指针,peb线程同步函数入口地址
5.SEH
由于seh在栈内,可以溢出缓冲区的数据有可能淹没seh,把seh构造为shellcode的起始地址,溢出后的栈帧或者堆块可能发生异常。当触发异常的时候就会把shellcode当作异常处理函数执行,异常处理和堆分配机制类似,会检测进程是否处于调试状态,如果直接使用调试器加载程序,异常处理会进入调试状态下的处理流程。主要关键步骤就是确定栈中的seh回调句柄的偏移,然后布置缓冲区,精确淹没这个地址,将该句柄改为shellcode的起始地址。
也可以利用堆溢出攻击将seh异常处句柄改为shellcode地址。也可以攻击peb中的函数指针。exitprocess()是利用通过存放在peb中的一对指针来调用
这两个函数的,如果能够把peb中的这对指针改成shellcode入口地址,那么程序最终结束的时候,exitprocess()将启动。
6.攻击c++虚函数
虚函数的虚表
1.成员函数用virtual声明的时候称为虚函数,一个类中可以有多个虚函数,虚函数的入口地址保存在虚标中,使用虚函数的时候先通过虚标指针找到虚表,从虚表中取出最终的函数入口地址进行调用。虚表指针保存在对象内存空间终,紧接虚标指针的是其它成员变量,虚表指针只有通过对象的指针引用才能表现出它的动态调用的特性,如果对象变量发生了溢出,有机会修改对象终的虚表指针或者修改虚标中的虚函数指针,那么在程序调用虚函数的时候就会跑去执行shellcode。由于虚标在成员函数之前,溢出只能向后修改数据,所以这种方式在“栈溢出”场景种有一定的局限性。对象内容空间位于队中。如果存在多个对象连续覆盖还是有机会的,对于堆溢出的double shoot的利用场景攻击虚函数会相对更加容易一些,修改虚标指针或者直接修改虚函数指针都是一个不错的选择。
7.堆喷雾 heap spray:堆栈协同攻击
溢出的最终目标就是要能够获得eip,在使用heap spray的的hi后,一般会将eip指向堆区0x0c0c0c0c位置,然后用javascript申请大量的堆内存,并且用包含着0x90和shellcode的内存片覆盖这些内存。通常,javascript会从内存低地址向高地址分配内存,申请超过200M的内存后,0x0c0c0c0c机会被含有shellcode的内存片覆盖,只要内存片种的0x90能够命中0x0c0c0c0c的位置,shellcode就能够得到执行。200MB=200*1024*1024=0x0c800000>0x0c0c0c0c0),我们构造相应的内存片来覆盖内存,用200个这样的内存片来覆盖堆内存,只要其中任意一片nop区域能够覆盖0x0c0c0c0c,攻击就可以成功。
8.格式化字符串漏洞
如果printf种的格式控制符可以被外界输入影响,就是所谓的格式化字符串漏洞了格式控制符号%n这个控制符号可以把当前输出的数据长度写回一个变量中。
格式化字符串漏洞的防范:当输入输出的格式化控制符能够被外界所影响的时候,攻击者可以综合利用前面的内存读写方式修改函数的返回地址,劫持进程从而使得shellcode得到执行。可以引起这种漏洞的函数有,printf,wprintf,fprintf,swprintf,sprintf,swprintf,vpringf,vwprintf,vfprintf,vfwprintf,vsprintf,vswprintf.
9.GS(great stack)
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2019-2-28 09:45
被wwzzww编辑
,原因: