題目來源于:bugku
題目難度:難
題目描 述: 字符?正則?
題目htmnl源代碼:
<code><span style="color: #000000">
<span style="color: #0000BB"><?php <br />highlight_file</span><span style="color: #007700">(</span><span style="color: #DD0000">'2.php'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$key</span><span style="color: #007700">=</span><span style="color: #DD0000">'flag{********************************}'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$IM</span><span style="color: #007700">= </span><span style="color: #0000BB">preg_match</span><span style="color: #007700">(</span><span style="color: #DD0000">"/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i"</span><span style="color: #007700">, </span><span style="color: #0000BB">trim</span><span style="color: #007700">(</span><span style="color: #0000BB">$_GET</span><span style="color: #007700">[</span><span style="color: #DD0000">"id"</span><span style="color: #007700">]), </span><span style="color: #0000BB">$match</span><span style="color: #007700">);<br />if( </span><span style="color: #0000BB">$IM </span><span style="color: #007700">){ <br /> die(</span><span style="color: #DD0000">'key is: '</span><span style="color: #007700">.</span><span style="color: #0000BB">$key</span><span style="color: #007700">);<br />}<br /></span><span style="color: #0000BB">?></span>
</span>
</code>
題目的php代碼:
<?php
highlight_file('2.php');
$key='flag{********************************}';
$IM= preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match);
if( $IM ){ die('key is: '.$key);
}
?>
這段 PHP 代碼試圖執行幾個任務,但其中有一些錯誤和不明確的正則表達式模式。我將逐一解釋代碼的各個部分,并指出其中的問題。
highlight_file('2.php');
這行代碼將嘗試顯示 2.php
文件的源代碼。如果 2.php
文件存在并且服務器配置允許,那么你將看到它的內容。
$key='flag{********************************}';
這里定義了一個變量 $key
,其值是一個字符串,其中 "flag{"
后跟了一些星號(*
),可能代表某種隱藏或占位的內容。
- 正則表達式和
preg_match
正則表達式 "/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i"
試圖匹配某個特定的模式,但存在一些問題:
* 它試圖匹配字符串中包含多次出現的 `"key"`,但這可能不是預期的行為。
* `{4,7}` 通常用于指定前面的字符或組出現的次數范圍,但在這里它被放置在了 `"key"` 后面,這可能不是預期的使用方式。
* `\/.\/` 似乎試圖匹配一個斜杠(`\/`),后跟任何字符(`.`),再后跟另一個斜杠。但通常,在 PHP 字符串中,反斜杠(`\`)是一個轉義字符,所以 `\/` 實際上只匹配一個斜杠(`/`)。
* `(.*key)` 捕獲了以 `"key"` 結尾的任意字符序列,但前面的模式似乎并沒有為此捕獲組提供明確的上下文。
* `[a-z][[:punct:]]` 匹配一個小寫字母后跟一個標點符號字符,但這也可能不是預期的行為。
* `i` 標志表示正則表達式應該不區分大小寫,但在這個特定的正則表達式中,它可能不是必需的,因為所有的字符都是小寫或已轉義的。
preg_match
函數調用
preg_match
函數試圖在 trim($_GET["id"])
的結果中查找與正則表達式匹配的內容。如果找到匹配項,$IM
將被設置為 1
(表示成功匹配),并且 $match
數組將包含匹配的結果。
- 條件語句
如果 $IM
為真(即找到了匹配項),則執行 die('key is: '.$key);
,這將終止腳本并輸出一個包含 $key
變量值的消息。但是,由于 $key
的值已經被硬編碼為 'flag{********************************}'
,并且與正則表達式匹配的結果無關,因此這個消息將總是顯示相同的 key
值,無論是否找到了匹配項。
總結:
- 這段代碼可能試圖通過某種方式驗證或提取來自 URL 參數
id
的特定信息,但正則表達式可能不正確或不符合預期。 - 由于
$key
的值被硬編碼為固定的字符串,因此無論是否找到匹配項,輸出的key
值都將相同。 - 如果你的目的是基于 URL 參數
id
的內容來動態地設置$key
的值,那么你需要修改正則表達式和后續的邏輯以正確地提取和處理這些信息。
下面我們開始解答題目:
直接Get傳參輸入“?id=key4444key5555555key:/3/155465keyk;”即可獲取到flag
原文鏈接: CTF網絡安全大賽web題目:字符?正則? - [紅客網]網絡編程與滲透技術筆記
紅客網:blog.hongkewang.cn