目次
0x01 ThinkPHP の機能によって引き起こされる超特権の脆弱性
0x02 モデルの誤用による超特権の脆弱性
0x03 横向挖掘 —— 权限提升漏洞(可获取管理员权限)
ホームページ バックエンド開発 PHPチュートリアル SRCMS の複数の上書き + 権限昇格管理者の脆弱性

SRCMS の複数の上書き + 権限昇格管理者の脆弱性

Jun 20, 2016 pm 12:38 PM

最新の cms フレームワーク (laraval/symfony/slim) の登場により、今日の PHP 脆弱性の発生箇所、原理、利用方法にいくつかの変化が生じています。このシリーズでそれをお伝えできれば幸いです。このような cms の脆弱性がマイニングされました。

今日の脆弱性は、Model の不当な使用によって引き起こされる、SRCMS における複数の権限侵害の脆弱性です。

まず、脆弱性の原理を簡単に説明します。

[脆弱性ソース コードをダウンロード: https://mega.nz/#!4UxCTaxJ!DpVvhBPK7YE9D_jdFQ0CjQ1ylJ4sQws-CT3LIJ5AA8Y]

今日 http://zone.wooyun .org /content/25144 SRCMS が更新されたことを確認しました。実は、少し前にこのソース コードにスターを付けましたが、まだ見ていません。このシリーズ(モダンフレームワークシリーズ)を書きたいので、今回はソースコードをダウンロードして読んでみました。

抜け穴を探す前に、優れたコード セットを提供してくれたコードの作成者に感謝の意を表したいと思います。脆弱性はすべてのプログラムに避けられないため、心理的なプレッシャーを感じる必要はありません。

SRCMS は、ThinkPHP フレームワークに基づいて開発されたオープンソースのエンタープライズ セキュリティ緊急対応センターです。私が ThinkPHP を準モダンなフレームワークとして分類しているのは、近年の開発において、いくつかのモダンな要素 (名前空間、ORM など) がますます導入されているためです。もちろん、これらの要素の導入により、以前にコードを作成したときには発生しなかったセキュリティ上の問題がいくつか発生します。

ここでの脆弱性は、SRCMS による ORM (またはフレームワークのモデル) の不当な使用が原因で、結果として権限がオーバーライドされます。

0x01 ThinkPHP の機能によって引き起こされる超特権の脆弱性

まず、この脆弱性は ThinkPHP の機能によって引き起こされます。 /Application/User/Controller/PostController.class.php:77

/***查看漏洞报告*/public function view(){    $id = session('userId');    $rid = I('get.rid',0,'intval');    $model = M("Post");   $post = $model->where('user_id='.$id)->where('id='.$rid)->find();    $tmodel= M('setting');    $title = $tmodel->where('id=1')->select();    $this->assign('title', $title);   $this->assign('model', $post);   $this->display();}
ログイン後にコピー

他人の脆弱性レポートを勝手に閲覧できる脆弱性が存在します。彼は明らかに where('user_id='.$id) をここに持っています。user_id を照会しましたか?

これには、依然として thinkphp の一般的なエラー (機能) が関係しています。多くの開発者はドキュメントを注意深く読んでいません。その理由は実際にはドキュメントに明確に記載されています。

ThinkPHP は where 関数の複数の呼び出しをサポートしていますが。ただし、条件が文字列の場合、複数回出現する場合は、最後の条件のみが取得されます。 SQL ログを確認すると、where user_id 条件がないことがわかります。

最初の不正な脆弱性が発生しました: 「脆弱性を表示」、http://localhost/srcms/user.php?m=User&c=post&a=view&rid=1

修正しましょう。where 条件を文字列型から配列型に変更する必要があると思います。この開発者がハッカーに挑戦したいのか、それとも ThinkPHP の機能を体験したいのかはわかりませんが、多くの場所では (SQL インジェクションの脆弱性はありませんが) 特に文字のスプライシングが使用されていますが、これは不適切だと思います。著者が使用している手法は依然として文字列のスプライシングであるため、この脆弱性は「新しい PHP セキュリティ脆弱性」とはみなされないと思います。フレームワーク アーキテクチャの下で生成された伝統的な脆弱性としか言えません。

0x02 モデルの誤用による超特権の脆弱性

次に、実際に新しい PHP セキュリティ脆弱性について考えてみましょう。

この問題によって引き起こされる多くの抜け穴があるので、「連絡先情報の更新」機能を使用して説明します。

/Application/User/Controller/InfoController.class.php:56

public function update(){    //默认显示添加表单    $id = session('userId');    if (!IS_POST) {        $info = M('info')->where('user_id='.$id)->select();        $this->assign('info',$info);        $this->display();    }    if (IS_POST) {        //如果用户提交数据        $model = D("info");        $model->user_id = 1;        $model->username = 1;        if (!$model->create()) {            // 如果创建失败 表示验证没有通过 输出错误提示信息            $this->error($model->getError());            exit();        } else {            if ($model->save()) {                $this->success("更新成功", U('info/index'));            } else {                $this->error("更新失败");            }        }    }}
ログイン後にコピー

ここでは、作成者は ORM に似たデータベース更新メソッドを使用して、フォームのデータを自動的に取得しますcreate() 内の内容はデータベース save() に更新されます。 create 関数を見てみましょう:

public function create($data='',$type='') {   // 如果没有传值默认取POST数据   if(empty($data)) {       $data   =   I('post.');   }elseif(is_object($data)){       $data   =   get_object_vars($data);   }   // 验证数据   if(empty($data) || !is_array($data)) {       $this->error = L('_DATA_TYPE_INVALID_');       return false;   }      // 状态   $type = $type?:(!empty($data[$this->getPk()])?self::MODEL_UPDATE:self::MODEL_INSERT);   ...   // 创建完成对数据进行自动处理   $this->autoOperation($data,$type);   // 赋值当前数据对象   $this->data =   $data;   // 返回创建的数据以供其他调用   return $data;}
ログイン後にコピー

最初のパラメーター $data が空の場合、実際には POST データから読み取る I('post.') から取得されます。 。

その後、多くの処理の後、autoOperation メソッドが渡されます。 autoOperation メソッドについて詳しく説明します。

private function autoOperation(&$data,$type) {    if(!empty($this->options['auto'])) {        $_auto   =   $this->options['auto'];        unset($this->options['auto']);    }elseif(!empty($this->_auto)){        $_auto   =   $this->_auto;    }    // 自动填充    if(isset($_auto)) {        foreach ($_auto as $auto){            // 填充因子定义格式            // array('field','填充内容','填充条件','附加规则',[额外参数])            if(empty($auto[2])) $auto[2] =  self::MODEL_INSERT; // 默认为新增的时候自动填充            if( $type == $auto[2] || $auto[2] == self::MODEL_BOTH) {                if(empty($auto[3])) $auto[3] =  'string';                switch(trim($auto[3])) {                    case 'function':    //  使用函数进行填充 字段的值作为参数                    case 'callback': // 使用回调方法                        $args = isset($auto[4])?(array)$auto[4]:array();                        if(isset($data[$auto[0]])) {                            array_unshift($args,$data[$auto[0]]);                        }                        if('function'==$auto[3]) {                            $data[$auto[0]]  = call_user_func_array($auto[1], $args);                        }else{                            $data[$auto[0]]  =  call_user_func_array(array(&$this,$auto[1]), $args);                        }                        break;                    case 'field':    // 用其它字段的值进行填充                        $data[$auto[0]] = $data[$auto[1]];                        break;                    case 'ignore': // 为空忽略                        if($auto[1]===$data[$auto[0]])                            unset($data[$auto[0]]);                        break;                    case 'string':                    default: // 默认作为字符串填充                        $data[$auto[0]] = $auto[1];                }                if(isset($data[$auto[0]]) && false === $data[$auto[0]] )   unset($data[$auto[0]]);            }        }    }    return $data;}
ログイン後にコピー

これは、条件を自動的に入力するメソッドです。特定のモデルの _auto 配列の値を決定します。 InfoModel.class.php でどのように定義されているかを見てみましょう。

<?phpnamespace User\Model;use Think\Model;class InfoModel extends Model{        protected $_validate = array(        array('realname','require','请填写真实姓名'), //默认情况下用正则进行验证        array('zipcode','require','请填写邮编'), //默认情况下用正则进行验证        array('location','require','请填写地址'), //默认情况下用正则进行验证        array('tel','require','请填写联系电话'), //默认情况下用正则进行验证        array('alipay','require','请填写支付宝账号,方便发放现金奖励'), //默认情况下用正则进行验证    );        protected $_auto = array (         array('user_id','getUid',1,'callback'), // 对update_time字段在更新的时候写入当前用户ID        array('username','getUsername',1,'callback'), // 对update_time字段在更新的时候写入当前用户名    );        protected function getUid(){        return session('userId');    }        protected function getUsername(){        return session('username');    }}
ログイン後にコピー

ここで user_id が示されていることがわかります。 getUid はコールバック関数 getUid にバインドされており、現在のユーザーの user_id を正確に返します。

すべてが正しいと思いますか? _auto の 3 番目のパラメーターを注意深く観察します: 1

3 番目のパラメーターの定義を確認します:

1 は挿入を表し、挿入時にのみ処理されます。 。渡した POST に user_id (getPk) があると仮定すると、ThinkPHP は現在のタイプが update (2:

// 状态$type = $type?:(!empty($data[$this->getPk()])?self::MODEL_UPDATE:self::MODEL_INSERT);
ログイン後にコピー

) であると自動的に判断します。そのため、autoOperation メソッドでスタックします。この if ステートメント、マスター、入力できません:

//type是update(2),但$auto[2]却是 1, $type==$auto[2]不成立if( $type == $auto[2] || $auto[2] == self::MODEL_BOTH) {
ログイン後にコピー

この if ステートメントは入力できないため、実際には user_id はプログラムによって上書きされず、POST で渡した user_id は次のようになります。保持されます。したがって、私は権限を超えてあらゆるユーザーの連絡先情報を変更できます。訴状の分析はすべて YY の私が行っています。今から検証させてください。まずテスト ユーザーを登録し (user_id は 4)、次のように連絡先情報を追加します。

他のユーザーは、ログイン後、次のデータ パケットを送信して user_id= の連絡先情報を変更します。 4、携帯電話番号、Alipayなどを含む:

返回test用户的页面,发现已经被改:

这就是一个典型的新型框架的越权漏洞,因为不熟悉框架,在使用框架提供的『新式方法』时,造成了错误。

0x03 横向挖掘 —— 权限提升漏洞(可获取管理员权限)

既然我们这个漏洞是开发者对框架不熟悉造成的,属于是『架构漏洞』,那么srcms里可能并非一处地方存在此漏洞。

存在此类漏洞需要有这个条件:Model中设置的类型与实际执行的SQL类型不同。比如这个漏洞是设置的insert,实际执行的是update。

但我看了下前台,前台大部分地方都是调用的add()进行insert,都能够对上。暂时没发现其他地方存在这个问题,后台我就不看了。

等下,insert?看到这个的时候,我就想到下一步利用方法了。我们看到注册时候的代码:

public function add(){    //默认显示添加表单    if (!IS_POST) {        $this->display();    }    if (IS_POST) {        //如果用户提交数据        $model = D("Member");        if (!$model->create()) {            // 如果创建失败 表示验证没有通过 输出错误提示信息            $this->error($model->getError());            exit();        } else {            if ($model->add()) {                $this->success("用户添加成功", U('index/index'));            } else {                $this->error("用户添加失败");            }        }    }}
ログイン後にコピー

过程也是create()以后add(),再看到member.class.php

<?phpnamespace User\Model;use Think\Model;class MemberModel extends Model{    protected $_validate = array(        array('username','require','请填写用户名!'), //默认情况下用正则进行验证        array('email','require','请填写邮箱!'), //默认情况下用正则进行验证        array('email','email','邮箱格式错误!'), //默认情况下用正则进行验证        array('password','require','请填写密码!','','',self::MODEL_INSERT), //默认情况下用正则进行验证        array('repassword','password','确认密码不正确',0,'confirm'), // 验证确认密码是否和密码一致        array('username','','用户名已存在!',0,'unique',self::MODEL_BOTH), // 在新增的时候验证name字段是否唯一        array('email','','邮箱已存在!',0,'unique',self::MODEL_BOTH), // 在新增的时候验证name字段是否唯一    );    protected $_auto = array(        array('password','md5',1,'function') , //添加时用md5函数处理         array('update_at','time',2,'function'), //更新时        array('create_at','time',1,'function'), //新增时        array('login_ip','get_client_ip',3,'function'), //新增时    );}
ログイン後にコピー

可见,并没有对type进行设置,也就是说,我只要传入的POST数据里设置一下我自己的type=2,即可注册一个管理员。测试一下:

成功用hacker登陆后台:

前台也可以看到其积分是99999:

后台漏洞,我就不挖了,涉及不到新型CMS的漏洞挖掘了。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Laravelでフラッシュセッションデータを使用します Laravelでフラッシュセッションデータを使用します Mar 12, 2025 pm 05:08 PM

Laravelは、直感的なフラッシュメソッドを使用して、一時的なセッションデータの処理を簡素化します。これは、アプリケーション内に簡単なメッセージ、アラート、または通知を表示するのに最適です。 データは、デフォルトで次の要求のためにのみ持続します。 $リクエスト -

PHPのカール:REST APIでPHPカール拡張機能を使用する方法 PHPのカール:REST APIでPHPカール拡張機能を使用する方法 Mar 14, 2025 am 11:42 AM

PHPクライアントURL(CURL)拡張機能は、開発者にとって強力なツールであり、リモートサーバーやREST APIとのシームレスな対話を可能にします。尊敬されるマルチプロトコルファイル転送ライブラリであるLibcurlを活用することにより、PHP Curlは効率的なexecuを促進します

Laravelテストでの簡略化されたHTTP応答のモッキング Laravelテストでの簡略化されたHTTP応答のモッキング Mar 12, 2025 pm 05:09 PM

Laravelは簡潔なHTTP応答シミュレーション構文を提供し、HTTP相互作用テストを簡素化します。このアプローチは、テストシミュレーションをより直感的にしながら、コード冗長性を大幅に削減します。 基本的な実装は、さまざまな応答タイプのショートカットを提供します。 Illuminate \ support \ facades \ httpを使用します。 http :: fake([[ 'google.com' => 'hello world'、 'github.com' => ['foo' => 'bar']、 'forge.laravel.com' =>

Codecanyonで12の最高のPHPチャットスクリプト Codecanyonで12の最高のPHPチャットスクリプト Mar 13, 2025 pm 12:08 PM

顧客の最も差し迫った問題にリアルタイムでインスタントソリューションを提供したいですか? ライブチャットを使用すると、顧客とのリアルタイムな会話を行い、すぐに問題を解決できます。それはあなたがあなたのカスタムにより速いサービスを提供することを可能にします

PHPにおける後期静的結合の概念を説明します。 PHPにおける後期静的結合の概念を説明します。 Mar 21, 2025 pm 01:33 PM

記事では、PHP 5.3で導入されたPHPの後期静的結合(LSB)について説明し、より柔軟な継承を求める静的メソッドコールのランタイム解像度を可能にします。 LSBの実用的なアプリケーションと潜在的なパフォーマ

フレームワークセキュリティ機能:脆弱性から保護します。 フレームワークセキュリティ機能:脆弱性から保護します。 Mar 28, 2025 pm 05:11 PM

記事では、入力検証、認証、定期的な更新など、脆弱性から保護するためのフレームワークの重要なセキュリティ機能について説明します。

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

See all articles