Buffer Overflow Works in GDB but not in Terminal - terminal

I am using Mac OSX. I have created a buffer overflow vulnerable program:
#include<stdio.h>
#include<string.h>
int neverCalled() {
puts("You got me to be called");
return 0;
}
int main() {
puts("Name: ");
char name[64];
gets(name);
return 0;
}
I also have created an input file containing 88 "A"s (0x414141...) and 0x700E000001000000
When run in gdb:
(gdb) run < input
I get the output: You got me to be called and then a EXC_BAD_ACCESS error. Meaning that I exploited the program successfully.
When run it in terminal:
$ ./vulnerable < input
I get the output: Segmentation fault: 11 and nothing more.
Why does my buffer overflow work in gdb but fail in normal terminal.

gdb on mac os X appears to disable address space layout randomization
http://reverse.put.as/2011/08/11/how-gdb-disables-aslr-in-mac-os-x-lion/

Why 0x700E000001000000? Your exploit seems to be layout-specific, probably out of what gdb prints when typing "p neverCalled".
This is not guaranteed in all executions. As cabellicar123 correctly pointed out, the layout where libraries and executable are mapped in a process are randomized and not guaranteed to be the same between executions.
For some reason it seems that gdb always gets the same layout. As an exercise include "printf("%p"\n", neverCalled)" somewhere in your program and see how the value changes.

Related

redirected stdin ends prematurely Lua for Windows

I'm using Lua in a cmd window under Windows.
I use "cat" (from UnxUtils) to feed a file to a Lua script. The script uses "io.read(1)" to read one byte at a time.
local b, n ;
n = -1 ;
b = true ;
while b do
n = n + 1 ;
b = io.read(1) ;
end ;
print( n, "bytes read" ) ;
When I feed the script a 333K .EXE file, it claims "24025 bytes read".
Feed the same .EXE to "wc" (another UnxUtils), and wc correctly says 333008.
> cat "Firefox Installer.exe" | lua count.lua
24025 bytes read
cat: write error: Invalid argument
> cat "Firefox Installer.exe" | wc
1408 8674 333008
Since I get the expected answer when I "cat | wc", I don't think there's anything wrong with the "cat" program, or with Windows' implementation of redirection.
I am not looking for advice on how to make the Lua script more efficient. I do not need advice on how to make the script read directly from a file (that works as expected). I am looking for a clue as to where to look for the reason I can't use Lua to write a filter (and be able to trust the results).
I have looked at the input file to see if a Ctrl-Z or Ctrl-D was the reason for the early shut-off -- they occur very early in the file.
I tried reading after "io.read()" returned "false": the script admitted to seeing more bytes, but still no more than 45K of the 333K input file.
Copied from my comments:
Likely to be a Windows issue (see e.g. this answer). Windows treats binary and text "streams" / files differently. I would assume that your program's stdin is a text stream by default; it isn't possible to change the mode of stdin to binary later on using plain Lua, you'll need a library for that. Something like lfs = require("lfs"); lfs.setmode(io.stdin, "binary") might work (using the LuaFileSystem library).
You could also try to fix your script invocation to set the correct mode using a script which changes stdin to binary mode before invoking your Lua script:
./stdbin.c:
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
int main(int argc, char** argv) {
if (argc < 1) {
printf("Arguments: <program> {args}\n");
return 1;
}
// See https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode?redirectedfrom=MSDN&view=msvc-170
if (_setmode(_fileno(stdin), _O_BINARY) == -1)
perror("_setmode failed");
execvp("lua", ++argv);
// execvp only returns if there is an error
perror("execvp failed");
return 1;
}
Note: Untested. Usage: ./stdbin lua count.lua.
(This is an addition to LMD's answer)
In LuaJIT no external libraries and executables are needed:
local ffi = require"ffi"
ffi.cdef"int _setmode(int,int)"
ffi.C._setmode(0, 0x8000)
-- Now io.read() will return binary data

How to print source file name with dladdr() function?

I was trying to print a backtrace using dladdr(). info.dli_fname in the following code snippet is displaying the file name of an ELF file. Could you please tell me if it is possible to resolve and print the name of the source file and line number programmatically without the help of addr2line or gdb?
Code:
void print_caller(void)
{
int rc = -1;
Dl_info info = {0};
void *pc = __builtin_return_address(0);
rc = dladdr(pc, &info);
printf(" ==> %p: %s (in %s)\n", pc, info.dli_sname, info.dli_fname);
}
Output:
$ ./a.out
==> 0x55a6b04a1589: foo2 (in ./a.out)
tell me if it is possible to resolve and print the name of the source file and line number programmatically
It is definitely possible -- addr2line and gdb do that.
But it is very non-trivial -- it requires understanding and decoding (possibly multiple) complicated debugging info formats.
If you only care about a single platform (looks like Linux), things are a bit easier -- you only need to decode DWARF.
But that format is still pretty complicated. You should start with a helper library, such as libdwarf.

The optimal way to set a breakpoint in the Python source code while debugging CPython by GDB

I use GDB to understanding how CPython executes the test.py source file and I want to stop the CPython when it starts the execution of opcode I am interested.
OS: Ubuntu 18.04.2 LTS
Debugger: GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
The first problem - many CPython's .py own files are executed before my test.py gets its turn, so I can't just break at the _PyEval_EvalFrameDefault - there are many of them, so I should distinguish my file from others.
The second problem - I can't set the condition like "when the filename is equal to the test.py", because the filename is not a simple C string, it is the CPython's Unicode object, so the standard GDB string functions can't be used for comparing.
At this moment I do the next trick for breaking the execution at the needed line of test.py source:
For example, I have the source file:
x = ['a', 'b', 'c']
# I want to set the breakpoint at this line.
for e in x:
print(e)
I add the binary left shift operator to the code:
x = ['a', 'b', 'c']
# Added for breakpoint
a = 12
b = 2 << a
for e in x:
print(e)
And then, track the BINARY_LSHIFT opcode execution in the Python/ceval.c file by this GDB command:
break ceval.c:1327
I have chosen the BINARY_LSHIFT opcode, because of its seldom usage in the code. Thus, I can reach the needed part of .py file quickly - it happens once in the all other .py modules executed before my test.py.
I look the more straightforward way of doing the same, so
the questions:
Can I catch the moment the test.py starts executing? I should mention, what the test.py filename is appearing on different stages: parsing, compilation, execution. So, it also will be good to can break the CPython execution at the any stage.
Can I specify the line of the test.py, where I want to break? It is easy for .c files, but is not for .py files.
My idea would be to use a C-extension, to make setting C-breakpoints possible in a python-script (similar to pdb.set_trace() or breakpoint() since Python3.7), which I will call cbreakpoint.
Consider the following python-script:
#example.py
from cbreakpoint import cbreakpoint
cbreakpoint(breakpoint_id=1)
print("hello")
cbreakpoint(breakpoint_id=2)
It could be used as follows in gdb:
>>> gdb --args python example.py
[gdb] b cbreakpoint
[gdb] run
Now, the debuger would stops at cbreakpoint(breakpoint_id=1) and cbreakpoint(breakpoint_id=2).
Here is proof of concept, written in Cython to avoid the otherwise needed boilerplate-code:
#cbreakpoint.pyx
cdef extern from *:
"""
long long last_breakpoint_id = -1;
void cbreakpoint(long long breakpoint_id){
last_breakpoint_id = breakpoint_id;
}
"""
void c_cbreakpoint "cbreakpoint"(long long breakpoint_id)
def cbreakpoint(breakpoint_id = 0):
c_cbreakpoint(breakpoint_id)
which can be build inplace via:
cythonize -i cbreakpoint.pyx
If Cython isn't installed, I have uploaded a version which doesn't depend on Cython (too much code for this post) on github.
It is also possible to break conditionally, given the breakpoint_id, i.e.:
>>> gdb --args python example.py
[gdb] break src/cbreakpoint.c:595 if breakpoint_id == 2
[gdb] run
will break only after hello was printed - at cbreakpoint with id=2 (while cbreakpoint with id=1 will be skipped). Depending on Cython version the line can vary, but can be found out once gdb stops at cbreakpoint.
It would also do something similar without any additional modules:
add breakpoint or import pdb; pdb.set_trace() instead of cbreakpoint
gdb --args python example.py + run
When pdb interrupts the program, hit Ctrl+C in order to interrupt in gdb.
Activate breakpoints in gdb.
continue in gdb and then in pdb (i.e. c+enter twice).
A small problem is, that after that the breakpoints might be hit while in pdb, so the first method is a little bit more robust.

Debugging with GDB - seeing code around a given breakpoint

I am trying to debug a C++ program using GDB. I have set 15 breakpoints. Most of the breakpoints are in different files. After the first 5 breakpoints, it became difficult to remember what line of code any given breakpoint refers to.
I struggle quite a bit simply trying to recall what a given breakpoint refers to. I find this quite distracting. I was wondering if there is a way to tell gdb to display code around a certain breakpoint.
Something like this - $(gdb) code 3 shows 30 lines of code around breakpoint 3. Is this possible today. Could you please show me how?
I run gdb in tui mode, and I also keep emacs open to edit my source files.
You can use gdb within emacs.
In emacs, type M-x gdb, after entering the name of the executable, type M-x gdb-many-windows. It brings up an IDE-like interface, with access to debugger, locals, source, input/output, stack frame and breakpoints.
You can find a reference and snapshot here.
I don't think you can do it exactly like this in gdb as such, but it can be scripted in gdb python.
This crude script should help:
import gdb
class Listbreak (gdb.Command):
""" listbreak n Lists code around breakpoint """
def __init__ (self):
super(Listbreak, self).__init__ ("listbreak", gdb.COMMAND_DATA)
def invoke (self, arg, from_tty):
printed = 0
for bp in gdb.breakpoints():
if bp.number == int(arg[0]):
printed = 1
print ("Code around breakpoint " + arg[0] + " (" + bp.location + "):")
gdb.execute("list " + bp.location)
if printed == 0:
print ("No such breakpoint")
Listbreak()
Copy this to listbreak.py, source it in gdb (source listbreak.py), then use it like this:
listbreak 2

How to set a breakpoint with lldb + mono

I have the following C# program (test.cs) which I want to debug:
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
Console.WriteLine( "Hello, World!" );
List<int> list = new List<int>();
list.Add(123);
list.Add(234);
list.Add(345);
list.Add(456);
int number = 4;
++number;
Console.WriteLine(" number " + number); // <--- L:16 I want to set a breakpoint here :)
Console.WriteLine("Number of elements" + list.Count);
foreach (Object obj in list)
{
Console.WriteLine(" " + obj);
}
Console.WriteLine("Bye");
}
}
And below is the debug session using lldb and mono (I am in OSX). I can start the session and run the program however I am not able to setup any breakpoint. I guess that when using mono as the executable file things are different. How can I achieve this?
$ mcs -debug test.cs
$ lldb
(lldb) target create mono
Current executable set to 'mono' (i386).
(lldb) b test.cs:16
Breakpoint 1: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
(lldb) run --debug test.exe
Process 15191 launched: '/usr/bin/mono' (i386)
Hello, World!
number 5
Number of elements4
123
234
345
456
Bye
Process 15191 exited with status = 0 (0x00000000)
(lldb)
I've tried with GBD as this old guide suggests but it is worse, apparently there is something broken in mono in OSX that makes it impossible to debug unless the soft debugger is used (which is exactly what I want to avoid. MonoDevelop debugger is really really unstable/unreliable/slow). This is what I have tried with GBD. No luck at all.
And help is appreciated.
Isn't mono the interpreter for your language and test.exe the binary? lldb only knows about mono -- any breakpoints you try to set would be in the mono interpreter. e.g. if you were debugging an issue with mono itself.
This is a unique enough environment that you'll need to do a little analysis to understand what lldb sees. What do you get for
(lldb) image list test.exe
? Of course if you do
(lldb) im li mono
You'll see mono listed -- because that's a binary that lldb knows about. (you can use plain image list aka im li to see all the binaries that lldb knows)
You can ask lldb to list all of the line table entries based on a source filename with a command line
(lldb) target modules dump line-table test.cs
if lldb has any debug information for a test.cs, you'll see a line table. Without a line table, file and line breakpoints (b test.cs:16) won't work.
For what it's worth, I don't think trying to use lldb (or gdb) to debug your C# program will work. You'll probably need to use some facility of the mono runtime itself to set breakpoints and examine program state.

Resources