Writing a return-to-libc attack, but libc is loaded at 0x00 in memory

时光毁灭记忆、已成空白 提交于 2019-12-19 09:10:29

问题


I'm writing a return to libc attack for my systems security class. First, the vulnerable code:

//vuln.c
#include <stdio.h>
#include <stdlib.h>

int loadconfig(void){
  char buf[1024];
  sprintf(buf, "%s/.config", getenv("HOME"));
  return 0;
}

int main(int argc, char **argv){
  loadconfig();
  return 0;
}

I want to use a return to libc attack. Compiling and debugging the program:

$ gcc -g -fno-stack-protector -o vuln vuln.c
$ gdb vuln
(gdb) break loadconfig
(gdb) run
Reached breakpoint blah blah blah.
(gdb) p $ebp
$1 = (void *) 0xbfffefb0
(gdb) p system
$2 = {<text variable, no debug info>} 0x0016db20 <system>
(gdb) p exit
$3 = {<text variable, no debug info>} 0x001639e0 <exit>
(gdb) x/2000s $esp
...
0xbffff5af:    "SHELL=/bin/bash"

To execute the attack, I want to overflow the buffer into loadconfig's return address (aka $esp+4), replacing it with the return address for system, then the return address for exit (since system expects a real return address), then the command name (the address of SHELL=/bin/bash plus 6, to trim the SHELL= part). This should be possible by crafting a $HOME environment variable of 1024 characters of crap, then the little-endian address of system, exit, and /bin/bash.

However, with every computer I've tried, system gets loaded at an address that starts with 0x00, which will null terminate the string that sprintf is reading and stop the attack dead. Is there some way to force libc to load elsewhere in memory, or am I misinterpreting the attack?

For reference, I'm running an Ubuntu Server 11.10 virtual machine in VirtualBox (Windows host), with gcc version 4.6.1 and gdb version 7.3-2011.08. edit: ASLR is disabled, and I compiled with -fno-stack-protector to remove the canary. Since I'm not executing anything from the stack, I don't need to execstack it.


回答1:


The act of mapping important libc function to addresses which contain a NULL byte is called ASCII armoring. This protection is part of RedHat Exec-shield which is currently enabled on recent ubuntu distros link To disable it you have to run as root:

sysctl -w kernel.exec-shield=0

as explained here

By the way you can find interesting material about how to bypass ASCII armoring here on exploit-db




回答2:


I am fairly certain that this is impossible on 11.10, at least in the ways you mention. Have a look:

https://wiki.ubuntu.com/Security/Features

In detail, and just picking some problems with your ideas:

(1) because of canary values and for other reasons, buffer Overflow into esp+4 will raise a Segmentation fault exception

(2) you probably mean to extract the address of the environmental variable, which traditionally would have been at ESP (main) + a certain number of bytes. However, as even logical memory addresses these days are scrambled/randomized after compile, you will instead get a different mememory address for your $HOME variable for each run, probably somewhere on the other side of the main stack

(3) to the best of my knowledge, there are other ways in which return from library attacks these days are thwarted. I am less familiar with those. This should be why you see x00 for the address

Hacking these days on a ubunti system is hard. If you just need to do this for a class that doesn't insist on current distros, install instead the first ubunti distro in virtualbox. Magically, all you try will work. There is no more "standard overflow attack" that you also reference - even if you cleverly bypass canary valued etc, setting the nx bit makes this impossible. And similarly, while I'm less perfectly certain about how return from libc attacks are addressed, don't rely on believing this will be possible on a current distro. Good luck!



来源:https://stackoverflow.com/questions/7779534/writing-a-return-to-libc-attack-but-libc-is-loaded-at-0x00-in-memory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!