一、破解工具之php-screw-brute
1、項目地址
https://github.com/securifybv/php-screw-brute
2、項目介紹
此腳本可以恢復/爆破php screw使用的密鑰。PHP Screw使用壓縮文件的長度來確定(硬編碼)密鑰的起始索引。PHP Screw的工作原理是首先使用ZLIB(級別1)壓縮PHP文件,然后按位取反,再與密鑰進行異或。 因為ZLIB具有固定的頭部並且不同文件的起始索引不同,所以可以恢復密鑰的一部分, 其余字節可以爆破。 通常,你擁有的文件越多,恢復密鑰的速度就越快。 當然,所有文件都必須使用相同的PHP Screw密鑰進行加密。 如果你擁有的文件足夠多,則可直接恢復密鑰而不需要爆破。
下圖1是php文件經過php screw加密后的一個樣子,通過開頭的“PM9SCREW”字符串得知使用了php screw進行加密。
圖1
3、使用
下圖2是使用方法,解密成功后,會在相同目錄下生成以“.plain”為后綴的同名文件。比如待解密的文件是“index.php”,則解密成功后生成“index.php.plain”文件。
圖2
寫了一個python腳本,用於篩選解密成功的php文件。
#!/usr/bin/python # -*- coding: UTF-8 -*- import os import shutil def main(): src = '/root/Download/demo' dst = src + '_backup' shutil.copytree(src,dst) #備份 for root,dirs,files in os.walk(src): for name in files: basename, ext = os.path.splitext(name) oldname = os.path.join(root,name) newname = os.path.join(root,basename) if ext == '.php': os.remove(oldname) #刪除原來的加密的PHP文件 if ext == '.plain': os.rename(oldname,newname) #重命名解密成功的文件 filename.php.plain => filename.php print('Good job') if __name__ == '__main__': main()
二、破解工具之screw_decode
1、項目地址
https://github.com/firebroo/screw_decode
2、項目介紹
前提需要有加密之后的文件,和加密的擴展庫php_screw.so 打開screwdecode.c找到PM9SCREW,PM9SCREW_LEN和pm9screw_mycryptkey,3個可能被使用者修改,需要用IDA去查找然后替換掉。 pm9screw_mycryptkey是至關重要的,拿不到就解密不了。別的兩個可以暴力嘗試解決,其實就是讀取掉頭部n個字節嘗試解密。
3、安裝和使用
安裝:
git clone https://github.com/firebroo/screw_decode.git
make
如果以上出錯,就看報錯然后google,一個是依賴php-devel,一個是依賴zlibc-devel
使用:
sudo ./decode path
說明: 結果保存在同目錄,文件名字為原文件名字后面追加.decode, sudo 權限保證可以有chdir和創建文件權限。
三、IDA獲取加密的key
1、通過導圖查找
首先找到php_screw.so文件,然后通過IDA分析(幸好之前跟基友要了份IDA)。加密過程是在pm9screw_ext_fopen函數中實現的,所以只需要到這個函數中去找加密部分即可。
圖3
找到pm9screw_ext_fopen函數,雙擊,如圖4所示:
圖4
然后右邊的窗口就會如圖5所示:
圖5
很明顯,我標黃的就是加密密鑰了,雙擊跳轉至其指針保存處:
圖6
再次雙擊,跟蹤變量,見下圖7,打碼處就是密鑰了。
圖7
如下圖8,右鍵,將十六進制的密鑰轉成十進制的,然后打開screwdecode.c,見下圖9,將密鑰替換掉,即可使用screw_decode解密。
圖8
圖9
2、通過偽代碼查找
再找到目標函數之后,使用F5,查看偽代碼,雙擊黃標也可以跳轉到之前找到的位置。
圖10
四、php-screw加密文件
1、項目地址
https://sourceforge.net/projects/php-screw/ 或者
https://github.com/Luavis/php-screw
2、使用
(1)我是在kali-rolling上測試的,提示沒有phpize這個命令。
apt-get install php-dev
(2)然后解壓
tar –zxvf php_screw-1.5.tar.gz
圖9
(3) 編譯PHP擴展的工具,主要是根據系統信息生成對應的configure文件
Phpize
./configure
圖10
圖11
(4)編輯my_screw.h修改pm9screw_mycryptkey密鑰的值
如圖12是默認值。
圖12
(5)此外我們可以編輯php_screw.h修改PM9SCREW 和 PM9SCREW_LEN的值,注意PM9SCREW_LEN的值要小於等於PM9SCREW的長度。如圖13是其默認值。
圖13
(5)進行編譯
如圖14編譯時出錯了,在php_screw的目錄下以下命令執行即可解決,最后編譯成功。
sed -i "s/CG(extended_info) = 1;/CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;/g" php_screw.c
圖14
(6)將編譯好的php_screw.so拷貝到php擴展庫目錄。
通過phpinfo()頁面查找extension-dir關鍵字
圖16
將編譯好的php_screw.so拷貝到php擴展目錄。
cp modules/php_screw.so /usr/lib/php/20151012/php_screw.so
(7)編輯php.ini添加以下一行代碼
extension=php_screw.so
(8)重啟http服務器
Service apache2 restart
(9)編譯加密工具
cd tools
make
編譯完成后生成screw可執行文件。
圖17
(10)嘗試加密一個php文件
我們寫一個phpinfo.php文件內容是<?php phpinfo();?>
然后執行./screw phpinfo.php加密文件,見下圖18。
圖18
(11)將加密好的文件拷貝到web目錄
cp phpinfo.php /var/www/html/phpinfo.php
圖19
(12)批量加密php文件
find /data/php/source -name “*.php” -print|xargs -n1 screw //加密所有的.php文件
五、參考:
php_screw的加密和解密探究(二)解密算法與Python實現:
php_screw的加密和解密探究(一)編譯Screw擴展並測試:
用 phpize 編譯共享 PECL 擴展庫:
https://www.php.net/manual/zh/install.pecl.phpize.php
轉載請注明出處。