Decoding gzinflate(base64_decode()) with Perl
I must admit that I love Perl, but sometimes it forces me to go through the documentation to get what I need. In this case, I will try to summarize how I managed to decode the text string 80jNyclXKM8vykkBAA==
, which I found in a PHP file in a code with the nested functions gzinflate(base64_decode())
.
The history.
I found this text string while analyzing the folder /wp-content/
into blog www.vozidea.com, which according to its owner, it seems that someone left that file there during a time when the web had a vulnerable WordPress plugin with security issues.
That string was something disturbing for the administrator of the blog, a person outside the programming. But in reality it is very easy to decode using PHP, the following code would suffice:
<?php echo gzinflate(base64_decode('80jNyclXKM8vykkBAA==')); ?>
Decoding the strings.
In any case, the objective was to create a small scanner written in Perl, so it can verify the existence of this type of strings encoded with Base64 and Gzip, under the WordPress files. Here we are not going to address the code of this scanner, but we are going to focus on the decoding task of the function gzinflate(base64_decode()) with Perl.
The problem was that the Zlib module used by Perl needs to be instructed to use a data stream according to RFC 1951. The trick was to use the option -WindowBits => -MAX_WBITS
with the compression and decompression interfaces.
The following code in Perl speaks for itself:
#!/usr/bin/perl use strict; use warnings; use MIME::Base64; use Compress::Zlib; my $code = "Hello world"; # Encode string with base_64. my $b64 = encode_base64($code, ''); print "Encoded string with base_64: " . $b64 . "\n\n"; # Compress with deflate and then encode with base 64. my $bufer; my $d = deflateInit( -WindowBits => -MAX_WBITS); $bufer = $d->deflate($code); $bufer .= $d->flush(); my $out = encode_base64($bufer, ''); print "Encoded and compressed string: " . $out . "\n\n"; # Decode string with base_64. my $b64decoded = decode_base64($b64); print "Decode string with base_64: " . $b64decoded . "\n\n"; # Decompres with deflate and then decode with base_64. my $compresseddata = decode_base64($out); my $i = inflateInit( -WindowBits => -MAX_WBITS); my $bufer2; while ($compresseddata) { $bufer2 .= $i->inflate($compresseddata); } print "Decoded and decompressed data: " . $bufer2 . "\n\n";
The routine "inflate_raw" from my module Gzip::Faster does this action as well, without the complicated -WindowBits stuff:
https://metacpan.org/pod/distribution/Gzip-Faster/lib/Gzip/Faster.pod#inflate_raw
If using it with the above routine, be sure to call it before the "inflate" above, since, as we can see from the while ($compresseddata), apparently "inflate" messes with its parameters.