Search string in memory within GDB - gdb

I am currently working on memory corruption techniques for a study and especially ROP and ret2libc. I've read many times that for achieving a system() call, the address of the string of /bin/sh (or equivalent) was required on the stack. I managed to get it when dealing with environment variables, but I wanted to known if the string was present in the libc:
$ strings libc-2.22.so | grep -i /bin/sh
/bin/sh
Okay, but when searching the string with the process started, I saw some strange behaviour:
user#protostar:/opt/protostar/bin$ gdb -q ./stack6
Reading symbols from /opt/protostar/bin/stack6...done.
(gdb) start
Temporary breakpoint 1 at 0x8048500: file stack6/stack6.c, line 27.
Starting program: /opt/protostar/bin/stack6
Temporary breakpoint 1, main (argc=1, argv=0xbffff854) at stack6/stack6.c:27
27 stack6/stack6.c: No such file or directory.
in stack6/stack6.c
(gdb) find __libc_start_main,+999999,"/bin/sh"
Pattern not found.
(gdb) find __libc_start_main,+99999999,"/bin/sh"
0xb7fba23f
warning: Unable to access target memory at 0xb7fd9647, halting search.
1 pattern found.
(gdb) x/1s 0xb7fba23f
0xb7fba23f: "KIND in __gen_tempname\""
And more strangeness when just searching the "sh" pattern:
(gdb) find __libc_start_main,+99999999,"sh"
0xb7fb7a95
0xb7fb821d
warning: Unable to access target memory at 0xb7fdb4a0, halting search.
2 patterns found.
(gdb) x/1s 0xb7fb7a95
0xb7fb7a95: "getpwuid_r"
(gdb) x/1s 0xb7fb821d
0xb7fb821d: "sh"
In a way, I successfully conducted a ret2libc attack using the string located at 0xb7fb821d, but here are my questions:
Why did GDB not "really" find the /bin/sh pattern?
Why are matches found by gdb not really matching my search?
I am pretty new to all this stuff, and even if I discovered a lot of tricks related to binary exploitation, I think that I am missing something here.

Related

Deciphering a C++ Backtrace

Can someone point me as to where I might find an explanation for decoding/deciphering a backtrace. There are thousands of links that explain how to read a dump file, a call stack within an IDE, or creating a backtrace. So where is the one for "I was given a backtrace in an email for a previously internally released code, but nothing explaining why"
i.e. /lib/x86_64-linux-gnu/libc.so.6(+0x350e0) [0x7f58aa6a80e0]
I have been given a backtrace from a crash that occurred once. So I am trying to determine why there was a crash and fix so the it gracefully continues. I have no explanation of what the user was doing, what the system was supposedly doing or anything just the backtrace.
I am not trying to find an issue in the above line it is just the example of a backtrace line. Now what I do know from the example above.
The line states that a line of code in libc.so.6 was called, that the line of code can be found at 0x7f58aa6a80e0 within the code segment of the binary. Problem here is that the code segment address is not returned using addr2line since the address in not in the viewable range (symbols removed). What again does the +0x350e0 represent and how do I use?
I know the exact function that the crash occurred in, not the line.
This is not a solution but a WT.
Best I can tell from a little reverse engineering of the code.
Recompiled libtsm_sl with the added flags -Xlinker -Map=object.map
Found the Address for both AssignReservationSlots and GenerateSOL in object.map.
Then
objdump -D libtsm_sl | less
Then searched the output for AssignReservationSlots+0x5ec which I found. At 558481
Also searched for the address for the call from GenerateSOL and got that address. At 55a480
Now from the stack trace in the log file
4) /usr/lib/libtsm_sl.so.0(AssignReservationSlots()+0x5ec) [0x7f58ae415490]
5) /usr/lib/libtsm_sl.so.0(GenerateSOL()+0x87d) [0x7f58ae417485]
I took the [value] and found the delta which is 0x1FF5, subtracted that from the address for in the libtsm_sl for GenerateSOL’s call to AssignReservationSlots and the resulting address comes to fall on the line in the objdump that has AssignReservationSlots+0x5ec
7f58ae417485 - 7f58ae415490 = 1ff5
55a480 – 1ff5 = 55848B
558481 is line 1449 in NCClass.cpp
55848B is also 1449. It is an if statement and refers to the second argument on the line which is just a bool variable.
So we crashed on evaluating a bool????
Now what??? No answer needed, its rhetorical.

How can I use a variable name instead of addresses when debugging valgrind runs with gdb?

Let's say I'm debugging with valgrind and gdb by doing:
$ valgrind --vgdb-error=0 ./magic
...and then in a second terminal:
$ gdb ./magic
...
(gdb) target remote | /usr/lib/valgrind/../../bin/vgdb
If I want to examine the defined-ness of some memory, I can use:
(gdb) p &batman
$1 = (float *) 0xffeffe20c
(gdb) p sizeof(batman)
$2 = 4
(gdb) monitor get_vbits 0xffeffe20c 4
ffffffff
Using three commands to do one thing is kind of annoying, especially since I usually want to do this a few times for many different variables in the same stack frame. But if I try the obvious thing, I get:
(gdb) monitor get_vbits &batman sizeof(batman)
missing or malformed address
Is it possible to get gdb to evaluate &batman and sizeof(batman) on the same line as my monitor command?
But if I try the obvious thing, I get: missing or malformed address
This is from GDB doc (http://sourceware.org/gdb/onlinedocs/gdb/Connecting.html#index-monitor-1210) for the monitor cmd:
monitor cmd
This command allows you to send arbitrary commands
directly to the remote monitor. Since gdb doesn't care about the
commands it sends like this, this command is the way to extend gdb—you
can add new commands that only the external monitor will understand
and implement.
As you can see "gdb doesn't care about the commands it sends like this". It probably means that the command after monitor is not processed in any way and sent AS IS.
What you can do to evaluate your variable on the same line is to use user defined commands in gdb (http://sourceware.org/gdb/onlinedocs/gdb/Define.html). Define your own comand and use the eval gdb command to prepare your command with necessary values (http://sourceware.org/gdb/current/onlinedocs/gdb/Output.html#index-eval-1744):
define monitor_var
eval "monitor get_vbits %p %d", &$arg0, sizeof($arg0)
end
And then use it like this:
(gdb) monitor_var batman

How to get line number from libunwind and AddressSanitizer listed as <shared object>+offset?

I often get stack traces from libunwind or AddressSanitizer like this:
#12 0x7ffff4b47063 (/home/janw/src/pl-devel/lib/x86_64-linux/libswipl.so.7.1.13+0x1f5063)
#13 0x7ffff4b2c783 (/home/janw/src/pl-devel/lib/x86_64-linux/libswipl.so.7.1.13+0x1da783)
#14 0x7ffff4b2cca4 (/home/janw/src/pl-devel/lib/x86_64-linux/libswipl.so.7.1.13+0x1daca4)
#15 0x7ffff4b2cf42 (/home/janw/src/pl-devel/lib/x86_64-linux/libswipl.so.7.1.13+0x1daf42)
I know that if I have gdb attached to the still living process, I can use this to get details
on the location:
(gdb) list *0x7ffff4b47063
But if the process has died, I can not just restart it under gdb and use the above because
address randomization makes that I get the wrong result (at least, that is my assumption;
I clearly do not get meaningful locations). So, I tried
% gdb program
% run
<get to the place everything is loaded and type Control-C>
(gdb) info shared
<Dumps mapping location of shared objects>
(gdb) list *(<base of libswipl.so.7.1.13>+0x1f5063)
But, this either lists nothing or clearly the wrong location. This sounds simple, but
I failed to find the answer :-( Platform is 64-bit Linux, but I guess this applies to
any platform.
(gdb) info shared
<Dumps mapping location of shared objects>
Unfortunately, above does not dump actual mapping location that is usable with this:
libswipl.so.7.1.13+0x1f5063
(as you've discovered). Rather, GDB output lists where the .text section was mapped, not where the ELF binary itself was mapped.
You can adjust for .text offset by finding it in
readelf -WS libswipl.so.7.1.13 | grep '\.text'
It might be easier to use addr2line instead. Something like
addr2line -fe libswipl.so.7.1.13 0x1f5063 0x1da783
should work.
Please see http://clang.llvm.org/docs/AddressSanitizer.html for the instructions on using the asan_symbolize.py script and/or the symbolize=true option.

Analyze backtrace of a crash occurring due to a faulty library

In my application I have setup signal handler to catch Segfaults, and print bactraces.
My application loads some plugins libraries, when process starts.
If my application crashes with a segfault, due to an error in the main executable binary, I can analyze the backtrace with:
addr2line -Cif -e ./myapplication 0x4...
It accurately displays the function and the source_file:line_no
However how do analyze if the crash occurs due to an error in the plugin as in the backtrace below?
/opt/myapplication(_Z7sigsegvv+0x15)[0x504245]
/lib64/libpthread.so.0[0x3f1c40f500]
/opt/myapplication/modules/myplugin.so(_ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi+0x6af)[0x7f5588fe4bbf]
/opt/myapplication/modules/myplugin.so(_Z11myplugin_reqmodP12CONNECTION_TP7Filebuf+0x68)[0x7f5588fe51e8]
/opt/myapplication(_ZN10Processors7ExecuteEiP12CONNECTION_TP7Filebuf+0x5b)[0x4e584b]
/opt/myapplication(_Z15process_requestP12CONNECTION_TP7Filebuf+0x462)[0x4efa92]
/opt/myapplication(_Z14handle_requestP12CONNECTION_T+0x1c6d)[0x4d4ded]
/opt/myapplication(_Z13process_entryP12CONNECTION_T+0x240)[0x4d79c0]
/lib64/libpthread.so.0[0x3f1c407851]
/lib64/libc.so.6(clone+0x6d)[0x3f1bce890d]
Both my application and plugin libraries have been compiled with gcc and are unstripped.
My application when executed, loads the plugin.so with dlopen
Unfortunately, the crash is occurring at a site where I cannot run the application under gdb.
Googled around frantically for an answer but all sites discussing backtrace and addr2line exclude scenarios where analysis of faulty plugins may be required.
I hope some kind-hearted hack knows solution to this dilemma, and can share some insights. It would be so invaluable for fellow programmers.
Tons of thanks in advance.
Here are some hints that may help you debug this:
The address in your backtrace is an address in the address space of the process at the time it crashed. That means that, if you want to translate it into a 'physical' address relative to the start of the .text section of your library, you have to subtract the start address of the relevant section of pmap from the address in your backtrace.
Unfortunately, this means that you need a pmap of the process before it crashed. I admittedly have no idea whether loading addresses for libraries on a single system are constant if you close and rerun it (imaginably there are security features which randomize this), but it certainly isn't portable across systems, as you have noticed.
In your position, I would try:
demangling the symbol names with c++filt -n or manually. I don't have a shell right now, so here is my manual attempt: _ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi is ICAPSection::process(CONNECTION_T *, Filebuf *, int). This may already be helpful. If not:
use objdump or nm (I'm pretty sure they can do that) to find the address corresponding to the mangled name, then add the offset (+0x6af as per your stacktrace) to this, then look up the resulting address with addr2line.
us2012's answer was quite the trick required to solve the problem. I am just trying to restate it here just to help any other newbie struggling with the same problem, or if somebody wishes to offer improvements.
In the backtrace it is clearly visible that the flaw exists in the code for myplugin.so. And the backtrace indicates that it exists at:
/opt/myapplication/modules/myplugin.so(_ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi+0x6af)[0x7f5588fe4bbf]
The problem of locating the line corresponding to this fault cannot be determined as simplistically as:
addr2line -Cif -e /opt/myapplication/modules/myplugin.so 0x7f5588fe4bbf
The correct procedure here would be to use nm or objdump to determine the address pointing to the mangled name. (Demangling as done by us2012 is not really necessary at this point). So using:
nm -Dlan /opt/myapplication/modules/myplugin.so | grep "_ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi"
I get:
0000000000008510 T _ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi /usr/local/src/unstable/myapplication/sources/modules/myplugin/myplugin.cpp:518
Interesting to note here is that myplugin.cpp:518 actually points to the line where the opening "{" of the function ICAPSection::process(CONNECTION_T *, Filebuf *, int)
Next we add 0x6af to the address (revealed by the nm output above) 0000000000008510 using linux shell command
printf '0x%x\n' $(( 0x0000000000008510 + 0x6af ))
And that results in 0x8bbf
And this is the actual source_file:line_no of the faulty code, and can be precisely determined with addr2line as:
addr2line -Cif -e /opt/myapplication/modules/myplugin.so 0x8bbf
Which displays:
std::char_traits<char>::length(char const*)
/usr/include/c++/4.4/bits/char_traits.h:263
std::string::assign(char const*)
/usr/include/c++/4.4/bits/basic_string.h:970
std::string::operator=(char const*)
/usr/include/c++/4.4/bits/basic_string.h:514
??
/usr/local/src/unstable/myapplication/sources/modules/myplugin/myplugin.cpp:622
I am not too sure why the function name was not displayed here, but myplugin.cpp:622 was quite precisely where the fault was.

How to interpret gdb disassemble output?

I am trying to match the gdb disassemble output (disas [address]) against the source code. I know that such mapping can be done using (gdb) info line *address to find the matching line. However I do not quite understand the format of the output of disassemble. Specifically, what do the following numbers, +4722, and +4281, mean ?
0x00002ad61e45bd02 <+4722>: jmpq 0x2ad61e45bb49 <MsgManager::ForwardMsg(boost::shared_ptr<Channel>, boost::shared_ptr<Msg>, boost::shared_ptr<Context>)+4281>
I am using GNU gdb (GDB) 7.4.1.
Specifically, what do the following numbers, +4722, and +4281, mean
The instruction at address 0x00002ad61e45bd02, which is 4722 bytes from the start of current function (most likely MsgManager::ForwardMsg()) is a jump to address 0x2ad61e45bb49, which is 4281 bytes from the start of MsgManager::ForwardMsg().
You may also find (gdb) disas/m command handy.