Reverse Engineering

Ini semua tentang Reverse Engineering

by invalid

Tutorial ini akan membahas cara melakukan dekripsi script yang diproteksi/dienkripsi menggunakan phpobfuscator v02 buatan eddiekidiw. Script yang diproteksi menggunakan phpobfuscator buatan eddiekidiw tersebut mudah dikenali, karena terdapat informasi berikut ini pada bagian awal script:

PHPObfuscator v02 Header

Adapun script sumber yang digunakan pada tutorial ini dapat ditemukan pada situs pastebin dan sempat ditanyakan pada group ReversingID di facebook. Fungsi yang pertama perlu diperhatikan pada script target tersebut adalah sebagai berikut:

function mMNvvEVymAgRePPCQTBW($eWgIMwgeaVJKlxFGZzms) {
    $KpNUuBTGtuUzqIxFpcaF  = "\x63";
    $KpNUuBTGtuUzqIxFpcaF .= chr(104);
    $KpNUuBTGtuUzqIxFpcaF .= "\x72";
    return $KpNUuBTGtuUzqIxFpcaF($eWgIMwgeaVJKlxFGZzms);
}

Fungsi tersebut jika diterjemahkan akan menjadi:

function mMNvvEVymAgRePPCQTBW($param_1) {
    return chr($param_1);
}

Dengan mengetahui fungsi di atas, maka kita dapat menerjemahkan beberapa fungsi-fungsi lainnya, yaitu fungsi berikut ini:

function EEJYxbdYfliEfzYGianf($param_1) {
    return base64_encode($lATPVCnqngAikfNYlSAn);
}

function eJAjizPqzdwLPjhkNcJa($param_1) {
    return file_get_contents($param_1);
}

function HrEwBLHpOqprghaLNkin($param_1) {
    return base64_decode($param_1);
}

Dari informasi di atas, kita dapat menerjemahkan atau melakukan deobfuscate terhadap fungsi ini:

function yBKNzmsSJmhWCPwnvSFv($nbgaxEMcWHQUFrSBUftB) {
    $xGWuLONTtDbsEuIyvKSj = '';
    $VvHQucMxatkkrTHLAOhQ = '';
    $UeFFOgeBcmvzTsUFgHyA = __FILE__;
    $UeFFOgeBcmvzTsUFgHyA = eJAjizPqzdwLPjhkNcJa($UeFFOgeBcmvzTsUFgHyA);
    $HByeNdvKgBxcXfSshFQi = 0;

    preg_match(HrEwBLHpOqprghaLNkin('LyhwcmludHxzcHJpbnR8ZWNobykv'),$UeFFOgeBcmvzTsUFgHyA,$HByeNdvKgBxcXfSshFQi);

    if (count($HByeNdvKgBxcXfSshFQi)) {
        while(0x125 != 0x836) {
            $YatqUabuOjlwLKAyNViU = mMNvvEVymAgRePPCQTBW(85892);
        }
    }

    $jXJwuGgvqTtHwlErWdfN = ceil(strlen($nbgaxEMcWHQUFrSBUftB)/3)*3;
    $rDSWULyOQRqTVYuWcYGM = str_pad($nbgaxEMcWHQUFrSBUftB,$jXJwuGgvqTtHwlErWdfN,'0',STR_PAD_LEFT);

    for ($cdIBbeDKJlqXmxXKbJMX = 0; $cdIBbeDKJlqXmxXKbJMX < (strlen($rDSWULyOQRqTVYuWcYGM)/3); $cdIBbeDKJlqXmxXKbJMX++) {
        $VvHQucMxatkkrTHLAOhQ .= mMNvvEVymAgRePPCQTBW(substr(strval($rDSWULyOQRqTVYuWcYGM),$cdIBbeDKJlqXmxXKbJMX*3,3));
    }
    return$VvHQucMxatkkrTHLAOhQ;
}

Fungsi di atas, jika di-deobfuscate, maka hasilnya kurang lebih seperti ini:

function yBKNzmsSJmhWCPwnvSFv($param_1) {
    $v_0 = '';
    $v_1 = '';
    $v_2 = __FILE__;
    $v_2 = file_get_contents($v_2);
    $v_3 = 0;

    preg_match('/(print|sprint|echo)/',$v_2,$v_3);

    if (count($v_3)) {
        while(0x125 != 0x836) {
            $v_4 = chr(85892);
        }
    }

    $v_5 = ceil(strlen($param_1)/3)*3;
    $v_6 = str_pad($param_1,$v_5,'0',STR_PAD_LEFT);

    for ($i = 0; $i < (strlen($v_6)/3); $i++) {
        $v_1 .= chr(substr(strval($v_6),$i*3,3));
    }
    return $v_1;
}

Bisa terlihat bahwa fungsi tersebut berisi jebakan betmen, dimana terdapat infinite loop jika terdapat string print, sprint, atau echo pada file yang sedang dijalankan. Oleh karena itu, kita harus membersihkan fungsi di atas agar dapat digunakan. Berikut ini adalah bentuk fungsi di atas yang telah bersih dari jebakan betmen :

function yBKNzmsSJmhWCPwnvSFv($param_1) {
    $v_1 = '';
    $v_5 = ceil(strlen($param_1)/3)*3;
    $v_6 = str_pad($param_1,$v_5,'0',STR_PAD_LEFT);

    for ($i = 0; $i < (strlen($v_6)/3); $i++) {
        $v_1 .= chr(substr(strval($v_6),$i*3,3));
    }
    return $v_1;
}

Dengan demikian, kita dapat melanjutkan dengan beberapa baris pada bagian awal skrip yang memanggil fungsi tersebut. Berikut ini adalah baris yang dimaksud:

$BpyjIrBGjCInEHMzNuDP = yBKNzmsSJmhWCPwnvSFv('088116101097');
$sjCqOLgxQbxrrWAancHw = yBKNzmsSJmhWCPwnvSFv('116114105109');
$FqKjYwIMQmBjwezlQGJG = yBKNzmsSJmhWCPwnvSFv('101110099114121112116');
$HgXZcyaqBHMgXwqVTZIK = new $BpyjIrBGjCInEHMzNuDP(yBKNzmsSJmhWCPwnvSFv('053097099055100055054053052099102053097057055049054048057054052098055099097048048101050098054051'));

@eval($sjCqOLgxQbxrrWAancHw($HgXZcyaqBHMgXwqVTZIK->$FqKjYwIMQmBjwezlQGJG('W/PS7 ... srbv3I=')));

Berikut ini adalah hasil dari 4 baris di atas setelah di-deobfuscate:

$v_xtea = new Xtea('5ac7d7654cf5a97160964b7ca00e2b63');
@eval(trim($v_xtea->encrypt('W/PS7 ... srbv3I=')));

Dan pada class Xtea itu sendiri terdapat beberapa jebakan betmen juga. Berikut ini adalah jebakan yang dimaksud:

$ljTIotTeZCKHIIGLgGbI = __FILE__;
$ljTIotTeZCKHIIGLgGbI = file_get_contents($ljTIotTeZCKHIIGLgGbI);

if (((strpos($ljTIotTeZCKHIIGLgGbI,base64_decode('KSk7ZXJyb3JfcmVwb3J0aW5nKDApO0BldmFsKCRzakNxT0xneFFieHJyV0FhbmNIdygkSGdYWmN5YXFCSE1nWHdxVlRaSUstPiRGcUtqWXdJTVFtQmp3ZXpsUUdKRw=='))!==false&&strpos($ljTIotTeZCKHIIGLgGbI,base64_decode('JFVlRkZPZ2VCY212elRzVUZnSHlBPV9fRklMRV9fOyRVZUZGT2dlQmNtdnpUc1VGZ0h5QT1lSkFqaXpQcXpkd0xQamhrTmNKYSgkVWVGRk9nZUJjbXZ6VHNVRmdIeUEpOyRIQnllTmR2S2dCeGNYZlNzaEZRaT0wO3ByZWdfbWF0Y2goSHJFd0JMSHBPcXByZ2hhTE5raW4oJ0x5aHdjbWx1ZEh4emNISnBiblI4WldOb2J5a3YnKSwkVWVGRk9nZUJjbXZ6VHNVRmdIeUEsJEhCeWVOZHZLZ0J4Y1hmU3NoRlFpKTtpZihjb3VudCgkSEJ5ZU5kdktnQnhjWGZTc2hGUWkpKXt3aGlsZSgweDEyNSE9MHg4MzYpeyRZYXRxVWFidU9qbHdMS0F5TlZpVT1tTU52dkVWeW1BZ1JlUFBDUVRCVyg4NTg5Mik7fX0='))!==false)?1:0))

Selain itu, fungsi encrypt dan decrypt sepertinya sengaja dibalik namanya oleh pembuat phpobfuscator v02 tersebut. Karena implementasi class Xtea yang digunakan relatif sama dengan script yang dapat ditemukan pada github, maka cukup mudah untuk melakukan dekripsi. Caranya adalah:

  • Temukan key enkripsi dengan menggunakan fungsi yang terdapat pada bagian bawah script.
  • Inisialisasi class Xtea menggunakan key tersebut.
  • Lakukan dekripsi dengan memanggil fungsi Xtea->encrypt menggunakan parameter berupa string yang diencode menggunakan base64.

Selanjutnya, Anda dapat menjalankan script tersebut dan menyimpan hasil dekripsinya ke file dengan perintah seperti ini:

$ php -f UHmwMsL2.php > decrypted.php

Hasilnya adalah script yang masih ter-obfuscate dan di dalamnya banyak terdapat karakter non-printable seperti ini:

?><?php $__¹ÐÐر¿å±àæàؼ†="\146";
//--snip--
@eval($__
//--snip--
($_SERVER['SCRIPT_FILENAME'])))),"b5fdbf744bbd3ad469760be7f8498799352613e3")?
//--snip--
("s7ezsS/IKODlSk3OyFdQ8kjNyclXKM8vyklRUFSyRhV2Kc3LTIQI29sBAA==")));?>

Jangan khawatir, jika kita mengubah nama setiap variabel yang menggunakan karakter non-printable tersebut, maka scriptnya akan terlihat lebih jelas. Berikut ini adalah script tersebut jika variabel yang menggunakan karakter non-printable sudah diganti:

<?php
$__aaa="\146";
$__bbb="\x67";
$__ccc="\x73";
$__ddd="\160";
$__eee="\x73";
$__fff="\142";
$__ccc.="\x74";
$__eee.="\x68";
$__fff.="\141";
$__aaa.="\x69";
$__bbb.="\172";
$__ddd.="\162";
$__aaa.="\154";
$__bbb.="\151";
$__ddd.="\x65";
$__fff.="\x73";
$__eee.="\141";
$__ccc.="\162";
$__fff.="\x65";
$__bbb.="\x6e";
$__ddd.="\x67";
$__aaa.="\x65";
$__ccc.="\143";
$__eee.="\x31";
$__aaa.="\x5f";
$__ddd.="\x5f";
$__bbb.="\146";
$__ccc.="\x6d";
$__fff.="\x36";
$__bbb.="\154";
$__ddd.="\162";
$__ccc.="\x70";
$__fff.="\64";
$__aaa.="\147";
$__aaa.="\x65";
$__bbb.="\x61";
$__fff.="\x5f";
$__ddd.="\x65";
$__aaa.="\x74";
$__ddd.="\160";
$__fff.="\x64";
$__bbb.="\164";
$__fff.="\145";
$__ddd.="\x6c";
$__aaa.="\x5f";
$__bbb.="\x65";
$__fff.="\x63";
$__aaa.="\143";
$__ddd.="\x61";
$__fff.="\157";
$__ddd.="\x63";
$__aaa.="\157";
$__fff.="\144";
$__aaa.="\156";
$__ddd.="\x65";
$__fff.="\145";
$__aaa.="\x74";
$__aaa.="\145";
$__aaa.="\x6e";
$__aaa.="\164";
$__aaa.="\163";
@eval($__ccc($__eee($__ddd("\x2f\15\x7c\12\x2f","",$__ddd("\x2F\x5C\x2A\x5C\x2A\x5C\x2A\x5C\x2F\x5C\x6E\x2B\x28\x2E\x2A\x29\x2F","\x2A\x2A\x2A\x2F",$__aaa($_SERVER['SCRIPT_FILENAME'])))),"b5fdbf744bbd3ad469760be7f8498799352613e3")?$__bbb($__fff("tZNtT9swEMe/yi0vVpDWuOkGgpBmYrSMvBggWglNqoQu8ZW4dezMdmD99nPSFsEktmnTXsSy7y7/e/DPVJR6ry7rO4u1uFNY0d7+aNQrpOh9DOZqdpFNYXp2k13P4OJ0Cp8mk0v4cjXOzrPJOJyrubo9vbnMLj/P1UTdS2HLGDIwVAnFYa0b4BqUdkBcOHClsGALI2q/14APWnAgY7SxXipTXCuyAmOY4hqhInUv1D26FSo4VRyhUa5ZgRMcV523E7UrrwdCia27dZQ+OxoBK7IosUTVVTp7lt7vSHVb4nM1RkcxzBqyHNfvhoPoqB9F/eEAosN4eBAP3s/VudEVZHUM0dEwHITR4UEYHQ9b2SDuJW/GV2ezr9cTKF0l02S7EvI0kUKt/EDkKLBuLcmWRC6A0tBiFJTO1TZmrOBqacNC6oYvJBoKC10xXOJ3JkVumXsUzpHp51o76wzW7EMYhRErrGVPttCPPPSWAFiabLu0pvjjJMtvDZk1i8Jjr7w5dJJLG6QJ2wimiRNOUvp8kiVayIkUVJqLhSCesE1QwjYDyDVfpwkXD1BItHYUFFo5FIpM8MKMkoyDbu3barvh6K/Z7A7CVsJakUuCBXICW+rHAIyWtP09+E1pufH1pLdolCcrYXnaWv4N3FYB/iu7bYbX2AWtwHf0C3TbLuGJXh/7AuBuBrjFcYkPuMkRtx3uDfaDpzuT2lIAHB3urmE3cvDVYl9i3jJ+1sV5AGvfeOcoBeekRoEzjXe8daIie+KB8gEeEfSfZ2C3/gW3rz2O5c9v4yXIbIMl655qb//kBw==")):$__bbb($__fff("s7ezsS/IKODlSk3OyFdQ8kjNyclXKM8vyklRUFSyRhV2Kc3LTIQI29sBAA==")));
?>

Nah, sekarang lebih mudah terbaca bukan? Namun agar lebih jelas lagi, kita akan mengganti setiap variabel tersebut dengan nama fungsi yang seharusnya. Caranya cukup mudah, yaitu seperti ini:

<?php
$__aaa="\146";
$__bbb="\x67";
$__ccc="\x73";
$__ddd="\160";
$__eee="\x73";
$__fff="\142";
$__ccc.="\x74";
$__eee.="\x68";
$__fff.="\141";
$__aaa.="\x69";
$__bbb.="\172";
$__ddd.="\162";
$__aaa.="\154";
$__bbb.="\151";
$__ddd.="\x65";
$__fff.="\x73";
$__eee.="\141";
$__ccc.="\162";
$__fff.="\x65";
$__bbb.="\x6e";
$__ddd.="\x67";
$__aaa.="\x65";
$__ccc.="\143";
$__eee.="\x31";
$__aaa.="\x5f";
$__ddd.="\x5f";
$__bbb.="\146";
$__ccc.="\x6d";
$__fff.="\x36";
$__bbb.="\154";
$__ddd.="\162";
$__ccc.="\x70";
$__fff.="\64";
$__aaa.="\147";
$__aaa.="\x65";
$__bbb.="\x61";
$__fff.="\x5f";
$__ddd.="\x65";
$__aaa.="\x74";
$__ddd.="\160";
$__fff.="\x64";
$__bbb.="\164";
$__fff.="\145";
$__ddd.="\x6c";
$__aaa.="\x5f";
$__bbb.="\x65";
$__fff.="\x63";
$__aaa.="\143";
$__ddd.="\x61";
$__fff.="\157";
$__ddd.="\x63";
$__aaa.="\157";
$__fff.="\144";
$__aaa.="\156";
$__ddd.="\x65";
$__fff.="\145";
$__aaa.="\x74";
$__aaa.="\145";
$__aaa.="\x6e";
$__aaa.="\164";
$__aaa.="\163";

echo "aaa = $__aaa\nbbb = $__bbb\nccc = $__ccc\nddd = $__ddd\neee = $__eee\nfff = $__fff\n";
?>

Simpan potongan kode di atas (misalnya dengan nama skidipap.php) lalu jalankan:

$ php -f skidipap.php
aaa = file_get_contents
bbb = gzinflate
ccc = strcmp
ddd = preg_replace
eee = sha1
fff = base64_decode

Itu dia nama fungsi yang digunakan pada script tersebut, dan setelah mengganti variabel yang berkaitan dengan nama fungsi tersebut, hasilnya seperti ini:

<?php
@eval(strcmp(sha1(preg_replace("/\15|\12/","",preg_replace("/\*\*\*\/\n+(.*)/","***/",file_get_contents($_SERVER['SCRIPT_FILENAME'])))),"b5fdbf744bbd3ad469760be7f8498799352613e3")?gzinflate(base64_decode("tZNtT9swEMe/yi0vVpDWuOkGgpBmYrSMvBggWglNqoQu8ZW4dezMdmD99nPSFsEktmnTXsSy7y7/e/DPVJR6ry7rO4u1uFNY0d7+aNQrpOh9DOZqdpFNYXp2k13P4OJ0Cp8mk0v4cjXOzrPJOJyrubo9vbnMLj/P1UTdS2HLGDIwVAnFYa0b4BqUdkBcOHClsGALI2q/14APWnAgY7SxXipTXCuyAmOY4hqhInUv1D26FSo4VRyhUa5ZgRMcV523E7UrrwdCia27dZQ+OxoBK7IosUTVVTp7lt7vSHVb4nM1RkcxzBqyHNfvhoPoqB9F/eEAosN4eBAP3s/VudEVZHUM0dEwHITR4UEYHQ9b2SDuJW/GV2ezr9cTKF0l02S7EvI0kUKt/EDkKLBuLcmWRC6A0tBiFJTO1TZmrOBqacNC6oYvJBoKC10xXOJ3JkVumXsUzpHp51o76wzW7EMYhRErrGVPttCPPPSWAFiabLu0pvjjJMtvDZk1i8Jjr7w5dJJLG6QJ2wimiRNOUvp8kiVayIkUVJqLhSCesE1QwjYDyDVfpwkXD1BItHYUFFo5FIpM8MKMkoyDbu3barvh6K/Z7A7CVsJakUuCBXICW+rHAIyWtP09+E1pufH1pLdolCcrYXnaWv4N3FYB/iu7bYbX2AWtwHf0C3TbLuGJXh/7AuBuBrjFcYkPuMkRtx3uDfaDpzuT2lIAHB3urmE3cvDVYl9i3jJ+1sV5AGvfeOcoBeekRoEzjXe8daIie+KB8gEeEfSfZ2C3/gW3rz2O5c9v4yXIbIMl655qb//kBw==")):gzinflate(base64_decode("s7ezsS/IKODlSk3OyFdQ8kjNyclXKM8vyklRUFSyRhV2Kc3LTIQI29sBAA==")));
?>

Ternyata script tersebut membandingkan nilai hash SHA1 script yang telah di-obfuscate dengan nilai yang valid. Dan jika hasilnya tidak sama, maka akan muncul pesan yang telah dikompres dan diencode menggunakan base64, yaitu pesan ini:

gzinflate(base64_decode("tZNtT9swEMe/yi0vVpDWuOkGgpBmYrSMvBggWglNqoQu8ZW4dezMdmD99nPSFsEktmnTXsSy7y7/e/DPVJR6ry7rO4u1uFNY0d7+aNQrpOh9DOZqdpFNYXp2k13P4OJ0Cp8mk0v4cjXOzrPJOJyrubo9vbnMLj/P1UTdS2HLGDIwVAnFYa0b4BqUdkBcOHClsGALI2q/14APWnAgY7SxXipTXCuyAmOY4hqhInUv1D26FSo4VRyhUa5ZgRMcV523E7UrrwdCia27dZQ+OxoBK7IosUTVVTp7lt7vSHVb4nM1RkcxzBqyHNfvhoPoqB9F/eEAosN4eBAP3s/VudEVZHUM0dEwHITR4UEYHQ9b2SDuJW/GV2ezr9cTKF0l02S7EvI0kUKt/EDkKLBuLcmWRC6A0tBiFJTO1TZmrOBqacNC6oYvJBoKC10xXOJ3JkVumXsUzpHp51o76wzW7EMYhRErrGVPttCPPPSWAFiabLu0pvjjJMtvDZk1i8Jjr7w5dJJLG6QJ2wimiRNOUvp8kiVayIkUVJqLhSCesE1QwjYDyDVfpwkXD1BItHYUFFo5FIpM8MKMkoyDbu3barvh6K/Z7A7CVsJakUuCBXICW+rHAIyWtP09+E1pufH1pLdolCcrYXnaWv4N3FYB/iu7bYbX2AWtwHf0C3TbLuGJXh/7AuBuBrjFcYkPuMkRtx3uDfaDpzuT2lIAHB3urmE3cvDVYl9i3jJ+1sV5AGvfeOcoBeekRoEzjXe8daIie+KB8gEeEfSfZ2C3/gW3rz2O5c9v4yXIbIMl655qb//kBw=="));

//--snip--

echo(php_sapi_name()=='cli'?"\nTHIS SCRIPT HAS BEEN MODIFIED.\n\nWARNING\nEnglish: I remind you do not edit this script to avoid errors.\nIndonesia: Saya mengingatkan Anda untuk tidak mengedit skrip ini untuk menghindari kesalahan.\n\nThis script is encripted\nDate: Tuesday,2018-11-20 16:25:03\nFrom Ip: 182.0.165.192\n\n":'<!DOCTYPE html><html><head><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.min.css" /><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script><title>This script has been modified</title></head><body><div class="container"><div class="alert alert-sm alert-danger alert-dismissible fade show" role="alert">This script has been modified<br><b>Warning</b><br>English: I remind you do not edit this script to avoid errors.<br> Indonesia: Saya mengingatkan Anda untuk tidak mengedit skrip ini untuk menghindari kesalahan.<br>This script is encripted on <b>Tuesday,2018-11-20 16:25:03</b> From Ip: <b>182.0.165.192</b><a href="javascript:void(0)" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></a></div></div><script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/js/bootstrap.min.js"></script></body></html>');

Dan jika nilai hash SHA1 script yang telah di-obfuscate tersebut benar, maka script aslinya yang akan dijalankan, yaitu bagian ini:

gzinflate(base64_decode("s7ezsS/IKODlSk3OyFdQ8kjNyclXKM8vyklRUFSyRhV2Kc3LTIQI29sBAA=="));

//--snip--

?><?php
echo "Hello world !";
echo "Hello Dunia !";
?>

Jadi, secara garis besar, berikut ini adalah langkah-langkah yang dapat digunakan untuk melakukan dekripsi/deobfuscate terhadap script yang diproteksi menggunakan phpobfuscator v02:

  • Cari key yang digunakan.
  • Ambil string yang diencode menggunakan base64 pada script, lalu dekripsi menggunakan key dari langkah pertama.
  • Ambil string ke-2 yang diencode menggunakan base64 yang merupakan hasil dari langkah sebelumnya, lalu decode menggunakan base64_decode serta dekompresi menggunakan gzinflate.

Sekian tutorial singkat kali ini, semoga bermanfaat. Terima kasih kepada Tuhan Yang Maha Esa, dan Anda yang telah membaca tutorial ini. Sampai jumpa pada tutorial lainnya.