Ok, I’m in a remote situation where I don’t have access to the remote filesystem but where I can run arbitrary python code (except I can’t fork processes and I don’t have access to ulimit and uname).

However, it means I can read and write at arbitrary virtual memory addresses. I know the python interpreter is statically linked so it has no external shared object dependencies.
While nx is enabled, strangely aslr seems to be disabled.
I already identified and dumped the following region whose contents and places never change :

0x00010000:0x00050000 # read only and executable
0x01000000:0x01b80000 # read only and executable
0x11000000:0x1158c000 # writable
# The heap is located between those 2 places and it’s location is chose at random
0xfe500000:0xffffffff # writable

In that case, is it possible to rebuild the ᴇʟꜰ binary ? (it was compiled for native client). It doesn’t have to be the original binary with the original header, but just an executable that can be launched from the various parsed ᴇʟꜰ segments.

Update :

Unlike normal nexe, the python.nexe is compiled nacl_interp can only be ran on Linux. This mean the target ᴏꜱ in the ᴇʟꜰ header is set to 0x7B (whereas normal nexe are ᴏꜱ independent).

The libc is glibc. See also https://groups.google.com/forum/#!topic/native-client-discuss/t54RajuGnPc

  • As this is on a remote ʜᴛᴛᴘ server, the only process I can use is python 2.7.5. Sep 7 '16 at 22:26

It is possible to rebuild the whole binary if you can leak any address in the process address space. As an example here is a memory map of a process

$cat /proc/self/maps
00400000-0040c000 r-xp 00000000 08:01 10223630                           /bin/cat
0060b000-0060c000 r--p 0000b000 08:01 10223630                           /bin/cat
0060c000-0060d000 rw-p 0000c000 08:01 10223630                           /bin/cat
0232c000-0234d000 rw-p 00000000 00:00 0                                  [heap]
7ffef94f3000-7ffef9514000 rw-p 00000000 00:00 0                          [stack]
7ffef95cd000-7ffef95cf000 r--p 00000000 00:00 0                          [vvar]
7ffef95cf000-7ffef95d1000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

The first three sections in the map contain the executable itself. You just have to leak that section and then can reassemble to form an executable.

If the binary is not PIE enabled, the location of the executable code will be static every time the binary is ran, as in the above example. By default, you get 0x8048000 load address in 32-bits and 0x400000 64-bit. However this can be changed during the linking process. You can search in the process space for "ELF" and probably your executable would start from there.

  • Any attempt to read the filesystem return no such file or directory error, even for listing or chdir to/. So I can’t access /proc. The only way to find mapping is through trial. You can search in the process space for "ELF" and probably your executable would start from there. But where search ? It’s definitely not in .text since I dumped the whole region with execute permissions. I found the .text section because some function pointers where directed at it from a section which was read only (and in both cases they don’t change). I can’t know if a particular address is allocated or not. Sep 7 '16 at 21:16
  • However, it means I can read and write at arbitrary virtual memory addresses I meant to look for "ELF" in the address space of the process. Though I don't know if python allows that or not!
    – sudhackar
    Sep 7 '16 at 21:18
  • Have a look at : asciinema.org/a/85104
    – sudhackar
    Sep 7 '16 at 21:28
  • If I read an address that isn’t allocated the program segfault. So I can’t create a single dump of the whole virtual memory. In the same time I don’t have any access to the ᴄᴘᴜ registers (both in reading or writing). I told I was in a remote situation. The only program I can use is python. Sep 7 '16 at 21:28
  • If the program segfaults you can iterate multiple times looking for the "ELF" string in the memory. Here's a script I wrote for leaking the binary when I could leak arbitrary strings with the SSP(Stack Smashing Protector) : pastebin.com/EiGj38ka. I just assumed the binary is at 0x8048000 as it was x86.
    – sudhackar
    Sep 7 '16 at 21:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.