0%

复习基础

复习基础

挖过什么洞

  1. sql注入, 二次注入,万能密码,sql盲注,报错注入
  2. 文件上传 php的站
  3. 破过挺多软件的,逻辑洞.
  4. 信息泄露
  5. xss

断点

  1. int3 断点(将指令改成0xCC) 当调试进程执行到int3 导致异常,调试器捕获异常
  2. 硬件断点(DR寄存器) DR0-DR3是可以控制的,DR4-DR5保留, DR6 组状态,DR7组控制
  3. 内存断点 设置不可访问,不可写属性,当写入访问就会产生异常
  4. 消息断点 根据window消息机制断下

硬件断点可以设置在任何位置

普通软件断点用于代码段

脱壳

esp定律

特征:

  1. pushad
  2. popad

pushad过后跟随esp下硬件访问断点,,运行单步几步就可以追到oep

原理: pushad过后要还原堆栈的时候便是oep了

单步

一直单步,到popad注意是否要到oep了

两次断点

设置od忽略所有异常

  1. .rsrc下断点
  2. .text段下断
  3. 单步

image-20200413163303497

image-20200413163422895

最后一次异常法

不要忽略异常,shift+f9运行,最后一次异常单步跟踪

sfx

设置sfx停在真正入口处

模拟跟踪

利用两次断点,在进行跟踪

tc eip < sfx

出口标志

搜索popad,然后单步

看段首,段位尾,段首反汇编跟随,往上跟下硬件断

模块删除分析,找到第一个对应壳名的地址

绕过aslr

  1. jmp esp
  2. partial write
  3. 攻击未启用aslr的模块
  4. heap spray

pe文件复习

输入表

加载其它dll的代码或者数据的动作称为输入

IAT会被PE加载器重写,INT只做寻址用,写完后就用不上了

加密算法

单向散列算法

  • md5
  • sha-1, sha-256, sha-512,sha-34

sm3

对称加密算法

rc4,tea,idea,aes,sm4分组

公开密钥加密算法

rsa, dsa,椭圆曲线

其它

crc32, base64

操作系统

分页跟分段

页和分段系统有许多相似之处,但在概念上两者完全不同,主要表现在:

1、页是信息的物理单位,分页是为实现离散分配方式,以消减内存的外零头,提高内存的利用率;或者说,分页仅仅是由于系统管理的需要,而不是用户的需要。

段是信息的逻辑单位,它含有一组其意义相对完整的信息。分段的目的是为了能更好的满足用户的需要。

2、页的大小固定且由系统确定,把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的,因而一个系统只能有一种大小的页面。

段的长度却不固定,决定于用户所编写的程序,通常由编辑程序在对源程序进行编辑时,根据信息的性质来划分。

3、分页的作业地址空间是维一的,即单一的线性空间,程序员只须利用一个记忆符,即可表示一地址。

分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。

页面置换算法

1 先入先出法(FIFO)

最简单的页面置换算法是先入先出(FIFO)法。这种算法的实质是,总是选择在主存中停留时间最长(即最老)的一页置换,即先进入内存的页,先退出内存。理由是:最早调入内存的页,其不再被使用的可能性比刚调入内存的可能性大。建立一个FIFO队列,收容所有在内存中的页。被置换页面总是在队列头上进行。当一个页面被放入内存时,就把它插在队尾上。

这种算法只是在按线性顺序访问地址空间时才是理想的,否则效率不高。因为那些常被访问的页,往往在主存中也停留得最久,结果它们因变“老”而不得不被置换出去。

FIFO的另一个缺点是,它有一种异常现象,即在增加存储块的情况下,反而使缺页中断率增加了。当然,导致这种异常现象的页面走向实际上是很少见的。

2 最优置换算法(OPT)

最优置换(Optimal Replacement)是在理论上提出的一种算法。其实质是:当调入新的一页而必须预先置换某个老页时,所选择的老页应是将来不再被使用,或者是在最远的将来才被访问。采用这种页面置换算法,保证有最少的缺页率。

但是最优页面置换算法的实现是困难的,因为它需要人们预先就知道一个进程整个运行过程中页面走向的全部情况。不过,这个算法可用来衡量(如通过模拟实验分析或理论分析)其他算法的优劣。

3 最久未使用算法(LRU)

FIFO算法和OPT算法之间的主要差别是,FIFO算法利用页面进入内存后的时间长短作为置换依据,而OPT算法的依据是将来使用页面的时间。如果以最近的过去作为不久将来的近似,那么就可以把过去最长一段时间里不曾被使用的页面置换掉。它的实质是,当需要置换一页时,选择在最近一段时间里最久没有使用过的页面予以置换。这种算法就称为最久未使用算法(Least Recently Used,LRU)。

LRU算法是与每个页面最后使用的时间有关的。当必须置换一个页面时,LRU算法选择过去一段时间里最久未被使用的页面。

LRU算法是经常采用的页面置换算法,并被认为是相当好的,但是存在如何实现它的问题。LRU算法需要实际硬件的支持。其问题是怎么确定最后使用时间的顺序,对此有两种可行的办法:

(1)计数器。最简单的情况是使每个页表项对应一个使用时间字段,并给CPU增加一个逻辑时钟或计数器。每次存储访问,该时钟都加1。每当访问一个页面时,时钟寄存器的内容就被复制到相应页表项的使用时间字段中。这样我们就可以始终保留着每个页面最后访问的“时间”。在置换页面时,选择该时间值最小的页面。这样做,不仅要查页表,而且当页表改变时(因CPU调度)要维护这个页表中的时间,还要考虑到时钟值溢出的问题。

(2)栈。用一个栈保留页号。每当访问一个页面时,就把它从栈中取出放在栈顶上。这样一来,栈顶总是放有目前使用最多的页,而栈底放着目前最少使用的页。由于要从栈的中间移走一项,所以要用具有头尾指针的双向链连起来。在最坏的情况下,移走一页并把它放在栈顶上需要改动6个指针。每次修改都要有开销,但需要置换哪个页面却可直接得到,用不着查找,因为尾指针指向栈底,其中有被置换页。

因实现LRU算法必须有大量硬件支持,还需要一定的软件开销。所以实际实现的都是一种简单有效的LRU近似算法。

一种LRU近似算法是最近未使用算法(Not Recently Used,NUR)。它在存储分块表的每一表项中增加一个引用位,操作系统定期地将它们置为0。当某一页被访问时,由硬件将该位置1。过一段时间后,通过检查这些位可以确定哪些页使用过,哪些页自上次置0后还未使用过。就可把该位是0的页淘汰出去,因为在最近一段时间里它未被访问过。

4 第二次机会算法(SCR)

第二次机会算法的基本思想是与FIFO相同的,但是有所改进,避免把经常使用的页面置换出去。当选择置换页面时,检查它的访问位。如果是0,就淘汰这页;如果访问位是1,就给它第二次机会,并选择下一个FIFO页面。当一个页面得到第二次机会时,它的访问位就清为0,它的到达时间就置为当前时间。如果该页在此期间被访问过,则访问位置1。这样给了第二次机会的页面将不被淘汰,直至所有其他页面被淘汰过(或者也给了第二次机会)。因此,如果一个页面经常使用,它的访问位总保持为1,它就从来不会被淘汰出去。

第二次机会算法可视为一个环形队列。用一个指针指示哪一页是下面要淘汰的。当需要一个存储块时,指针就前进,直至找到访问位是0的页。随着指针的前进,把访问位就清为0。在最坏的情况下,所有的访问位都是1,指针要通过整个队列一周,每个页都给第二次机会。这时就退化成FIFO算法了。

页面置换算法还有很多变种,如考虑到被置换页是否修改过、按FIFO算法选中的页正在使用等情况,都需要硬件、软件协同实现。

Hook

IAT Hook

修改IAT表进行hook

Inline Hook

修改函数内部代码进行Hook

Hook分类

Address Hook

  1. PE的IAT表 导入表
  2. PE的EAT 输出表 输入表存放的是函数偏移, 使用需要加上模块基地址
  3. user32.dll的回调函数表
  4. IDT系统的中断描述符表
  5. SSDT(系统服务描述符表)和Shadow SSDT
  6. C++ 虚表
  7. COM接口的功能函数表

Inline Hook

  1. jmp xxx(5字节)
  2. push xxx/retn(6字节)
  3. mov eax, xxx/jmp eax
  4. call hook
  5. HotPatch hook

基于异常处理的Hook

SEH

hook位置挑选

早期的各类安全软件是Hook SSDT和SSDT Shadow达到主动防御和自我保护的目的

dll注入

输入表

改变程序运行流程

CreateRemoteThread

  1. 目标进程中申请内存,写入dll路径
  2. 目标进程中创建一个线程, 线程函数地址为LoadLibraryA,参数存放DLL路径的内存指针
  3. 需要权限

由于会话隔离, 有检查,检查在原始进程用户层, CreateRemoteThreadEx函数所在KernelBase.dll中,可以Patch,或者进行Hook

RtlCreateUserThread

APC注入

APC(Asynchronous Procedure Call)异步过程调用, 当一个线程从等待状态中苏醒时,他会检测有没有APC交付给自己,如果有,就会执行

  1. 内核APC
  2. 用户模式APC

为增加机会,枚举所有线程, 向指定进程中的线程添加APC

SetThreadContext

线程暂停执行的时候会保存线程上下文环境, 当Resume线程的执行时候,会恢复上下文, 我们在暂停后修改线程的Context Eip设置为Shellcode

内核中通过Hook/Notify干预执行流程法

NtResumeThread为例, 线程恢复执行(创建或者被以前暂停),一样,写入Shellcode并修改Context, 使线程恢复时首先执行Shellcode

内核KeUserModeCallback

系统机制加载Dll

  1. SetWindowHookEx安装特定钩子函数
  2. 输入法注入
  3. 注册表注入

本文作者:NoOne
本文地址https://noonegroup.xyz/posts/af04c0f6/
版权声明:转载请注明出处!