CSC 382: Computer Security Command Injection CSC 382: Computer Security
CSC 382: Computer Security Topics Processes fork() exec() system() and popen() CSC 382: Computer Security
CSC 382: Computer Security Processes A process is a program in execution. Each process has a unique identifier, its PID. Each process was created by a parent process. Except PID 1, the init process, which is started on boot. CSC 382: Computer Security
CSC 382: Computer Security Process Tree CSC 382: Computer Security
CSC 382: Computer Security Process Tree > ptree -a 1 /etc/init - 156 /usr/sbin/inetd -s 20190 in.telnetd 20192 -csh 20200 telnet nkuadm.nku.edu 20369 in.telnetd 20371 -sh 345 /usr/lib/ssh/sshd 18475 /usr/lib/ssh/sshd 18477 -bash 20637 ptree -a CSC 382: Computer Security
CSC 382: Computer Security PIDs #include <stdio.h> #include <unistd.h> int main (int argc, char *argv[]) { printf(“My PID is %ld\n", (long)getpid()); printf("My parent’s PID is %ld\n", (long)getppid()); return 0; } > gcc -ansi -pedantic -Wall -o outputPID outputPID.c > ./outputPID My PID is 20737 My parent’s PID is 18477 CSC 382: Computer Security
CSC 382: Computer Security Process State Diagram CSC 382: Computer Security
Process States: ps output # ps -aux USER PID %CPU %MEM SZ RSS S START TIME COMMAND root 3 0.5 0.0 0 0 S Jun 16 5:40 fsflush root 20790 0.2 0.2 1104 776 O 16:38:50 0:00 ps -aux root 18475 0.1 0.6 4536 2704 S 12:50:56 0:02 sshd waldenj 18477 0.1 0.5 2680 2064 R 12:51:01 0:00 -bash root 0 0.0 0.0 0 0 T Jun 16 0:00 sched Process States O Running R Runnable (in the run queue) S Sleeping T Stopped Z Zombie (terminated but parent not waiting) CSC 382: Computer Security
Process Creation: fork() A process calls fork() to create a new process. fork() copies process memory image so that new process is copy of original process fork() returns twice 0 in child child PID in parent Child finishes with exit() Fork parent Fork child Wait Exit CSC 382: Computer Security
CSC 382: Computer Security fork() example #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main(int argc, char *argv[]) { pid_t childpid; childpid = fork(); if (childpid == -1) { perror("Failed to fork"); return 1; } if (childpid == 0) /* child executes the next statement */ printf("I am child %ld\n", (long)getpid()); else /* parent executes the next statement */ printf("I am parent %ld\n", (long)getpid()); return 0; CSC 382: Computer Security
CSC 382: Computer Security fork() example > gcc -ansi -pedantic -Wall -o twoprocs twoprocs.c > ./twoprocs I am child 20830 I am parent 20829 Order dependent on current user activity. CSC 382: Computer Security
Running different code with exec() exec() overlays process image of calling process with a new image from disk. Typically the child process performs an exec() while the parent waits for it to complete. CSC 382: Computer Security
CSC 382: Computer Security execl() function #include <unistd.h> int execl(const char *path, const char *arg0, ..., const char *argn, char * /*NULL*/); execl() overlays the process with the image specified by path and invokes the program with the arguments arg0 through argn. CSC 382: Computer Security
exit() and wait() functions #include <sys/types.h> #include <sys/wait.h> pid_t wait(int *stat_loc); wait() causes caller to suspend execution until a child process completes. wait() returns the child PID that returns first or -1 if it fails. CSC 382: Computer Security
CSC 382: Computer Security fork/exec example #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main(int argc, char *argv[]) { pid_t childpid = fork(); if (childpid == -1) { perror("Failed to fork"); return 1; } if (childpid == 0) { /* child executes this block */ execl("/bin/ls", "ls", "-l", NULL); perror("Child failed to exec ls"); exit(1); if (childpid != wait(NULL)) { /* parent executes this block */ perror("Parent failed to wait due to signal or error"); return 0; CSC 382: Computer Security
system(): ease of use w/o security #include <stdlib.h> int system(const char *string); Invokes a shell and issues the shell command specified by string. CSC 382: Computer Security
CSC 382: Computer Security system() example #include <stdlib.h> #include <stdio.h> #include <sys/wait.h> int main(int argc, char *argv[]) { int status; if ((status = system("date")) < 0) perror("system() error"); if ((status = system("nosuchcommand")) < 0) if ((status = system("who")) < 0) return 0; } CSC 382: Computer Security
CSC 382: Computer Security system example() > gcc -ansi -pedantic -Wall -o systest systest.c > ./systest Mon Sep 26 18:08:20 EDT 2005 sh: nosuchcommand: not found waldenj pts/10 Sep 26 12:51 (10.32.11.77) halla pts/2 Sep 26 15:59 (foo.bar.com) newella pts/5 Sep 26 15:42 (172.16.18.153) longa pts/11 Sep 22 12:18 (10.32.13.102) CSC 382: Computer Security
Code Injection Attacks Attacker sends data to entry point Data flows through application until… …a subsystem interprets it as code. Subsystem could be Command shell SQL database Language interpreter CSC 382: Computer Security
CSC 382: Computer Security Shell Injection Find program that invokes a subshell command with user input such as system(). Use shell meta-characters to insert user-defined code into the command. CSC 382: Computer Security
CSC 382: Computer Security Shell Metacharacters `command` will execute command ; separates commands | creates a pipe between two commands && and || are logical operators which may execute following command ! logical negation—reverses truth value of test - could convert filename into an argument * and ? glob, matching files, which may be interpreted as args: what if “-rf” is file? # comments to end of line CSC 382: Computer Security
CSC 382: Computer Security Shell Injection in C /* Mail to root with user-defined subject */ int main( int argc, char **argv ) { char buf[1024]; sprintf( buf, “/bin/mail –s %s root </tmp/message”, argv[1] ); system( buf ); } CSC 382: Computer Security
CSC 382: Computer Security Shell Injection in C How to exploit? ./mailprog \`/path/to/hacked_bin\` /path/to/hacked_bin will be run by mailprog How to fix? Best solution: Avoid invoking a shell. Use fork() and exec() to run /bin/mail without invoking a shell. CSC 382: Computer Security
CSC 382: Computer Security Not just C/UNIX C/C++ on Windows ShellExecute() family of functions Java Runtime.exec() function Perl system() open() with | operator CSC 382: Computer Security