CIS 4615 meeting -*- Outline -*- * Command Injection Based on chapter 10 of the book: 24 Deadly Sins of Software Security by M. Howard, D. LeBlanc, and J. Viega (McGraw-Hill, 2010). ** attack ------------------------------------------ ATTACK OVERVIEW 1. find/guess where input is 2. provide input that Example: /* IRIX login screen printing */ char buf[1024]; snprintf(buf, "system lpr -P %s %s", users_printer, doc_selection, sizeof(buf)-1); system(buf); ------------------------------------------ ... being passed to an interpreter (like the shell) via string concatenation ... does more than expected (executes a general command) Q: What's this like that we have seen before? SQL injection attacks Q: In the example, what could happen? users_printer could be not just a name, but also a command, like: FRED /dev/null; xterm & which starts xterm (a graphical shell) running, with administrative privileges! ------------------------------------------ AFFECTED LANGUAGES Any language that can call an interpreter Perl, Ruby, Python prone because easy to pass commands to shell Python example: def call_func(user_input, system_data): exec 'special_function_%s("%s")' % (system_data, user_input) ------------------------------------------ Q: What does the Python code do? It should call a function passing it user data, but if the user input is fred"); print ("foo then it will print foo, but could do anything! ** summary ------------------------------------------ SUMMARY Like SQL injection, the problem is: - using untrusted - using concatenation instead of Problem symptoms: - mixing commands with - running ------------------------------------------ ... input without validation ... parsing ... user data ... interpreter as a privileged user ** remediation *** code review ------------------------------------------ CODE REVIEW Track Validate all Never run Find calls to ------------------------------------------ ... user input (taint tracking) ... user input (by parsing) ... a command interpreter! ... command processors like: language construct C/C++ system, popen, execlp, execvp C/C++ ShellExecute() family Perl System, Exec, `...`, Perl open("| ..."), | operator Perl eval, regular expression /e operator Python exec eval Python execfile Python input (equivalent to eval(raw_input())!) Python compile JavaScript eval Java Class.forName Java Class.newInstance Java Runtime.exec("/bin/sh ...") *** other measures ------------------------------------------ OTHER DEFENSIVE MEASURES Run app using least privilege Be conservative, use an "allow only" approach, not a Use taint mode in Perl and Ruby ------------------------------------------ ... "deny these" approach Q: Why is an allow list approach better than a deny list? Because if someone has a problem they will complain, but attackers won't mind if you don't know about their attack.