Rumah pembangunan bahagian belakang tutorial php php反序列unserialize的一个小特点

php反序列unserialize的一个小特点

Jun 13, 2016 pm 12:30 PM
case data false goto return

php反序列unserialize的一个小特性

这几天wordpress的那个反序列漏洞比较火,具体漏洞我就不做分析了,看这篇:http://drops.wooyun.org/papers/596,?
你也可以去看英文的原文:http://vagosec.org/2013/09/wordpress-php-object-injection/。?

wp官网打了补丁,我试图去bypass补丁,但让我自以为成功的时候,发现我天真了,并没有成功绕过wp的补丁,但却发现了unserialize的一个小特性,在此和大家分享一下。?

1.unserialize()函数相关源码:?

if ((YYLIMIT - YYCURSOR) ????????yych = *YYCURSOR;?<br style="margin: 0px; padding: 0px;">????????switch (yych) {?<br style="margin: 0px; padding: 0px;">????????case 'C':?<br style="margin: 0px; padding: 0px;">????????case 'O':????????goto yy13;?<br style="margin: 0px; padding: 0px;">????????case 'N':????????goto yy5;?<br style="margin: 0px; padding: 0px;">????????case 'R':????????goto yy2;?<br style="margin: 0px; padding: 0px;">????????case 'S':????????goto yy10;?<br style="margin: 0px; padding: 0px;">????????case 'a':????????goto yy11;?<br style="margin: 0px; padding: 0px;">????????case 'b':????????goto yy6;?<br style="margin: 0px; padding: 0px;">????????case 'd':????????goto yy8;?<br style="margin: 0px; padding: 0px;">????????case 'i':????????goto yy7;?<br style="margin: 0px; padding: 0px;">????????case 'o':????????goto yy12;?<br style="margin: 0px; padding: 0px;">????????case 'r':????????goto yy4;?<br style="margin: 0px; padding: 0px;">????????case 's':????????goto yy9;?<br style="margin: 0px; padding: 0px;">????????case '}':????????goto yy14;?<br style="margin: 0px; padding: 0px;">????????default:????????goto yy16;?<br style="margin: 0px; padding: 0px;">????????}

上边这段代码是判断序列串的处理方式,如序列串O:4:"test":1:{s:1:"a";s:3:"aaa";},处理这个序列串,先获取字符串第一个字符为O,然后case 'O':??goto yy13?

yy13:?<br style="margin: 0px; padding: 0px;">????????yych = *(YYMARKER = ++YYCURSOR);?<br style="margin: 0px; padding: 0px;">????????if (yych == ':') goto yy17;?<br style="margin: 0px; padding: 0px;">????????goto yy3;

从上边代码看出,指针移动一位指向第二个字符,判断字符是否为:,然后 goto yy17?

yy17:?<br style="margin: 0px; padding: 0px;">????????yych = *++YYCURSOR;?<br style="margin: 0px; padding: 0px;">????????if (yybm[0+yych] & 128) {?<br style="margin: 0px; padding: 0px;">????????????????goto yy20;?<br style="margin: 0px; padding: 0px;">????????}?<br style="margin: 0px; padding: 0px;">????????if (yych == '+') goto yy19;?<br style="margin: 0px; padding: 0px;"><br style="margin: 0px; padding: 0px;">.......?<br style="margin: 0px; padding: 0px;"><br style="margin: 0px; padding: 0px;">yy19:?<br style="margin: 0px; padding: 0px;">????????yych = *++YYCURSOR;?<br style="margin: 0px; padding: 0px;">????????if (yybm[0+yych] & 128) {?<br style="margin: 0px; padding: 0px;">????????????????goto yy20;?<br style="margin: 0px; padding: 0px;">????????}?<br style="margin: 0px; padding: 0px;">????????goto yy18;

从上边代码看出,指针移动,判断下一位字符,如果字符是数字直接goto yy20,如果是'+'就goto yy19,而yy19中是对下一位字符判断,如果下一位字符是数字goto yy20,不是就goto yy18,yy18是直接退出序列处理,yy20是对object性的序列的处理,所以从上边可以看出:?

O:+4:"test":1:{s:1:"a";s:3:"aaa";}?<br style="margin: 0px; padding: 0px;">O:4:"test":1:{s:1:"a";s:3:"aaa";}

都能够被unserialize反序列化,且结果相同。?

2.实际测试:?

<?php ?<br style="margin: 0px; padding: 0px;">var_dump(unserialize('O:+4:"test":1:{s:1:"a";s:3:"aaa";}'));?<br style="margin: 0px; padding: 0px;">var_dump(unserialize('O:4:"test":1:{s:1:"a";s:3:"aaa";}'));?<br style="margin: 0px; padding: 0px;">?>

输出:?

object(__PHP_Incomplete_Class)#1 (2) { ["__PHP_Incomplete_Class_Name"]=> string(4) "test" ["a"]=> string(3) "aaa" }?<br style="margin: 0px; padding: 0px;">object(__PHP_Incomplete_Class)#1 (2) { ["__PHP_Incomplete_Class_Name"]=> string(4) "test" ["a"]=> string(3) "aaa" }

其实,不光object类型处理可以多一个'+',其他类型也可以,具体测试不做过多描述。?

3.我们看下wp的补丁:?

function is_serialized( $data, $strict = true ) {?<br style="margin: 0px; padding: 0px;">????????// if it isn't a string, it isn't serialized?<br style="margin: 0px; padding: 0px;">????????if ( ! is_string( $data ) )?<br style="margin: 0px; padding: 0px;">????????????????return false;?<br style="margin: 0px; padding: 0px;">????????$data = trim( $data );?<br style="margin: 0px; padding: 0px;">???????? if ( 'N;' == $data )?<br style="margin: 0px; padding: 0px;">????????????????return true;?<br style="margin: 0px; padding: 0px;">????????$length = strlen( $data );?<br style="margin: 0px; padding: 0px;">????????if ( $length ????????????????return false;?<br style="margin: 0px; padding: 0px;">????????if ( ':' !== $data[1] )?<br style="margin: 0px; padding: 0px;">????????????????return false;?<br style="margin: 0px; padding: 0px;">????????if ( $strict ) {//output?<br style="margin: 0px; padding: 0px;">????????????????$lastc = $data[ $length - 1 ];?<br style="margin: 0px; padding: 0px;">????????????????if ( ';' !== $lastc && '}' !== $lastc )?<br style="margin: 0px; padding: 0px;">????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????} else {//input?<br style="margin: 0px; padding: 0px;">????????????????$semicolon = strpos( $data, ';' );?<br style="margin: 0px; padding: 0px;">????????????????$brace???? = strpos( $data, '}' );?<br style="margin: 0px; padding: 0px;">????????????????// Either ; or } must exist.?<br style="margin: 0px; padding: 0px;">????????????????if ( false === $semicolon && false === $brace )?<br style="margin: 0px; padding: 0px;">????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????????????// But neither must be in the first X characters.?<br style="margin: 0px; padding: 0px;">????????????????if ( false !== $semicolon && $semicolon ????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????????????if ( false !== $brace && $brace ????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????}?<br style="margin: 0px; padding: 0px;">????????$token = $data[0];?<br style="margin: 0px; padding: 0px;">????????switch ( $token ) {?<br style="margin: 0px; padding: 0px;">????????????????case 's' :?<br style="margin: 0px; padding: 0px;">????????????????????????if ( $strict ) {?<br style="margin: 0px; padding: 0px;">????????????????????????????????if ( '"' !== $data[ $length - 2 ] )?<br style="margin: 0px; padding: 0px;">????????????????????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????????????????????} elseif ( false === strpos( $data, '"' ) ) {?<br style="margin: 0px; padding: 0px;">????????????????????????????????return false;?<br style="margin: 0px; padding: 0px;">????????????????????????}?<br style="margin: 0px; padding: 0px;">????????????????case 'a' :?<br style="margin: 0px; padding: 0px;">????????????????case 'O' :?<br style="margin: 0px; padding: 0px;">????????????????????????echo "a";?<br style="margin: 0px; padding: 0px;">????????????????????????return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );?<br style="margin: 0px; padding: 0px;">????????????????case 'b' :?<br style="margin: 0px; padding: 0px;">????????????????case 'i' :?<br style="margin: 0px; padding: 0px;">????????????????case 'd' :?<br style="margin: 0px; padding: 0px;">????????????????????????$end = $strict ? '$' : '';?<br style="margin: 0px; padding: 0px;">????????????????????????return (bool) preg_match( "/^{$token}:[0-9.E-]+;$end/", $data );?<br style="margin: 0px; padding: 0px;">????????}?<br style="margin: 0px; padding: 0px;">????????return false;?<br style="margin: 0px; padding: 0px;">}
补丁中的?

return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );

可以多一个'+'来绕过,虽然我们通过这个方法把序列值写入了数据库,但从数据库中提取数据,再次验证的时候却没法绕过了,我这个加号没能使数据进出数据库发生任何变化,我个人认为这个补丁绕过重点在于数据进出数据的前后变化。?

4.总结?
虽然没有绕过wp补丁,但这个unserialize()的小特性可能会被很多开发人员忽略,导致程序出现安全缺陷。?
以上的分析有什么错误请留言指出。?

5.参考?
《WordPress
http://vagosec.org/2013/09/wordpress-php-object-injection/?
《var_unserializer.c源码》?
https://github.com/php/php-src/blob/73cd2e0ab14d804c6bf0b689490bdd4fd6e969b1/ext/standard/var_unserializer.c?
《PHP string序列化与反序列化语法解析不一致带来的安全隐患》?
http://zone.wooyun.org/content/1664

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Penjelasan terperinci tentang penggunaan pulangan dalam bahasa C Penjelasan terperinci tentang penggunaan pulangan dalam bahasa C Oct 07, 2023 am 10:58 AM

Penggunaan pulangan dalam bahasa C ialah: 1. Untuk fungsi yang jenis nilai pulangannya adalah batal, anda boleh menggunakan pernyataan pulangan untuk menamatkan pelaksanaan fungsi lebih awal 2. Untuk fungsi yang jenis nilai pulangannya tidak batal, fungsi bagi penyataan pulangan adalah untuk menamatkan pelaksanaan fungsi Hasilnya dikembalikan kepada pemanggil 3. Menamatkan pelaksanaan fungsi lebih awal, kita boleh menggunakan penyataan pulangan untuk menamatkan pelaksanaan fungsi lebih awal jika fungsi tidak mengembalikan nilai.

Apakah perintah pelaksanaan pemulangan dan akhirnya pernyataan di Jawa? Apakah perintah pelaksanaan pemulangan dan akhirnya pernyataan di Jawa? Apr 25, 2023 pm 07:55 PM

Kod sumber: publicclassReturnFinallyDemo{publicstaticvoidmain(String[]args){System.out.println(case1());}publicstaticintcase1(){intx;try{x=1;returnx;}akhirnya{x=3;}}}# Output Output kod di atas hanya boleh membuat kesimpulan: return dilaksanakan sebelum akhirnya. Mari kita lihat apa yang berlaku pada tahap bytecode. Yang berikut memintas sebahagian kod bait kaedah case1 dan membandingkan kod sumber untuk menganotasi maksud setiap arahan dalam

Apakah maksud pernyataan goto dalam bahasa c Apakah maksud pernyataan goto dalam bahasa c Dec 22, 2022 pm 06:00 PM

Dalam bahasa C, pernyataan goto dipanggil pernyataan pemindahan tanpa syarat, yang membenarkan pemindahan kawalan tanpa syarat kepada pernyataan berlabel dalam fungsi yang sama ialah "label goto;...label: pernyataan;", di mana label boleh; apa-apa kecuali C Teks biasa selain kata kunci, yang boleh ditetapkan sebelum atau selepas pernyataan goto dalam program C.

HMD Skyline mendapat pilihan warna baharu dan sarung magnet rasmi HMD Skyline mendapat pilihan warna baharu dan sarung magnet rasmi Aug 23, 2024 am 07:04 AM

Apabila HMD Skyline(tersedia di Amazon pada harga $499) dilancarkan bulan lepas, ia dikeluarkan dalam dua warna - Neon Pink dan Twisted Black. Mereka kini disertai oleh warna ketiga yang digelar Blue Topaz. HMD Global juga telah mengumumkan kes rasmi untuk ph

Cara menggunakan goto dalam bahasa go Cara menggunakan goto dalam bahasa go Nov 23, 2022 pm 06:40 PM

Dalam bahasa Go, pernyataan goto digunakan untuk melompat tanpa syarat ke baris tertentu dalam program; ia menggunakan label untuk membuat lompatan tanpa syarat antara kod. goto diikuti dengan label Maksud label ini adalah untuk memberitahu program Go yang baris kod untuk dilaksanakan seterusnya. goto memecahkan perintah pelaksanaan kod asal dan melompat terus ke baris yang ditentukan untuk melaksanakan kod penyataan goto biasanya digunakan bersama dengan pernyataan bersyarat dan boleh digunakan untuk melaksanakan pemindahan bersyarat, membentuk gelung dan melompat keluar dari badan gelung.

Bagaimanakah Vue3 menggunakan gula sintaksis persediaan untuk menolak menulis pulangan Bagaimanakah Vue3 menggunakan gula sintaksis persediaan untuk menolak menulis pulangan May 12, 2023 pm 06:34 PM

Gula sintaks persediaan Vue3.2 ialah gula sintaks masa kompilasi yang menggunakan gabungan API dalam satu komponen fail (SFC) untuk menyelesaikan persediaan yang rumit dalam Vue3.0 Pembolehubah, fungsi dan kandungan yang diisytiharkan yang diperkenalkan oleh import didedahkan melalui pulangan, supaya ia boleh digunakan dalam Vue3.0 Masalah dalam penggunaan 1. Tidak perlu mengembalikan pembolehubah yang diisytiharkan, fungsi dan kandungan yang diperkenalkan semasa penggunaan Anda boleh menggunakan gula sintaksis //import kandungan yang diperkenalkan import{getToday }from'./utils'//variable constmsg='Hello !'//function function

pembolehubah penghakiman kes suis pembolehubah penghakiman kes suis Feb 19, 2024 am 08:04 AM

Suis memerlukan contoh kod khusus untuk menentukan pembolehubah Dalam pengaturcaraan, kita selalunya perlu melakukan operasi yang berbeza berdasarkan nilai pembolehubah yang berbeza. Pernyataan suis ialah struktur mudah yang membolehkan anda memilih blok kod yang berbeza untuk pelaksanaan berdasarkan nilai pembolehubah. Berikut ialah contoh kod khusus yang menunjukkan cara menggunakan pernyataan kotak suis untuk menentukan nilai pembolehubah yang berbeza: #includeintmain(){

Penjelasan terperinci tentang nilai pulangan fungsi JavaScript dan penyata pulangan Penjelasan terperinci tentang nilai pulangan fungsi JavaScript dan penyata pulangan Aug 04, 2022 am 09:46 AM

Fungsi JavaScript menyediakan dua antara muka untuk berinteraksi dengan dunia luar Parameter berfungsi sebagai pintu masuk untuk menerima maklumat luaran berfungsi sebagai saluran keluar untuk menyalurkan kembali hasil operasi kepada dunia luar. Artikel berikut akan membawa anda memahami nilai pulangan fungsi JavaScript dan menganalisis secara ringkas penggunaan penyata pulangan saya harap ia akan membantu anda!

See all articles