千毒网盘
源码泄露
web1.zip
代码审计
分析index.php和code.php的重要代码
- index.php:
<?php
include 'code.php';
#GET: ?_POST[code]=114514'payload POST: code=114514'payload
$pan = new Pan();
foreach(array('_GET', '_POST', '_COOKIE') as $key)
#
{
if($$key) {
foreach($$key as $key_2 => $value_2) {
/*$$key = $_GET (数组) = {_POST => {code=>114514'}}
$key_2 = _POST $value_2 = {code=>114514'}
$$key2 = $_POST $_POST = {code => 114514'}=value_2*/
if(isset($$key_2) and $$key_2 == $value_2)
unset($$key_2);
}
}
}
if(isset($_POST['code'])) $_POST['code'] = $pan->filter($_POST['code']);
/*
extract函数 该函数使用数组键名作为变量名,使用数组键值作为变量值
EXTR_SKIP - 如果有冲突,不覆盖已有的变量
*/
if($_GET) extract($_GET, EXTR_SKIP); # $_GET={_POST => {code=>114514'}} $_POST = {code=>114514'}
if($_POST) extract($_POST, EXTR_SKIP);
if(isset($_POST['code']))
{
$message = $pan->getfile();
echo <<<EOF
<div class="alert alert-dismissable alert-info">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4>
注意!
</h4> <strong>注意!</strong> {$message}
</div>
EOF;
}
?>
- code.php:
<?php
class Pan
{
public $hostname = '127.0.0.1';
public $username = 'root';
public $password = 'root';
public $database = 'ctf';
private $mysqli = null;
public function __construct()
{
$this->mysqli = mysqli_connect(
$this->hostname,
$this->username,
$this->password
);
mysqli_select_db($this->mysqli,$this->database);
}
public function filter($string)
{
$safe = preg_match('/union|select|flag|in|or|on|where|like|\'/is', $string);
#/is i:将匹配设置为不区分大小写,搜索时不区分大小写
#s: . 时匹配除换行符\n之外的任何字符,加上s修饰符子后,. 中包含换行符\n
if($safe === 0){
return $string;
}else{
return False;
}
}
#获取文件
public function getfile()
{
$code = $_POST['code'];
if($code === False) return '非法提取码!';
$file_code = array(114514,233333,666666);
if(in_array($code,$file_code))
{
$sql = "select * from file where code='$code'";
$result = mysqli_query($this->mysqli,$sql);
$result = mysqli_fetch_object($result);#从结果集中取得当前行,并作为对象返回
return '下载直链为:'.$result->url;
}else{
return '提取码不存在!';
}
}
}
可疑点
- sql注入:
查询变量可控,可能存在sql注入。
filter函数,正则匹配过滤,看到过滤了 ‘ ,无法进行sql注入
尝试绕过filter(重点)
重点就在上图的代码中,变量销毁和变量重置
if(isset($_POST['code'])) $_POST['code'] = $pan->filter($_POST['code']);
filter中传入的是$_POST['code']
,要想绕过filter对我们传入的值的过滤,就得销毁变量$_POST['code']
绕过后,接着变量重置
- 分析过程
先抓个包
抓包,get和post同时传参。
GET:?_POST[code]=114514’payload
POST: code=114514’payload
要想变量销毁,就要满足if(isset($$key_2) and $$key_2 == $value_2)
才能执行unset()
变量销毁(过程见注释):
变量重置:
最后成功进入sql语句里面执行
进行注入
就是简单的注入,没有限制