91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP中序列化和反序列化的差異

發布時間:2020-06-25 15:30:41 來源:億速云 閱讀:256 作者:Leah 欄目:編程語言

這期內容當中小編將會給大家帶來有關PHP中序列化和反序列化的差異,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

官方文檔中介紹PHP序列化和反序列化如下:            

所有php里面的值都可以使用函數serialize()來返回一個包含字節流的字符串來表示。unserialize()函數能夠重新把字符串變回php原來的值。序列化一個對象將會保存對象的所有變量,但是不會保存對象的方法,只會保存類的名字。為了能夠unserialize()一個對象,這個對象的類必須已經定義過。如果序列化類A的一個對象,將會返回一個跟類A相關,而且包含了對象所有變量值的字符串。

簡單說序列化是對象轉化字符串的過程,反序列化是字符串還原對象的過程。

環境

文章中所述內容使用環境如下:

PHP7.3.1、SDK
VSCode
C++和C

環境配置建議參考:《WINDOWS下用VSCODE調試PHP7源代碼》

在網上公開參數反序列化執行流程已經非常詳細,但是對于一些細節地方有一些不足,其中就包括序列化和反序列化之間的語法差異問題

差異問題

序列化

我們通過編譯PHP內核源碼分析,發現PHP序列化在默認情況下在對象轉換中加入:{和}用來拼接成字符串。

[var.c]
Line:882
static void php_var_serialize_intern()

Line:896
if (ce->serialize(struc, &serialized_data, &serialized_length, (zend_serialize_data *)var_hash) == SUCCESS) {
                        smart_str_appendl(buf, "C:", 2);
                        smart_str_append_unsigned(buf, ZSTR_LEN(Z_OBJCE_P(struc)->name));
                        smart_str_appendl(buf, ":\"", 2);
                        smart_str_append(buf, Z_OBJCE_P(struc)->name);
                        smart_str_appendl(buf, "\":", 2);

                        smart_str_append_unsigned(buf, serialized_length);
                        smart_str_appendl(buf, ":{", 2);
                        smart_str_appendl(buf, (char *) serialized_data, serialized_length);
                        smart_str_appendc(buf, '}');
                    }

Line:952
smart_str_appendl(buf, ":{", 2);

Line:995
smart_str_appendc(buf, '}');

咱們來看上面這段代碼,PHP會使用smart_str_appendl為序列化字符串前后拼接:{和},從var.c的第882行開始進入序列化邏輯。在第896行進行序列化字符串拼接,第952行和第995行,對于內嵌方法進行拼接。

反序列化

反序列化是將序列化的字符串,按照一定語法規則進行轉化還原。

[var_unserialize.c]
Line:655
static int php_var_unserialize_internal()

Line:674
{
    YYCTYPE yych;
    static const unsigned char yybm[] = {
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
        128, 128, 128, 128, 128, 128, 128, 128, 
        128, 128,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
          0,   0,   0,   0,   0,   0,   0,   0, 
    };
    if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
    yych = *YYCURSOR;
    switch (yych) {
    case 'C':
    case 'O':    goto yy4;
    case 'N':    goto yy5;
    case 'R':    goto yy6;
    case 'S':    goto yy7;
    case 'a':    goto yy8;
    case 'b':    goto yy9;
    case 'd':    goto yy10;
    case 'i':    goto yy11;
    case 'o':    goto yy12;
    case 'r':    goto yy13;
    case 's':    goto yy14;
    case '}':    goto yy15;
    default:    goto yy2;
    }

Line:776
yy15:
    ++YYCURSOR;
    {
    /* this is the case where we have less data than planned */
    php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data");
    return 0; /* not sure if it should be 0 or 1 here? */
}

通過內核代碼能夠看到第655行進入反序列化,反序列化是利用詞法掃描,判斷各項符號轉換對應對象。能夠看到反序列化中對于}進行了處理,處理中只是對計數器加一并沒有其他操作。

實際作用

反序列化語法的差異,對于安全防護設備判斷反序列化產生很大的影響。在Snort中,有段規則如下:

alert tcp any any -> any [80,8080,443] (uricontent:".php"; pcre:"/\{\w:.+?\}/"; sid:1; msg:php_serialize;)

在攻擊載荷中可以使用大多數字符代替{},從而導致規則失效。

總結

在紅隊攻擊中可以利用PHP序列化和反序列化語法差異,從而達到繞過防護的目的。

在藍隊防御中建議考慮定義中所述不會保存對象的方法,只會保存類的名字。,攔截保存類的名字,以及語法中相同的字符比如冒號進行防御。

上述就是小編為大家分享的PHP中序列化和反序列化的差異了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

隆德县| 遂川县| 修文县| 庆阳市| 麟游县| 凤冈县| 新绛县| 临洮县| 湘西| 博爱县| 义乌市| 东光县| 昭通市| 辰溪县| 海盐县| 什邡市| 乌鲁木齐市| 焦作市| 南郑县| 高雄县| 锡林浩特市| 益阳市| 惠东县| 桃源县| 巴塘县| 浦北县| 鹤峰县| 平昌县| 金乡县| 黄大仙区| 和政县| 阿拉尔市| 邵武市| 五常市| 嘉义县| 大悟县| 嘉兴市| 洛隆县| 南和县| 新乡县| 渝中区|