Sponsored by: █ Sparkhost - Hosting Without Compromises! █ Hybrid Performance Web Hosting █ Spark Host Stream Hosting █ Hybrid IRC & IRCd Server Shell Accounts
How To Exploit A Buffer Overflow Vulnerability?
#1 Guest_T3cHn0b0y_*
Posted 05 April 2004 - 06:14 AM
When it comes to the basics of exploiting a buffer overflow vulnerability and writing code to run on the remote host, I know almost nothing...which is why I'm asking for someone with a bit more knowledge than myself to help the other members and I.
Ok. What I do know is that buffer overflows occur when attempting to write data outside of an arrays memory reference range. By this, I mean, for example, trying to assign a value to array_var[11] when array_var has only been allocated 10 slots of memory for the data in declaration.
So heres some vulnerable code below:
----------------------+ Turbo Pascal +------------------------
Program Buffer_Overflow;
uses WinCrt;
var
vuln: array[0..9] of char; {vulnerable array}
n: integer;
begin
for n := 0 to 10 do
vuln[n] := readkey; {assign vuln[n] single key pressed by the user}
end.
----------------------+ Turbo Pascal +------------------------
Well even if you havn't learned Turbo Pascal (easiest language in the world) then I'm sure you can work out what the above code does. When compiled, the overflow occurs on the 11th keypress of the user. The program will then stop responding.
Maybe someone can now elaborate on this and explain what an attacker might be able to do with this (if the data was entered over a network with a streaming data socket) to compromise your system.
#2 Guest_OneNight_*
Posted 05 April 2004 - 06:31 AM
Haitchttp://www.uhagr.org/papers/UHAGr-Bof.txt
#3
Posted 05 April 2004 - 06:40 AM
Certain languages such as C, C++ and Pascal don't have garbage collectors preventing data from being written outside of allocated space - other languages such as Perl and Python are therefore immune, as they do have garbage collectors to prevent this type of thing.
A buffer overflow occurs when too much data is written into a buffer, which doesn't have enough bytes allocated to hold it all. Therefore, the remainder of the data spills over the 'bounds' of the buffer, overwriting the Stack Frame Pointer, return address, several general purpose registers and other parts of the memory. The 'return address' is a very important part of program execution - this register controls the "program flow". It works basically like this:
- An instruction finishes executing
- The address of the next instruction in memory is placed into EIP, the instruction pointer - this register holds the "return address"
- The program "jumps" to the address held in EIP
- The instruction is executed
This process basically happens in a non-ending loop until all of the instructions in the program are executed (in theory, but some instructions are in reality skipped, because users can choose different options and stuff).
So, now we know this; after the execution of an instruction, the memory address held in EIP is jumped to, and the instruction found there is executed.
However, what do we know about buffer overflows? So far we know that when more data is shoved into a buffer (array) than is physically possible, it OVERFLOWS THE BOUNDS OF THE BUFFER, "SPILLING" INTO UNAUTHORISED MEMORY. It should now be noted than data which overflows the bounds of the buffer/array, if there is enough of it, can overwrite EVERYTHING on the stack beyond the location of our buffer, in theory.
Therefore, if we overflow a buffer in a vulnerable program with enough data, WE CAN OVERWRITE EIP, THE RETURN ADDRESS. This is a VERY important concept to learn, as this is what makes exploitation of buffer overflows possible. But what if we overflow the bounds of the buffer with enough data to overwrite the content of EIP? The program *WILL* jump to that memory location. But, what if we overwrite EIP with a memory address which WE KNOW DESIRABLE CODE IS LOCATED AT? The program *WILL* execute that code! Exploited. This can potentially result in a shell or execution of any other code, if we can overflow the buffer to put that code somewhere in memory, and then overwrite EIP with the approximate address of that code.
So let's sumarise what we would need to do to exploit a buffer overflow vulnerability:
- Place our arbitrary code ("shellcode") in memory by overflowing the buffer
- Overwrite EIP with the memory address of our shellcode by overflowing the buffer
- The program jumps to the NEW contents of EIP - THUS EXECUTING OUR SHELLCODE
0wned
Do you understand the basic concept. If you don't, or my explanation was shitty, I WILL explain again. Don't by any means just say you did understand my explanation, if you don't understand it yet, PLEASE DO ASK ME AGAIN. I literally have all day. Drop by on IRC aswell
If you want, I will do a demo for you. Not faked - just a real demo.
-Shaun.
#4
Posted 05 April 2004 - 07:19 AM
thhnx
#5
Posted 05 April 2004 - 07:56 AM
i also have some questions on that matter - hope it isnt too much ^^:^
1.) how do u know how much data (shellcode) u can stuff into the buffer? i mean it isnt unlimited is it? does it depend on the program u want to exploit?
2.) is there a difference between offset and ret-addy or is it the same?
3.) why can u chose the ret-addy as a conastant value? i mean doesnt the ret depend on how "full" the stack is? or is the buffer always on the same place on the stack?
4.) could u generally explain how u work with that jump and call commands? i didnt really get that yet :S
5.) how many NOPs do u have to put @ the beginning of ur shellcode? does this also depend on the program u want to exploit?
well i think enough questions for now. would appreciate it if u could help me a bit. and sry for my bad english...
greetz,
buzz
#6 Guest_T3cHn0b0y_*
Posted 05 April 2004 - 08:13 AM
Anyway...Shaun2k yes I do fully understand the concept of it and how it is done and the demo sounds great!
#7
Posted 05 April 2004 - 08:47 AM
You generally find out how large the buffer is by looking at the program code. For example, if an overflowable buffer is called 'buf', it might be declared like this in the code:1.) how do u know how much data (shellcode) u can stuff into the buffer? i mean it isnt unlimited is it? does it depend on the program u want to exploit?
[...] char buf[100]; [...]This buffer has 100 bytes allocated for it. In theory, 101 bytes should overflow it, but 101 bytes usually won't produce a segmentation fault. Try 110 for a seg fault.
Yeah, there's a big difference, they're totally different things. An 'offset' is how far off a variable/location is from the top of the stack (stack pointer, ESP).2.) is there a difference between offset and ret-addy or is it the same?
A return address is the address in EIP which essentially is the address of the next instruction.
When exploiting buffer overflows, you already know the approximate address of where your shellcode is going to be. This info is gained via trial and error, with help from a debugger such as GNU GDB or Valgrind.3.) why can u chose the ret-addy as a conastant value? i mean doesnt the ret depend on how "full" the stack is? or is the buffer always on the same place on the stack?
The location of a buffer can move occasionally, such as when there is POPs and PUSHes (assembly programmers will know what I mean).
I might've explained a little patchily. The hacker doesn't actually use those call or jmp commands - the program does that. The theory is that programs JMP to the address in EIP, thus executing the next instruction in the program. EIP = instruction pointer.4.) could u generally explain how u work with that jump and call commands? i didnt really get that yet :S
We just shove our calculated ret address into EIP and the program jmps to our shellcode.
I usually use around 100, but others have a lot more precision, using none at all.5.) how many NOPs do u have to put @ the beginning of ur shellcode? does this also depend on the program u want to exploit?
Yeap, it really does depend on the type of program you're sploiting. See, in theory, some buffer overflows aren't even exploitable to execute code. Whereas in others, you don't even need NOPs because you have local access and can calculate the required ret address perfectly. Note that the NOP instructions are basically if you calculate the wrong return address - if you are accurate enough to hit the NOP sled, the program will skip along executing the NOPs, and then run your code.
Sure, no prob, I can give a demo quite easily. However, note, I will be using a different technique - no shellcode. I will be using the "return-into-libc", which basically means you execute libc instead of shellcode. I find this more convenient for local exploits - it seems like a quicker alternative than messing with buggy shellcode oftentimes.
Don't get confused - the only difference than the generic exploitation method is this: Instead of placing the address of the shellcode into EIP, we place the address of a libc function into EIP instead - simple really. For example, I could put the address of 'system()' into EIP instead, with the necessary stuff to run /bin/sh. If enough people want me to execute shellcode instead, I'll do that
A show of hands please
-Shaun.
#8
Posted 05 April 2004 - 09:16 AM
as for the demo: i would prefer a demo of a shellcode executing a cammandshell on a win32 machine! im not that much into unix yet...
greetz
#9 Guest_BlaStA_*
Posted 05 April 2004 - 10:02 AM
So, how would you exploit some code like this:
int main(int argc, char *argv)
{
char buf[10];
scanf("%s",buf);
}Would this be possible?
#10
Posted 05 April 2004 - 10:58 AM
-Shaun.
#11
Posted 05 April 2004 - 11:45 AM
Here:
export OURSH=/bin/sh export OURMODE=S_ISUID echo `perl -e 'print "HACK"x7 . "\x90\x1f\x0e\x40HACK\x27\xfe\xff\xbf\x22\xfb\xff\xbf"'` | ./vuln2"HACK"x7 = garbage data to get \x90\x1f\x0e\x40 to overwrite EIP.
\x90\x1f\x0e\x40 = the address of the 'chmod' system call on MY system.
HACK = address to goto after executing the chmod syscall - no need for a real address.
\x27\xfe\xff\xbf - address of OURSH environmental variable, which holds "/bin/sh".
x22\xfb\xff\xbf - address of the OURMODE environmental variable, which holds S_ISUID, which means SUID.
Assuming vuln2 is SUID root, /bin/sh would now be SUID root. Woohoo!
I'm sorry about my perculiar exploitation techniques. I prefer to use perl + 'return into libc' type techniques when exploiting locally. Basically, this "perl one liner" overwrites EIP with \x90\x1f\x0e\x40, the address of 'chmod' syscall, and the other addresses, \x27\xfe\xff\xbf and \x22\xfb\xff\xbf point to the environmental variables which hold /bin/sh and the mode, S_ISUID. When I ran this command, /bin/sh was now SUID. This is because 'chmod' was called to set /bin/sh to SUID. Effectively, vuln2 was tricked into running the equivalent of this command:
chmod +s /bin/shEach to their own - others have cleaner exploitation methods.
THIS WON'T WORK ON ANY OTHER LINUX SYSTEM, BECAUSE THESE ARE THE ADDRESSES TO DATA ON *MY* SYSTEM, NOT YOURS.
If anyone really wants it, I'll code up an exploit which uses shellcode in C. I'm thinking about asking the admins if we can hold lectures regarding topics like buffer overflows on the GSO irc channel. I hope to be able to expand more on there.
However, the point is, I exploited it. I can explain things as well as write a better sploit, if anyone really cares
-Shaun.
#12
Posted 05 April 2004 - 11:59 AM
#13
Posted 05 April 2004 - 12:32 PM
The easist exploits to do are the ones that use Enviroment variables to store the shellcode.. You dont even have to have a NOP sled you can get the exact location of the shellcode and avoid ids detection just by doing the math.. and getting the exact location and keep in mind litte-endian.. which means
0xbfff8080 would have to be put into memory like \x80\x80\xff\xbf
#14 Guest_BlaStA_*
Posted 05 April 2004 - 01:08 PM
1) Why did u use the perl command (echo `perl -e 'print "..."'`)? Can't you just use echo "HACK\x90\x1f\x0e\x40HACK\x27\xfe\xff\xbf\x22\xfb\xff\xbf"?
2) How did u get the offsets of the chmod call and your two variables OURSH and OURMODE?
#15
Posted 05 April 2004 - 02:29 PM
I found a (I thought) very simple example of a way the buffer can be manipulated.
The code
############
#include <stdio.h>
void function(int a, int b, int c) {
char buffer1[8];
char buffer2[16];
int *ret;
ret = buffer1+12;
(*ret)+=8;
}
void main() {
int x;
x = 0;
function(1,2,3);
x = 1;
printf("%d\n",x);
}This code should manipulate the buffer so that the instruction "x = 1;" is not executed and jumps directly to the printf-instruction, this manipulation should be done with the line "(*ret)+=8;". But I only get an error and the program crashes.

Can someone explain me what is wrong with that example?
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users












