Can't inject x00 value with bash-printf using string format vulnerability in x64
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Can't inject x00 value with bash-printf using string format vulnerability in x64
Hello! This is my first post here! So, here's the problem: I'm following a nice book called Hacking - The Art Of Exploitation. I'm at the point in wich the string format vulnerability is being explained. I've learned how to do it and on a x32 system of mine: it worked flawlessly. But on my x64 Ubuntu, I can't make it work.
This is the code of the program wich I need to exploit:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char text[1024];
static int test_val = -72;
if(argc < 2) {
printf("Usage: %s <text to print>\n", argv[0]);
exit(0);
}
strcpy(text, argv[1]);
printf("The right way to print user-controlled input:\n");
printf("%s", text);
printf("\nThe wrong way to print user-controlled input:\n");
printf(text); // HERE IS THE VULNERABILITY
printf("\n");
// Debug output
printf("[*] test_val @ 0x%08x = %d 0x%08x\n", &test_val, test_val, test_val);
exit(0);
}
I have to input a string witch begins with the memory location of test_val, then some %08x. that reads the shit in the stack of main, then a %n parameter where I find the written address which on the inputed string to change the value of test_val to the number of writen bytes.
Normaly i would have to input this to make it work:
The problem in the x64 system is that test_val is located at 0x601080 (3 bytes) and when I input $(printf "\x80\x10\x60\x00"), it seems that \x00 doesn't input anything, because I think it's related to NULL as a string end.
Thus, I got a segmentation error all the times that I try because the address isn't valid.
How can I inject that 00? Or how can I write the address to make it readable to the %n parameter? It's just impossible? Hope I've made myself understood!
If there's anything unclear I can answer all the questions!
The problem in the x64 system is that test_val is located at 0x601080 (3 bytes) and when I input $(printf "\x80\x10\x60\x00"), it seems that \x00 doesn't input anything, because I think it's related to NULL as a string end.
Thus, I got a segmentation error all the times that I try because the address isn't valid.
Fortunately vulnerabilities aren't meant to be reliable. I'm also wondering how printing the address to standard output results in it being written to the stack right after printf's first argument, unless printf always has a stack-allocated output buffer at the beginning of the function.
Kevin Barry
PS It would be easier to just use an argument that's 1028 bytes long and overwrite test_val with strcpy, or if you're dead-set on %n use a string that writes past printf(text/*<--here*/); on the stack and write the address there (which could incidentally compromise the operation of strcpy, probably defeating your own effort).
Fortunately vulnerabilities aren't meant to be reliable. I'm also wondering how printing the address to standard output results in it being written to the stack right after printf's first argument, unless printf always has a stack-allocated output buffer at the beginning of the function.
Kevin Barry
PS It would be easier to just use an argument that's 1028 bytes long and overwrite test_val with strcpy, or if you're dead-set on %n use a string that writes past printf(text/*<--here*/); on the stack and write the address there (which could incidentally compromise the operation of strcpy, probably defeating your own effort).
Yo thx for the answer! I tought there was a method to print x00 with printf. No, I don't care about owning the program with the other overflows, because this was just an example. =) I'm just a little worried about all the times when I'll find adresses that start with 00.
Yo thx for the answer! I tought there was a method to print x00 with printf. No, I don't care about owning the program with the other overflows, because this was just an example. =) I'm just a little worried about all the times when I'll find adresses that start with 00.
You've got at least 3 things working against your attempt to pass 0x00 directly:
The shell (bash, anyway) will discard null characters:
$ ./a.out
0x7fff23b85ae0: '12'
0x7fff23b85ae6: 'hello'
[offset 6]<-- 12\00034\0000x7fffb7406146: '12'
0x7fffb7406149: 'hello'
[offset 3]<-- not far enough apart for \00034\000 to be present
strcpy and printf will stop reading the string upon encountering a null character.
Kevin Barry
PS Ubuntu 64-bit uses 32-bit addresses, in case it wasn't obvious.
Last edited by ta0kira; 08-19-2011 at 05:59 PM.
Reason: made execve example more instructive, added comment
$ ./a.out
0x7fff23b85ae0: '12'
0x7fff23b85ae6: 'hello'
[offset 6]<-- 12\00034\0000x7fffb7406146: '12'
0x7fffb7406149: 'hello'
[offset 3]<-- not far enough apart for \00034\000 to be present
strcpy and printf will stop reading the string upon encountering a null character.
Kevin Barry
PS Ubuntu 64-bit uses 32-bit addresses, in case it wasn't obvious.
Thanks a lot for the proof! ^^ I'm glad I've been clarified!
Resurreting this thread because I too am going through this book and have become stuck on this problem. My setup is exactly the same and wanted to know if this was solved?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.