PHP real-time system command output

Throwing some notes here for me to remember on having PHP not buffer the output of a long running process so that it provides realtime output to the browser. I tinkered with SSE options and even AJAX/jQuery, but I finally got this to somewhat work reliably. Note that these notes are tested on PHP 8.1 and Apache 2.4.

.htaccess

This is required to disable buffering at the server level. Make sure to have mod_rewrite enabled.

RewriteRule ^(.*)$ $1 [NS,E=no-gzip:1,E=dont-vary:1]

PHP

<?php
ob_implicit_flush(true);
ob_end_flush();

echo 'Begin', PHP_EOL;


for ($i = 0; $i < 10; $i++) {
echo $i, PHP_EOL;
ob_flush();
flush();

sleep(1);
}

echo 'Done', PHP_EOL;

A command example using passthru

<?php
ob_implicit_flush(true);
ob_end_flush();
echo '<PRE>';
echo 'BEGIN',PHP_EOL;
passthru('ping -c 5 8.8.8.8');
ob_flush();
flush();
echo 'DONE', PHP_EOL;
?>

Bulk change PHP memory_limit across all installed PHP versions

On my server, I have PHP 5.6 to 8.1 installed and use the versions for various testing purposes.

To change the memory_limit across all versions as simply as possible instead of editing each file, I use the following command.

find /etc/php -iname 'php.ini' -exec sed -i 's/memory_limit = .*/memory_limit = 512M/g' {} \;

Fail2ban + fail2sql + Ban Hammer + PHP7

width=625

I recently revisited a project from some time ago that I found and modified the code to support PHP7 which dropped support for mysql extension in favor of mysqli.

If you’re interested, I’ll attach the zip file https://github.com/rjkreider/banhammer.   I mainly just hacked it up and added i to mysql_ functions.  Modified mysql_numrows to mysqli_num_rows and also fixed the constant MYSQL_NUM to MYSQLI_NUM and a few other tweaks in fail2sql.

Note that these are just the ban hammer HTML/PHP files, not fail2sql, so you’ll need to still grab fail2sql and get that setup. I do include fail2sql in my repo with the modified PHP now.

Part 1: Analysis of a WordPress Malware

I had some time at lunch to kill, so I decided to see how Malware techniques were improving in the land of WordPress and free premium theme download sites.

Enter the Darknet.

A simple Google search got me a theme ZIP file pretty quickly.  Now, it was time to see what malicious happenings this thing would cause.
Unpacked, here’s the structure of the ZIP file.

.
├── functions.php
├── home.php
├── images
│   ├── arrow.png
│   ├── bg-pattern.png
│   ├── bg.png
│   ├── blockquote.png
│   ├── blue
│   │   ├── gradient.png
│   │   ├── logo.png
│   │   ├── logo-texture.png
│   │   ├── logo-vert-left.png
│   │   └── logo-vert-right.png
│   ├── favicon.ico
│   ├── footer-twitter.png
│   ├── footer-widgets.png
│   ├── gradient.png
│   ├── green
│   │   ├── gradient.png
│   │   ├── logo.png
│   │   ├── logo-texture.png
│   │   ├── logo-vert-left.png
│   │   └── logo-vert-right.png
│   ├── icon-dot.png
│   ├── list-after-post.png
│   ├── list.png
│   ├── logo.png
│   ├── logo-texture.png
│   ├── logo-vert-left.png
│   ├── logo-vert-right.png
│   ├── red
│   │   ├── gradient.png
│   │   ├── logo.png
│   │   ├── logo-texture.png
│   │   ├── logo-vert-left.png
│   │   └── logo-vert-right.png
│   ├── rss.png
│   ├── social-icons.png
│   └── twitter-nav.png
├── page_landing.php
├── page_landing2.php
├── README.txt
├── screenshot.png
└── style.css

Right off the bat, page_landing2.php sticks out to me. Let’s take a look.



Oh. Would you look at that fun. Time to see what this is doing.
First, I don’t like trying to read the garbled code, so I “prettify” it.


Ok, so let’s decode the above to make it readable.

There are a few interesting pieces here.



These interest me because they are making a call to a website to get additional payload/scripts. Let’s see what they are. =)

The first one, pastebin link, shows me this garbled shit. What I really care about is the compressed base64 at the end.


So, now I look to deobfuscating the compressed/base64 garbage… Here’s part of the file, my screencapture died when my computer automatically locked; [FIXME]

NOTE: Click on the image for a higher resolution. It’s like 62k pixels tall, lol.
 
What I’m interested in is the top of this file.


So again, uncompressing the base64 encoding of that gives me the following file.


Going back for a minute the the previous garbled shit $plsym variable which contains the compressed/base64 is decompressed and unencoded and saved as a perl file.


At this point, I have everything I need to begin to follow this even deeper into the dark underworld. There are a few domains (which I didn’t highlight in this article, but you can find them in the screenshots) and some passwords.

Stay tuned… in the next update, I show you what happens when I infiltrate their command servers. Much fun!

PHP Easter Eggs

To honor Easter, I’ve decided to put this little tidbit of information up. These are PHP easter eggs.  I had no idea these existed until I was running a security scan using Detectify.  This information can be considered to be a vulnerability since it could be used to obtain specific server information/versions and use that version as a reference to look up exploits against PHP, the server, etc.
You can use these by visiting your site, or another site, and using them in the URI:

http://www.example.com/?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000

PHP Credits (phpinfo):
PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000
PHP Logo:
PHPE9568F34-D428-11d2-A769-00AA001ACF42
Zend Logo:
PHPE9568F35-D428-11d2-A769-00AA001ACF42
Easter Egg (animals and a guy):
PHPE9568F36-D428-11d2-A769-00AA001ACF42