I'm studying buffer overflow and solving some wargames. There was a problem that all of the stack memory above the buffer is set to 0 except return address of main, which will be:
buffer
[0000000...][RET][000000...]
and I can overwrite that RET. So I found some hints for solving this problem. It was to use LD_PRELOAD. Some people said that LD_PRELOAD's value is in somewhere of stack not only in environment variable area of stack. So I set LD_PRELOAD and search it and found it using gdb.
$ export LD_PRELOAD=/home/coffee/test.so
$ gdb -q abcde
(gdb) b main
Breakpoint 1 at 0x8048476
(gdb) r
Starting program: /home/coffee/abcde
Breakpoint 1, 0x8048476 in main ()
(gdb) x/s 0xbffff6df
0xbffff6df: "@èC\001@/home/coffee/test.so"
(gdb) x/s 0xbffffc59
0xbffffc59: "LD_PRELOAD=/home/coffee/test.so"
(gdb) q
The program is running. Exit anyway? (y or n) y
$
So there is! Now I know that LD_PRELOAD's value is on stack below the buffer and now I can exploit!
But I wonder why LD_PRELOAD is loaded on that memory address. The value is also on environment variable area of the stack!
What is the purpose of this? Thanks.
Code to explore the stack layout:
With the program compiled as
x
, I ran it with a sanitized environment:If you study that carefully, you'll see that the
argv
argument tomain()
is the start of a series of pointers to strings further up the stack; theenvp
(optional third argument tomain()
on POSIX machines) is the same as the global variableenviron
andargv[argc+1]
, and is also the start of a series of pointers to strings further up the stack; and the strings pointed at by theargv
andenvp
pointers follow the two arrays.This is the layout on Mac OS X (10.7.5 if it matters, which it probably doesn't), but I'm tolerably sure you'd find the same layout on other Unix-like systems.