reverse-php-malware icon indicating copy to clipboard operation
reverse-php-malware copied to clipboard

Not malware but contains good excercises for deobfuscating

Open gnanet opened this issue 5 years ago • 3 comments

Sample source code: https://malwaredecoder.com/result/0a2a7c5bb813d755f72823f2a5895ac8

this is the cleanup module of ai-bolit scanner and it is a great sample of obfuscation techniques.

Until the third run of deobfuscation, I was missing the point about using the magic constant __FILE__

$f000001 = basename(__FILE__); // 'procu2.php' 

This specific script relies in its obfuscation techniques only on the basename: procu2.php, but for the sake of completeness The full path and filename of the file is

/opt/psa/admin/plib/modules/revisium-antivirus/library/externals/procu2.php

Regarding the usage of __FILE__ I noticed a good solution in the linked malwaredecoder source

  1. the first issue, that reverse-php-malware and PHP-Parser could not solve on it's own, was a goto pair, that jumps in the middle of the code, sets the function alias variables, then jumps back to the beginning. Without the variable to function replacements lot of things cannot be further deobfuscated.

  2. the second issue, that needed manual help, was the usage of XOR operator, sometimes combined with variable concatenatiion, and string-part deobfuscation like base64_decode to generate the function-names

$f000000001 = "CDB" ^ "000"; // "str"
$a000000001 = $f000000001 . ("E]FDESE" ^ "1234567"); // "str" . "toupper" = "strtoupper"
$b000000001 = $f000000001 . '_repeat'; // "str" ."_repeat" = "str_repeat"
$d000000001 = ("P@AULi@YU" ^ "1234567890") . 'k'; // "array_wal".'k' = "array_walk"
$c000000001 = strlen($a000000001) - 4; // = 6
  1. the third issue, that had to be resolved manually, was caused by some introduced compexity: either the name of a variable, that represented a function, was concatenated a weird way, array_map("i1001" . '100100111100111', array('')); or one time for example, the multi level obfuscation generated a list of function names, that were called by array_walk in their order of appearance as an argument of a wrapper function, that processed a strongly obfuscated string recursively, to replace a combination of base64decode, compression, rot13, etc calls .
$f000000001 = 'str';
$a000000001 = 'strtoupper';
$b000000001 = 'str_repeat';
$d000000001 = 'array_walk';
$c000000001 = 6;
$e000000001 = 'i1001010100101001';
$f000001 = $a000000001($b000000001($f000001, $c000000001)); // $f000001 = strtoupper(str_repeat('procu2.php', 6));
$i01000010100 = $i0010100010101(",", $i00100001000100("MjM8JmMGcTQtMz82Km8ySEc+LjwxJipvJkZcDzo/JGN8byZGXCItJnwwLjAwBBoPLDUzPSsm") ^ $f000001); // explode(',', "base64_decode,gzinflate,str_rot13,strrev,base64_decode");
$d000000001($i01000010100, $e000000001); // array_walk(array('base64_decode','gzinflate','str_rot13','strrev','base64_decode'), i1001010100101001);

gnanet avatar Apr 21 '19 01:04 gnanet

@bediger4000 i have not the required knowhow to write the code for the above mentioned "manual interventions", but it would be great to know if you think these would be useful.

Also in that case i could try to learn into the subject, and try to write the code.

gnanet avatar Apr 26 '19 00:04 gnanet

Hello, thank you! I have had a lot to do at work, so I haven't taken a detailed look at what you wrote. None of your ideas look impossible. I will incorporate what I can after my job requirements ease up.

Again, thank you for your ideas and effort, and my apologies for being unavailable.

bediger4000 avatar Apr 26 '19 02:04 bediger4000

You don't need any apologies, I totally understand your priorities. I have these kind of restrictions too on my time on opensource projects. I am happy to see you think it's worth the code, so if i have any of them ready, i will make a PR referring to this issue, also if i am already started and deep into one of these ill get back, to let you know.

gnanet avatar Apr 29 '19 23:04 gnanet