Guide to (mostly) Harmless Hacking

Vol. 5 Programmers' Series

No. 3: More on Advanced Unix Shell Programming



by Meino Christian Cramer <
root@solfire.ludwigsburg.netsurf.de>



In this Guide you will discover examples of powerful batch files




Want to get rolling as a serious hacker? Try out these favorites from
Meino Christian Cramer. He uses them often, if something
goes wrong on his system, or if he wants to check some things...
He uses Linux, kernel version 2.1.102 (hacker kernel), but
the scripts are not that kernel relevant, so they should run on
every newer Linux system with bash shell installed.


You will find these especially useful if you decide to learn how to program
in C -- that's in the next Programmer's Series GTMHH!


If your favorite shell isn't the bash shell, and these scripts won't run on
your shell, you have three choices:
1.) Install bash instead, learn to use it and forget your
current shell (OK, it is a little bit drastically...)
2.) Install the bash shell and change the first line of
all scripts from


#!/bin/sh


to


#!/<wherever you have installed the bash>


3.) Change the syntax of the scripts from bash syntax to the syntax
of your favorite shell. This is not that hard, because most
of the work of the scripts is done by utilities and tools,
not by the scripts themselves.


First example:




(store this script as "llib")



#!/bin/sh
#
# This script shows you, which shared libraries are
# installed on your system and where to find them.
#
# usage: llib <part or the whole name of the library to find>
###########################################
if [ -z $i ]
then
echo "usage: llib <part or the whole name of the library to find>"
exit
fi


echo "----------------------------------------------------------"
ldconfig -p | grep -i $1
echo "----------------------------------------------------------"
for i in $( ldconfig -p | grep -i $1 | gawk '{ print $4 }' )
do
ls "$i"*
done | sort -u
echo "----------------------------------------------------------"



This script is tested with ldconfig version 1.9.6., GNU grep version 2.2,
GNU awk (gawk) version 3.03, sort version 1.14 and bash version 2.02.01. But
it should run also with older version of the utilities, except of ldconfig,
which may have no "-p" switch in older versions.


What happens when the script is called? The if construct checks whether
there is a argument given to the script. If it is missing, it prompts you a
little help and terminates gracefully.
If there is an argument, it takes it as the name or a part of the name of a
library, which will be stored in $1. "ldconfig -p" reports ALL shared
libraries, which are known by the system along with the paths, where they
are stored. This output, if piped though grep, looks for all lines
containing the given name of that library. The "-i" switches grep into
"ignore case" mode.


This is more convenient for all those X-related libraries, because they use
also uppercase letters in their names...



Newbie note: "X-related libraries are not dirty pictures. They are function
libraries for X-windows, which does for Unix systems what Windows does for
Unix. If you want point and click hacking, install a Unix type operating
system on your home computer and get X-windows running.




The output of grep (all lines containing the library name) are piped into
gawk, which filters all but the fourth argument (the path to the library and
the library name itself) out of the stream. Each line
of the finally resulting output is taken -- line by line -- by a
for-loop. For each looping $i contains one new line -- a path and the
library name -- which is take by "ls". There is a little trick at this line.


There is not only a

ls "$i"


There is also a


ls "$i"*


This is because they may be different versions of that library, which can
be listed by using ls "$i"*.


Finally the output of the loop is piped through "sort -u" which sorts the
output alphabetically and removes all identically lines. Therefore each line
is only reported once. The "-u" switch stands for "unique".


Next one!




(store this script as "ldprint"


#!/bin/sh
#
# prints all libraries used by a
# certain program
#
##############################
if [ -z $1 ]
then
echo "usage: ldprint <program to examine>"
exit
fi


ldd $(which $1)



This one is simple. It runs with the same versions of tools mentioned
above. Additionally: ldd is of version 1.9.6.. The version of "which" is
unknown to me, but this program is so "unspecial", that I think, all
versions should work.... :-)


What happens here? ldd reports all libraries, which are used by a certain
program. But! if you type


ldd emacs


This will not work in most cases, cause emacs is not in the current
directory. "ldd" will only work if the full path to the program
(emacs) is specified.


If you type


which emacs


It will print (for example)


/usr/X11R6/bin/emacs


Now! If you type


ldd which emacs


The shell cannot decide correctly what to call first: ldd, which, or emacs.
It decides: First is the tool, all further things are arguments to ldd.


Wrong!!!


This is why we have to give the shell a hint, a tip. Are we friendly
hackers? YES! OK,


The $(which $1) replace "which $1" with the result of the run of which,
removes the $( and the closing ) and THEN it will execute ldd. Now ldd
"sees" the full path, the call of which left behind.
But this is a more complicate thing. It is called "argument substitution"
and you should read more about it in the man pages of your shell.


Next? Next!



(store this script as "trace")


#!/bin/sh
#
# store all calls into the OS in a file
# and call an editor afterwards to examine
# the calls
#################################


fname=$(basename $1)
echo "----------------------------------------------------------------"
echo "writing trace to /tmp/TRACE-$fname/#tracefile.$fname"
echo "----------------------------------------------------------------"
rm -fr "/tmp/TRACE-$fname"
mkdir -p "/tmp/TRACE-$fname"
strace -ff -v -x -a 40 -o /tmp/TRACE-$fname/$fname $*
cd "/tmp/TRACE-$fname"
for i in $(ls [^\#]* )
do
echo
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" >> \
"/tmp/TRACE-$fname/#tracefile.$fname"
echo "$i" >> "/tmp/TRACE-$fname/#tracefile.$fname"
echo
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" >> \
"/tmp/TRACE-$fname/#tracefile.$fname"
cat $i >> "/tmp/TRACE-$fname/#tracefile.$fname"
gzip $i
done


if test $TERM="linux"
then
jed "/tmp/TRACE-$fname/#tracefile.$fname"
else
xjed "/tmp/TRACE-$fname/#tracefile.$fname"
fi


WARNING!!! This shell script only works if you are logged in as root. And
sometimes it fails for some (unknown) reasons. I have used strace version
3.1 for this one. Jed or the X-window version XJed are editors. All other
ASCII editors will also work. If your editor comes in a console and a
X-windows version, you first has to check the environment variable "$TERM".
Log in your box and start "X". Start a shell and type


echo "$TERM"


You will get something like "linux", "xterm" or so. please insert this in the


if test $TERM="linux"


Instead of the word "linux".


But let's start right from the beginning!


The first line calls a tool called "basename". This one strips off all
directory stuff from a fully specified path. Example: Type:


echo `basename /usr/local/bin/xterm`


And it will print


xterm


Got it? OK, the result of basename is stored into a variable called fname
(stands for "filename"). The echoes there print out some useful hints.
Then a FORCED and RECURSIVE call of rm (remove) is done to remove a previous
stored file of this script in /tmp/.



YOU CAN KILL YOUR SYSTEM - WARNING!
Be very careful here! This script only works if your are
logged in as root. And as root, you have "the right" to
delete ALL files of the system. If you mistype something,
for example you accidentally wrote


rm -rf / tmp/..........


instead of


rm -rf /tmp/......


the call of the script will kill your system in microseconds.
Better to insert a


rm -ir /tmp/.....
for testing the script. This will ask you for each file to delete,
before it is gone.





You can go to jail warning: This is a perfect example of why people don't
like strangers getting root on their computers! You may think you are
quietly sneaking around learning lots of stuff. Let's say you run this
script because you would like to trace system calls and YOU BLOW IT BIG
TIME. RM STAR CITY! The Feds want your head! Run this script on your own
computer and be sure it is backed up first!




Right after the rm a mkdir command creates a new directory in
/tmp/ with the name TRACE-<name of the program to trace>


Now the most mystic call to strace. What does strace? Strace is a tool to
trace all calls into the OS of a certain program. What can it be used for?
Imagine: You have installed a new program, but calling this program only
produces the output


library not found, aborting


That's it. Grmmphhh...


And now? Strace! Strace will write down (or print) all calls into the OS of
the newly installed program, so all OPEN commands will be traced, too (check
"man open" !!!). If an open to a library, which is not or wrongly installed
at your system will fail, you will see it in the trace file, which is
written to /tmp/TRACE-<new program>


Handy tool, isn't it? Just be sure not to kill your system, OK?
Now back to the script. First look for the bunch of options given to strace
in the man pages.


If a program calls another program, this is called a subprocess. Strace not
only traces the calls into the OS of the main program, it can be configured
to trace also the subprocesses of this main program. Each trace of a
subprocess is written into an extra file.


All those files are written into the /tmp/TRACE-<name of the program>
directory. Now the for-loop in the script collects all files and
concatenates them into one big file. After all this an editor
is called to display the trace. This happens, if the program to be
traced has been finished.


OK, folks, are you beginning to feel like Uberhackers? OK, maybe you have
a few years of programming ahead of you to be an Uberhacker. But if you are
managing to write and run hacking programs now, you are already heading for
the big time. Congratulations!


This Guide was written by Meino Christian Cramer
<
root@solfire.ludwigsburg.netsurf.de> with a few obnoxious but hopefully
informative additions by Carolyn Meinel. If you have questions, please
email Meino and not Meinel!


Where are those back issues of GTMHHs and Happy Hacker Digests? Check out
the official Happy Hacker Web page at
http://www.happyhacker.org.
We are against computer crime. We support good, old-fashioned hacking of the
kind that led to the creation of the Internet and a new era of freedom of
information. So don't email us about any crimes you have committed!
To subscribe to Happy Hacker and receive the Guides to (mostly) Harmless
Hacking, please email
hacker@techbroker.com with message "subscribe
happy-hacker" in the body of your message.
Copyright 1998 Meino Christian Cramer and Nezah. You may forward, print out
or post this GUIDE TO (mostly) HARMLESS HACKING on your Web site as long as
you leave this notice at the end.


Carolyn Meinel
M/B Research -- The Technology Brokers
http://techbroker.com