主頁 > 後端開發 > PHP代碼審計基礎-初級篇

PHP代碼審計基礎-初級篇

2020-09-29 03:40:23 後端開發

對于php代碼審計我也是從0開始學的,對學習程序進行整理輸出沉淀如有不足歡迎提出共勉,對學習能力有較高要求,整個系列主要是在作業中快速精通php代碼審計,整個學習周期5天 ,建議花一天時間熟悉php語法,

 

我是直接phpstudy2019一鍵搭建小白首選

所謂工欲善其事必先利其器,找一款適合自己的php開發工具自行百度搭建,我用的是phpstrom .

 

初級篇主要講

1. php歷史版本漏洞,

2. 變數配置缺陷,

3. 函式缺陷,

4. 弱語言缺陷,

 

PHP配置漏洞

 

我們要熟知php各版本漏洞

Register_globals  全域變數注冊開關

在該選項為on情況下,會直接把用戶GET,POST等方式提交的引數注冊成全域變數并初始化值為引數對應的值

Php小于4.2.3默認打開 5.3廢棄 5.4移除

 

Allow_url_include  是否允許包含遠程檔案

Php 5.2 后默認設定off

 

Magic_quotes_gpc 魔術引號自動過濾

會自動在get post,cookie 變數對單引號,雙引號,反斜杠,空字符的前面加反斜杠

缺陷不會過濾$_SERVER 變數 

Php5.3后廢棄,5.4移除 小于4.2.3 默認打開

 

Magic_quotes_runtime  魔術引號自動過濾

和上面一樣 卻是對從資料庫取出的資料進行轉義  防止二次注入 同樣在5.4取消

 

 

Safe_mode  安全模式

在開啟時做命令執行操作會提示執行命令失敗,和一些敏感操作. 可以查看配置是否開啟,

 

Open_basedir  可訪問目錄

默認web目錄,查看配置是否出現全目錄可訪問情況

 

Disable_functions 禁用函式

禁用敏感函式如exec  可以通過dl()函式來繞過自定義php擴展方法實作命令執行,這個函式并不安全,

 

Display_errors  錯誤顯示

生產環境關閉錯誤回顯 display_errors=off

 

PHP漏洞函式

 變數覆寫

      extract()

該函式使用陣列鍵名作為變數名,使用陣列鍵值作為變數值,針對陣列中的每個元素,將在當前符號表中創建對應的一個變數,條件:若有EXTR_SKIP則不行,

<?php
$a = "Original";
$my_array = array("a" => "Cat", "b" => "Dog", "c" => "Horse");
extract($my_array);
echo "$a = $a; $b = $b; $c = $c";
?>
 
# 結果:$a = Cat; $b = Dog; $c = Horse

      parse_str()

決議字串并注冊成變數

$b=1;
Parse_str('b=2');
Print_r($b);
# 結果: $b=2

      import_request_variables()

將 GET/POST/Cookie 變數匯入到全域作用域中,全域變數注冊,在5.4之后被取消,只可在4-4.1.0和5-5.4.0可用,

//匯入POST提交的變數值,前綴為post_
import_request_variable("p", "post_");
//匯入GET和POST提交的變數值,前綴為gp_,GET優先于POST
import_request_variable("gp", "gp_");
//匯入Cookie和GET的變數值,Cookie變數值優先于GET
import_request_variable("cg", "cg_");

    $$變數覆寫

## 提交引數chs,則可覆寫變數"$chs"的值,$key為chs時,$$key就變成$chs

<?
$chs = '';
if($_POST && $charset != 'utf-8'){
    $chs = new Chinese('UTF-8', $charset);
    foreach($_POST as $key => $value){
        $$key = $chs->Convert($value);
    }
    unset($chs);
}

繞過過濾的空白字符

" "%00" (ASCII  0 (0x00)),空位元組符,
制表符
"\t" (ASCII  9 (0x09)),水平制表符,
空白字符:
"\n" (ASCII 10 (0x0A)),換行符,
"\v" "\x0b" (ASCII  11 (0x0B)),垂直制表符,
"\f" "%0c" 換頁符
"\r" "%0d"(ASCII  13 (0x0D)),回車符,
空格:
" " "%20" (ASCII  32 (0x20)),普通空格符,

Trim 函式過濾 \t\n\r 缺少了\f(%0c)

從而繞過%0c過濾

截斷

   

     Iconv 例外字符截斷問題

## 因iconv遇到例外字符就不轉后面的內容了,所以可以截斷,
## 這里chr(128)到chr(255)都可以截斷,
$a='1'.char(130).'2';
echo iconv("UTF-8","gbk",$a); //將字串的編碼從UTF-8轉到gbk
echo iconv('GB2312', 'UTF-8', $str); //將字串的編碼從GB2312轉到UTF-8

  eregi、ereg可用%00截斷

功能:正則匹配過濾 條件:要求php<5.3.4可以把非法的資料放在%00后面進行繞過我們可以看一個ctf題就是考察了這個知識

## http://127.0.0.1/Php_Bug/05.php?password=1e9%00*-*
#GET方式提交password,然后用ereg()正則限制了password的形式,只能是一個或者多個數字、大小寫字母,繼續strlen()限制了長度小于8并且大小必須大于9999999,繼續strpos()對password進行匹配,必須含有-,最終才輸出flag
#因為ereg函式存在NULL截斷漏洞,導致了正則過濾被繞過,所以可以使用%00截斷正則匹配,
#對于另一個難題可以使用科學計數法表示,計算器或電腦表達10的的冪是一般是e,也就是1.99714e13=19971400000000,所以構造 1e8 即 100000000 > 9999999,在加上-,于是乎構造password=1e8%00*-*,成功得到答案

<?php
if (isset ($_GET['password'])) {
    if (ereg ("^[a-zA-Z0-9]+$",$_GET['password']) === FALSE)
    {
        echo '<p>You password must be alphanumeric</p>';
    }
    else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)
    {
        if (strpos ($_GET['password'], '*-*') !== FALSE)
        {
            die('Flag: ' . $flag);
        }
        else
        {
            echo('<p>*-* have not been found</p>');
        }
    }
    else
    {
        echo '<p>Invalid password</p>';
    }
}

     move_uploaded_file 用\0截斷

5.4.x<= 5.4.39, 5.5.x<= 5.5.23, 5.6.x <= 5.6.7 原來在高版本(受影響版本中),PHP把長度比較的安全檢查邏輯給去掉了,導致了漏洞的發生

獲取檔案名不一致%00 \0  導致截斷后面的檔案名

     inclue用?截斷

<?php $name=$_GET['name']; $filename=$name.'.php'; include $filename; ?>

當輸入的檔案名包含URL時,問號截斷則會發生,并且這個利用方式不受PHP版本限制,原因是Web服務其會將問號看成一個請求引數, 測驗POC: http://127.0.0.1/test/t1.php?name=http://127.0.0.1/test/secret.txt? 則會打開secret.txt中的檔案內容,本測驗用例在PHP5.5.38版本上測驗通過,

 

     系統長度截斷

這種方式在PHP5.3以后的版本中都已經得到了修復, win260個字符,linux下4*1024=4096位元組

 

   mysql長度截斷

mysql內的默認字符長度為255,超過的就沒了, 由于mysql的sql_mode設定為default的時候,即沒有開啟STRICT_ALL_TABLES選項時,MySQL對于插入超長的值只會提示warning

     mysql中utf-8截斷

insert into dvwa.test values (14,concat("admin",0xc1,"abc"))寫入為admin  

弱型別比較

 

以下等式會成立

'' == 0 == false
 
'123' == 123
 
'abc' == 0
 
'123a' == 123
 
'0x01' == 1
 
'0e123456789' == '0e987654321'
 
[false] == [0] == [NULL] == ['']
 
NULL == false == 0
 
true == 1

    ==、>、<的弱型別比較

這里用到了PHP弱型別的一個特性,當一個整形和一個其他型別行比較的時候,會先把其他型別轉換成整型再比,

##方法1
 
##$a["a1"]="1e8%00";
 
##這里用%00繞過is_numeric,然后1e8可以比1336大,因此最后能$v1=1
 
##方法2
 
##$a["a1"]=["a"];
 
##使用陣列,可以,因為陣列恒大于數字或字串
 
##方法3
 
##$a["a1"]=1337a;
 
##1337a過is_numeric,又由>轉成1337與1336比較
 
<?php
 
is_numeric(@$a["a1"])?die("nope"):NULL;   
 
if(@$a["a1"]){
 
    var_dump($a);
 
    ($a["a1"]>1336)?$v1=1:NULL;
 
}
 
var_dump($v1);

      switch 弱型別

// 第一種:弱型別,1e==1
// $x1=1e
// 第二種:利用陣列名字bypass
// $x1=1[]
// 傳入后為string(3) "1[]",但在switch那里為1
if (isset($_GET['x1']))
{
    $x1 = $_GET['x1'];
    $x1=="1"?die("ha?"):NULL;
    switch ($x1)
    {
        case 0:
        case 1:
            $a=1;
            break;
    }
}

      md5比較(0e相等、陣列為Null)

md5('240610708') //0e462097431906509019562988736854
 
md5('QNKCDZO') //0e830400451993494058024219903391
 
0e 純數字這種格式的字串在判斷相等的時候會被認為是科學計數法的數字,先做字串到數字的轉換,
 
md5('240610708')==md5('QNKCDZO'); //True
 
md5('240610708')===md5('QNKCDZO'); //False
 
 
 
這樣的對應數值還有:
 
var_dump(md5('240610708') == md5('QNKCDZO'));
 
var_dump(md5('aabg7XSs') == md5('aabC9RqS'));
 
var_dump(sha1('aaroZmOk') == sha1('aaK1STfY'));
 
var_dump(sha1('aaO8zKZF') == sha1('aa3OFF9m'));
 
var_dump('0010e2' == '1e3');
 
var_dump('0x1234Ab' == '1193131');
 
var_dump('0xABCdef' == ' 0xABCdef');

可以用于登錄判斷

240610708

技巧:找出在某一位置開始是0e的,并包含“XXX”的字串

Md5 加密陣列都是空 可以利用繞過   

    json傳資料{“key”:0}

PHP將POST的資料全部保存為字串形式,也就沒有辦法注入數字型別的資料了而JSON則不一樣,JSON本身是一個完整的字串,經過決議之后可能有字串,數字,布爾等多種型別,

第一個application/x-www-form-urlencoded,是一般表單形式提交的content-type第二個,是包含檔案的表單,第三,四個,分別是json和xml,一般是js當中上傳的.

{“key”:”0″}

這是一個字串0,我們需要讓他為數字型別,用burp攔截,把兩個雙引號去掉,變成這樣:

{“key”:0}

 

     十六進制與十進制比較

== 兩邊的十六進制與十進制比較,是可以相等的,

 

至此已經介紹完了php常規函式缺陷,版本漏洞,語言特性導致的漏洞,需要熟記這些缺陷的利用方法,

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/136639.html

標籤:PHP

上一篇:echo、print和print_r的區別

下一篇:[視頻教程] ubuntu系統下以守護行程方式安裝使用Redis

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more