|
Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com |
Re: question on buffer overflow (was RE: Extreme Hacking)
Antonomasia (ant
notatla.demon.co.uk)
Mon, 12 Jul 1999 22:57:36 +0100
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
- Next message: Colin Horsington: "VPN Config's"
- Previous message: R. DuFresne: "Re: TCP port 7 traffic from DoubleClick"
- Next in thread: Choi, Byoung: "RE: question on buffer overflow (was RE: Extreme Hacking)"
"Choi, Byoung" <bchoi
visa.com>
> i have a dumb question:
OK, I'll bite on this. I'll point out in advance to any critics that
all of this is available already in many places. And it's all in the
interests of keeping my CC charges down.
I believe a good understanding of the exploits is useful both in testing and
proving flaws to pointy-haired types. Actually writing safe software is a
different discipline, but whan you rely on software from typical vendors you
(sometimes) have to prove every word of your complaint.
And despite the popularity of the overflow in recent years the systems I see
are often more easily vulnerable to simple environment manipulation and
plain bad filemodes (at any rate as far as local users are concerned).
> a local buffer can be overflown to overwrite the thread's stack (if the
> code doesn't check for the EOB). overwriting the stack can change the
> flow of the code, and possibly redirect it to rogue code inserted.
>
> but what's the "typical" (if there is one) technique? it all seems rather
> precarious:
> the rogue code is platform-dependent (machine code, etc.)
> the exploit must anticipate the stack frame location where it will get
> overwritten so that
> 1. the address depedence of the rogue code is satisfied
> 2. control flow is correctly redirected to the rogue code.
>
> am i in the ball park?
Certainly in the ballpark.
The definitive paper is by Aleph One, called in Phrack 49, file 14.
"Smashing The Stack For Fun And Profit". I've learned from that and
am going to ramble on about my own practice efforts here.
Once you have the shellcode (available for mainstream processors from
existing exploits) there are usually 3 things you have to fiddle with.
0) finding an exploitable bug - and you can write your own for practice
Having source code to audit helps, but is not essential.
1) finding where in the input to put the return address
This is done by reading core dumps with gdb or dbx. In the case
of set[ug]id programs you take an unpriviledged copy and hope it
works the same at least up to the point you're interested in. For
network programs that's not necessary but you might need to remove
a coresize resource limit from inetd and ensure the victim program
runs as root so it can dump core in /.
(It's assumed you are working on a box where you already have
legitimate root access.)
So feed different string lengths in with rough variation - in binary search
style (2000 -> coredump, 1000 -> normal execution, 1500 -> coredump ,...)
and look at the cores. (typical input "AAAAAA", debugger command "where")
When you have it narrowed down try the alphabet in the target region for the
return address. This confirms the position to the exact byte and shows the
byte order if you didn't know it. You want to terminate the buffer
correctly - either '\n' for gets() or '\0' for strcpy() and friends.
The core dumps you've been getting so far result from the fact that you've
been supplying total rubbish as a return address and execution cannot pick
up at that point. Just recognising your input in a stack trace is proof of
vulnerability and should be take seriously by a good vendor without an
actual exploit.
2) Spot where the buffer is in memory. If the victim code is using gets()
or something recognisable you might find this using the debugger and
noticing the address used by gets(). (Start it against an existing process
if called from inetd during the time it waits for your user input.)
Or make your example program in step 0 print out the address of a buffer
it uses and take that as a first guess to do a search on with commands like
0x2ff22c00/128x in dbx.
Next you need to insert the shellcode into the buffer (on a 4-byte boundary)
and set the return address to point to it. I like to make these 2 separate
steps so I set the address first and make sure the buffer contains invalid
code (07070707 or whatever for your processor). The result should be a core
dump with confirmation that you hit the right address.
Then you paste in your shellcode. Some shellcode wants tuning to the
kernel it runs under - examine the sploit you lifted it from.
Then run it on a test system (what _is_ that shellcode doing ?).
You should now be well on the way to writing a bug report for the vendor,
but don't expect quick fixes to result.
Cheating ? Of course. In step 1 you can repeat the retuen address many
times to save the bother of getting exact placement. In step 2 the cheat
is to pad the start of the shellcode with NOP instructions.
That's mostly it. There are variations such as pointing the return address
into your environment variables (useful if the buffer is too short for the
shellcode) and returning into the system() function if the stack is not
executable (idea due to Solar Designer I think).
If I don't illustrate anything more with this example I think the
point is made that exploit software is not nearly as demanding to write
as safe production software.
It should also (can I say this too often?) show why procurement and
security should be talking to each other. 30 minutes of evaluation
from a security viewpoint will often give convincing evidence why you
don't want a given product in your company. What good is finding out
after it's deployed ?
Linux, Intel: self-victim code as it overflows by itself without input.
You may have to adjust the numbers to suit your box, but that's what
this article is all about.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* using system() so that we don't need shellcode or an executable stack
*
* Victim code must use system() and must have a useful command name as a
* string somewhere we can find, such as the SHELL environment variable.
*/
int myfunc(char *cp)
{
char lame[8];
strcpy(lame,cp);
return 0;
}
int main(int argc, char **argv, char **envp)
{
char nasty[]="


















6789";
/* system() at 0x0804841c from gdb's "print system" */
nasty[12]=0x1c;
nasty[13]=0x84;
nasty[14]=0x04;
nasty[15]=0x08;
/***************/
/* "/bin/bash" in the environment, found with gdb's "x" */
nasty[20]=0xb7;
nasty[21]=0xff;
nasty[22]=0xff;
nasty[23]=0xbf;
myfunc(nasty);
/* expect a seg fault after the exploit */
printf("program not smashed\n");
exit(0);
return system("date");
}
-- ############################################################## # Antonomasia antnotatla.demon.co.uk # # See http://www.notatla.demon.co.uk/ # ##############################################################
- Next message: Colin Horsington: "VPN Config's"
- Previous message: R. DuFresne: "Re: TCP port 7 traffic from DoubleClick"
- Next in thread: Choi, Byoung: "RE: question on buffer overflow (was RE: Extreme Hacking)"
This archive was generated by hypermail 2.0b3 on Sat Jul 17 1999 - 07:19:03 CDT