小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

PHP代碼審計基礎(chǔ)-高級篇

 丹楓無跡 2021-12-02

高級篇主要講

1. 熟知各個開源框架歷史版本漏洞。

2. 業(yè)務(wù)邏輯漏洞

3. 多線程引發(fā)的漏洞

4. 事務(wù)鎖引發(fā)的漏洞

 

在高級篇審計中有很多漏洞正常情況下是不存在的只有在特殊情況下才有

 

PHP常用框架

Zendframwork,Yii,Laravel ,、ThinkPHP

這里舉例因為thinkphp由國內(nèi)人開發(fā)用戶量較多而且歷史漏洞也多

 

Thinkphp歷史漏洞很多,對于漏洞形成原因可以自己復(fù)現(xiàn)。

篇幅有限只介紹披露漏洞

Query方法 低于3.1.3 有sql注入問題

Order方法 低于 5.x 有sql注入問題

Update方法 低于3.2.3 有sql注入問題

/**
     * 更新記錄
     * @access public
     * @param mixed $data 數(shù)據(jù)
     * @param array $options 表達(dá)式
     * @return false | integer
     */
    public function update($data,$options) {
        $this->model  =   $options['model'];
        $this->parseBind(!empty($options['bind'])?$options['bind']:array());
        $table  =   $this->parseTable($options['table']);
        $sql   = 'UPDATE ' . $table . $this->parseSet($data);
        if(strpos($table,',')){// 多表更新支持JOIN操作
            $sql .= $this->parseJoin(!empty($options['join'])?$options['join']:'');
        }
        $sql .= $this->parseWhere(!empty($options['where'])?$options['where']:'');
        if(!strpos($table,',')){
            //  單表更新支持order和lmit
            $sql   .=  $this->parseOrder(!empty($options['order'])?$options['order']:'')
                .$this->parseLimit(!empty($options['limit'])?$options['limit']:'');
        }
        $sql .=   $this->parseComment(!empty($options['comment'])?$options['comment']:'');
        return $this->execute($sql,!empty($options['fetch_sql']) ? true : false);
    }

5. x 版本有命令執(zhí)行漏洞

在github上也有歷史分支可以查看修復(fù)代碼

 

業(yè)務(wù)邏輯

想要對整體的邏輯進行審計

  1. 熟悉業(yè)務(wù)場景
  2. 熟悉業(yè)務(wù)流程
  3. 通讀代碼

多線程引發(fā)的漏洞

這里我寫了個例子

<?php
 
$money=100;//數(shù)據(jù)庫查詢的用戶余額
 
$buy=intval($_GET['buy']);
 
 
 
if ($money>0&& $money-$buy>0)
 
{
 
    sleep(10);
 
    $moeny-=$buy;
 
    //寫入數(shù)據(jù)庫
 
}
 
 
return $money

正常情況下用戶余額一定不為負(fù)數(shù) 如果在并發(fā)情況下呢?

用戶發(fā)送惡意并發(fā)請求時就有可能出現(xiàn)這種情況。這么防御呢

這里需要知道事務(wù)和鎖的概念可以自行百度理解我這里簡單概述一下

事務(wù):類似一個執(zhí)行任務(wù) 成功就任務(wù)完成 ,失敗任務(wù)自動回滾到未接任務(wù)前

鎖:悲觀鎖,樂觀鎖。

我們可以把多線程請求變成單線程處理,這里也可以用隊列壓入壓出。

<?php
 
 
 
$money = 100;//數(shù)據(jù)庫查詢的用戶余額
 
$buy = intval($_GET['buy']);
 
try {
 
    if (flock($money, LOCK_EX)) {
 
        if ($money > 0 && $money - $buy > 0) {
 
            sleep(10);
 
            $moeny -= $buy;
 
            //寫入數(shù)據(jù)庫A
 
            throw new ExceptionNew("xp");
 
            //寫入數(shù)據(jù)庫B
 
        }
 
        flock($money, LOCK_UN);
 
    }
 
 
} catch (Exception $exceptione) {
 
    throw new ExceptionNew("xp");
 
}
 
 
 
return $money

這樣確實解決了這個并發(fā)問題,但又有另外一個問題,如果有多個數(shù)據(jù)庫操作中間一段中斷是無法對數(shù)據(jù)還原的,這里我們需要把事務(wù)也加上同時默認(rèn)加鎖。

我們修改一下代碼看一下

<?php
 
$money=100;//數(shù)據(jù)庫查詢的用戶余額
 
$buy=intval($_GET['buy']);
 
try
 
{
 
    $this->startTrans();//開啟事務(wù)
 
    if ($money>0&& $money-$buy>0)
 
    {
 
        sleep(10);
 
        $moeny-=$buy;
 
        $this->commit(); //提交事務(wù)
 
        //寫入數(shù)據(jù)庫
 
    }
 
}
 
catch (Exception $exceptione)
 
{
 
    $this->rollback();//回滾
 
}
 
 
 
return $money
<?php
 
 
 
$buy=intval($_GET['buy']);
 
try
 
{
 
    $this->startTrans();//開啟事務(wù)
 
    $money=100;//數(shù)據(jù)庫查詢的用戶余額
 
    if ($money>0&& $money-$buy>0)
 
    {
 
        sleep(10);
 
        $moeny-=$buy;
 
        $this->commit(); //提交事務(wù)
 
        //寫入數(shù)據(jù)庫
 
    }
 
}
 
catch (Exception $exceptione)
 
{
 
    $this->rollback();//回滾
 
}
 
 
 
return $money

在加了事務(wù)的悲觀鎖后,所有請求到已經(jīng)開啟事務(wù)的代碼,都會進行阻塞只有提交了事務(wù)或者回滾才會處理下一個請求。

然而這樣的代碼并不能防御并發(fā)。這也是很多開發(fā)中的問題,確實做了事務(wù)加鎖,依然沒有用。 加事務(wù)必須是在查詢內(nèi)加,不然依舊會造成并發(fā)問題。 我們在改改把讀放入事務(wù)鎖中。

<?php
 
 
 
$buy=intval($_GET['buy']);
 
try
 
{
 
    $this->startTrans();//開啟事務(wù)
 
    $money=100;//數(shù)據(jù)庫查詢的用戶余額
 
    if ($money>0&& $money-$buy>0)
 
    {
 
        sleep(10);
 
        $moeny-=$buy;
 
        $this->commit(); //提交事務(wù)
 
        //寫入數(shù)據(jù)庫
 
    }
 
}
 
catch (Exception $exceptione)
 
{
 
    $this->rollback();//回滾
 
}
 
 
 
return $money

這樣也解決了臟讀的問題。

  臟讀:

(針對未提交數(shù)據(jù))如果一個事務(wù)中對數(shù)據(jù)進行了更新,但事務(wù)還沒有提交,另一個事務(wù)可以“看到”該事務(wù)沒有提交的更新結(jié)果,這樣造成的問題就是,如果第一個事務(wù)回滾,那么,第二個事務(wù)在此之前所“看到”的數(shù)據(jù)就是一筆臟數(shù)據(jù)。

當(dāng)然也有更復(fù)雜的情況可能框架有多個端。這種二次利用的情況更加難以審計。

 

在實際審計中我們想要精通一個語言的代碼審計我們要做的更難

  1. 要比產(chǎn)品更懂業(yè)務(wù)
  2. 要比測試更懂流程
  3. 要比開發(fā)更懂代碼
  4. 要比架構(gòu)更懂框架

自此囊括從初級到高級的學(xué)習(xí)就到此為止了,但我們的學(xué)習(xí)卻不能停止,這也是我個人對php代碼審計學(xué)習(xí)的理解肯定有不合理的地方,不足可以直接提出修改,共勉!

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多