相關函數:php
php://input
僞協議能夠讀取$_POST[]
的值漏洞產生緣由:正則表達式
extract()函數當只有一個參數時,默認的第二參數是:EXTR_OVERWRITE,若是有變量發生衝突,則覆蓋已有的變量。數組
當設置了$shiyan
變量而且$shiyan==$contents
時,獲得flag。
可是咱們不知道$flag
也就不知道$content
是多少了,因而get一個flag變量覆蓋原有的$flag
的值,而且這個值與get的$shiyan
相等。瀏覽器
構造payload:函數
//利用extract()函數變量覆蓋漏洞+php僞協議 http://123.206.87.240:9009/1.php?shiyan=999&flag=data://,999 //利用file_get_content()函數返回字符串+php弱類型(null == "string" ==》 true) http://123.206.87.240:9009/1.php?shiyan= http://123.206.87.240:9009/1.php?shiyan=&flag= http://123.206.87.240:9009/1.php?shiyan=&content=
//file_get_contents()+php://input+post漏洞
?shiyan=xiao&flag=php://input(並設置post爲xiao)
flag:post
flag{bugku-dmsj-p2sm3N}
strcmp()函數語法:編碼
int strcmp( string $str1, string $str2) 注意該比較區分大小寫。 參數 str1 第一個字符串。 str2 第二個字符串。 返回值 若是 str1 小於 str2 返回 < 0;若是 str1 大於 str2 返回 > 0;若是二者相等,返回 0。
strcmp只能比較字符串,當a爲數組時,strcmp返回false;又由於是==只比較值是否相等(先自動轉換類型再比較)加密
必須讓他們兩個相等才能夠,用數組繞過試下,構造payload:url
?a[]或者?a[]=
flag:spa
flag{bugku_dmsj_912k}
eregi()函數語法:
eregi — 不區分大小寫的正則表達式匹配 int eregi( string $pattern, string $string[, array &$regs] ) 本函數和 ereg() 徹底相同,只除了在匹配字母字符時忽略大小寫的區別。 ereg()函數 int ereg ( string $pattern , string $string [, array &$regs ] ) 以區分大小寫的方式在 string 中尋找與給定的正則表達式 pattern 所匹配的子串。 若是找到與 pattern 中圓括號內的子模式相匹配的子串而且函數調用給出了第三個參數 regs,則匹配項將被存入 regs 數組中。
$regs[1] 包含第一個左圓括號開始的子串,$regs[2] 包含第二個子串,以此類推。$regs[0] 包含整個匹配的字符串。 若是在 string 中找到 pattern 模式的匹配則返回所匹配字符串的長度,若是沒有找到匹配或出錯則返回 FALSE。
若是沒有傳遞入可選參數 regs 或者所匹配的字符串長度爲 0,則本函數返回 1。
ereg有兩個漏洞:
Urldecode()函數:
把十六進制字符串轉換爲中文字符
Urlencode()函數:
把中文字符轉換爲十六進制,而後在每一個字符前面加一個標識符%
注意事項:
大部分的瀏覽器都會對傳過來的值進行urlencode,同時$_GET、$_REQUEST這些都會自動用urldecode解析瀏覽器傳過來的值
利用瀏覽器默認對提交的數據進行一次url解碼
代碼審計須要知足兩個條件:
1. id裏面不能包含字符串「hackerDJ」
2. id通過urldecode()以後等於字符串「hackerDJ」
構造payload:;
//只需對字符串"hackerDJ"一部分二次url編碼便可 h對應的十六進制碼爲0x108 %108進行一次url編碼%2568 http://123.206.87.240:9009/10.php?id=%2568ackerDJ
//eregi()函數規定id中不能包含hackerDJ,直接將hackerDJ用url編碼,放進去仍是同樣,由於url在$get進行傳參的時候通常都進行了一次解碼,
//因此上面的url編碼實際上已經被解碼了,直接就彈出了**「not allowed!」**因而將獲得的url編碼進行二次編碼便可:
hackerDJ => %2568%2561%2563%256B%2565%2572%2544%254A
flag:
flag{bugku__daimasj-1t2}
md5()函數漏洞:
md5()函數不能處理數組,使用數組繞過,md5(array)會返回null,因此用數組繞過,構造payload:
?username[]=a&password[]=s
老題:==弱類型繞過,QNKCDZO的MD5值是0e開頭解析爲0,因此直接找一個username讓他的MD5值也爲0e開頭就好
flag:
flag{bugk1u-ad8-3dsa-2}
ereg()函數語法:
int ereg ( string $pattern , string $string [, array &$regs ] ) 以區分大小寫的方式在 string 中尋找與給定的正則表達式 pattern 所匹配的子串。 若是找到與 pattern 中圓括號內的子模式相匹配的子串而且函數調用給出了第三個參數 regs,則匹配項將被存入 regs 數組中。
$regs[1] 包含第一個左圓括號開始的子串,$regs[2] 包含第二個子串,以此類推。$regs[0] 包含整個匹配的字符串。 若是在 string 中找到 pattern 模式的匹配則返回所匹配字符串的長度,若是沒有找到匹配或出錯則返回 FALSE。
若是沒有傳遞入可選參數 regs 或者所匹配的字符串長度爲 0,則本函數返回 1。
存在漏洞:
strpos()函數語法:
strpos — 查找字符串首次出現的位置
int strpos( string $haystack, mixed $needle[, int $offset = 0] )
返回 needle 在 haystack 中首次出現的數字位置。
參數
haystack
在該字符串中進行查找。
needle
若是 needle 不是一個字符串,那麼它將被轉換爲整型並被視爲字符的順序值。
offset
若是提供了此參數,搜索會從字符串該字符數的起始位置開始統計。若是是負數,搜索會從字符串結尾指定字符數開始。
返回值
返回 needle 存在於 haystack 字符串起始的位置(獨立於 offset)。同時注意字符串位置是從0開始,而不是從1開始的。
若是沒找到 needle,將返回 FALSE。
ereg()能夠進行%00截斷,繞過正則匹配
利用ereg()第一個漏洞作的,payload:
?password=1%00–
利用第二個漏洞,payload:
?password[]=
flag:
flag{ctf-bugku-ad-2131212}
is_numeric()函數語法:
is_numeric — 檢測變量是否爲數字或數字字符串 bool is_numeric( mixed $var) 若是 var 是數字和數字字符串則返回 TRUE,不然返回 FALSE。
is_numeric()對於空字符%00,不管%00放在前面仍是後面均可以判斷爲非數值,而空格%20只能放在數值後面,實質上都是弱類型轉換。
payload:
?password=1337%00
?password=1337%20
?password=1337a
?password[]=1336(1337...)
flag:
flag{bugku_null_numeric}
sha1()函數語法:
(PHP 4 >= 4.3.0, PHP 5, PHP 7) sha1 — 計算字符串的 sha1 散列值 string sha1( string $str[, bool $raw_output = false] ) 參數 str 輸入字符串。 raw_output 若是可選的 raw_output 參數被設置爲 TRUE,那麼 sha1 摘要將以 20 字符長度的原始格式返回,不然返回值是一個 40 字符長度的十六進制數字。 返回值 返回 sha1 散列值字符串。
利用sha1函數不能處理數組進行構造payload:
?name[]=1&password[]=2
flag:
flag{bugku--daimasj-a2}
MD5()函數語法:
md5 — 計算字符串的 MD5 散列值 string md5( string $str[, bool $raw_output = false] ) 參數 str 原始字符串。 raw_output 若是可選的 raw_output 被設置爲 TRUE,那麼 MD5 報文摘要將以16字節長度的原始二進制格式返回。 返回值 以 32 字符十六進制數字形式返回散列值。
//下面的特殊字符串通過MD5函數處理過以後相等
QNKCDZO 0e830400451993494058024219903391 s878926199a 0e545993274517709034328855841020 s155964671a 0e342768416822451524974117254469 s214587387a 0e848240448830537924465865611904 s214587387a 0e848240448830537924465865611904 s878926199a 0e545993274517709034328855841020 s1091221200a 0e940624217856561557816327384675 s1885207154a 0e509367213418206700842008763514
md5生成的以「0e」開頭的哈希值都解釋爲0,因此PHP在判斷時會認爲相同。
構造payload:
?a=s214587387a
flag:
flag{bugku-dmsj-am9ls}
ord()函數語法:
int ord( string $string) 返回字符串 string 第一個字符的 ASCII 碼值。 該函數是 chr() 的互補函數。 參數 string 一個字符。 返回值 返回整型的 ASCII 碼值。
題目中會要求輸入的password中不能有0~9數字,而且還須要判斷$number==$_GET[password]。
因此將$number=3735929054轉換爲16進制「deadc0de」,再在前面加上0x表示16進制。
利用雙等於號"=="能夠對不一樣進制的數比較來構造payload:
?password=0xdeadc0de
flag:
flag{Bugku-admin-ctfdaimash}
ereg()函數語法:
int ereg ( string $pattern , string $string [, array &$regs ] )
以區分大小寫的方式在 string 中尋找與給定的正則表達式 pattern 所匹配的子串。
若是找到與 pattern 中圓括號內的子模式相匹配的子串而且函數調用給出了第三個參數 regs,則匹配項將被存入 regs 數組中。$regs[1] 包含第一個左圓括號開始的子串,$regs[2] 包含第二個子串,以此類推。$regs[0] 包含整個匹配的字符串。
若是在 string 中找到 pattern 模式的匹配則返回所匹配字符串的長度,若是沒有找到匹配或出錯則返回 FALSE。若是沒有傳遞入可選參數 regs 或者所匹配的字符串長度爲 0,則本函數返回 1。
strpos()函數語法:
strpos — 查找字符串首次出現的位置
int strpos( string $haystack, mixed $needle[, int $offset = 0] )
返回 needle 在 haystack 中首次出現的數字位置。
參數
haystack
在該字符串中進行查找。
needle
若是 needle 不是一個字符串,那麼它將被轉換爲整型並被視爲字符的順序值。
offset
若是提供了此參數,搜索會從字符串該字符數的起始位置開始統計。若是是負數,搜索會從字符串結尾指定字符數開始。
返回值
返回 needle 存在於 haystack 字符串起始的位置(獨立於 offset)。同時注意字符串位置是從0開始,而不是從1開始的。
若是沒找到 needle,將返回 FALSE。
利用strlen()函數和strpos()函數不能處理數組進行構造payload
或
利用ereg()函數的%00截斷漏洞,並且輸入的值小於8位,大於9999999,使用科學計數法,輸入1e8,00截斷*-*便可
構造payload:
?password=1e8%00*-*
?password[]=
flag:
flag{bugku-dm-sj-a12JH8}
必須是1-9的數字,並且要包含#biubiubiu
坑點:#須要用url編碼
利用數組繞過,構造payload:
?ctf[]=
?ctf=1%00%23biubiubiu
flag:
flag{Bugku-D-M-S-J572}
preg_match()函數用法:
int preg_match( string $pattern, string $subject[, array &$matches[, int $flags = 0[, int $offset = 0]]] ) 搜索subject與pattern給定的正則表達式的一個匹配. 參數 pattern 要搜索的模式,字符串類型。 subject 輸入字符串。 matches 若是提供了參數matches,它將被填充爲搜索結果。 $matches[0]將包含完整模式匹配到的文本, $matches[1] 將包含第一個捕獲子組匹配到的文本,以此類推。 flags flags能夠被設置爲如下標記值: PREG_OFFSET_CAPTURE 若是傳遞了這個標記,對於每個出現的匹配返回時會附加字符串偏移量(相對於目標字符串的)。注意:這會改變填充到matches參數的數組,使其每一個元素成爲一個由第0個元素是匹配到的字符串,第1個元素是該匹配字符串在目標字符串subject中的偏移量。 offset 一般,搜索從目標字符串的開始位置開始。可選參數 offset 用於指定從目標字符串的某個位置開始搜索(單位是字節)。 返回值 preg_match()返回 pattern 的匹配次數。它的值將是0次(不匹配)或1次,由於preg_match()在第一次匹配後將會中止搜索。preg_match_all()不一樣於此,它會一直搜索subject 直到到達結尾。若是發生錯誤preg_match()返回 FALSE。
利用preg_match()函數不能處理數組進行構造payload:
POST:password=1
POST:password[]=1
flag:
flag{Bugku_preg_match}