pico ctf 2017 web exploitation write up

# 目的
解き方を思い出すため

# 解法

##  Level1

###  What Is Web
websiteを開いてdeveloperツールを使うと以下のhtmlソースを見ることができる

```html:index.html

</html>

<!-- Cool! Look at me! This is an HTML file. It describes what each page contains in a format your browser can understand. -->
<!-- The first part of the flag (there are 3 parts) is 8d96c7d8966 -->
<!-- What other types of files are there in a webpage? -->

```

3つのフラグがあることがわかる
こんな感じで他のファイルにも隠されているのではと考えると簡単に2つ見つかる

```js:script.js
/* This is a javascript file. It contains code that runs locally in your
 * browser, although it has spread to a large number of other uses.
 *
 * The final part of the flag is 3b680682297
 */


function sayHI(){
	alert("Hi there!");
}
```

```css:hacker.css
/*
This is the css file. It contains information on how to graphically display
the page. It is in a seperate file so that multiple pages can all use the same 
one. This allows them all to be updated by changing just this one.
The second part of the flag is 8106eabacc0 
*/
```

3つ繋げたらflagになる

## Level2

### My First SQL
sqlインジェクションを試みる.

まず, パスワードに`'`のみでloginすると`There Was An Error With Your Request`と`select * from users where user = '' and pass = ''';`が帰ってくる. これでSQLインジェクションが有効なことがわかり, さらにクエリの全貌までわかった. userカラムは考えずwhere句にorを入れることを考える.

よって, パスワードに` a ' or 'a' = 'a`を入れるとflag get.

### TW_GR_E1_ART
node.jsを使ったロールプレイングゲームとなっている.
4Fでたくさんのフラグがあり, ある一つの正しいflagを使用するとctfのflagがゲットできるが間違ったflagを使用するとゲームが終わってしまい初めからやり直すことになってしまう.

まんまとやり直しになったのでヒントを見る.

>  I think this game is running on a Node.js server. If it's configured poorly, you may be able to access the server's source. If my memory serves me correctly, Node servers have a special file that lists dependencies and a start command; maybe you can use that file to figure out where the other files are?

node.jsのソースが見れちゃいそうなので, まず[package.json](http://shell2017.picoctf.com:16929/package.json)にアクセスしてみる

```json:package.json
{
  "name": "rogue-1",
  "version": "1.0.0",
  "main": "server/serv.js",
  "dependencies": {
    "beautiful-log": "^1.3.0",
    "body-parser": "^1.16.0",
    "callsite": "^1.0.0",
    "clone": "^2.1.0",
    "colors": "^1.1.2",
    "cookie-parser": "^1.4.3",
    "deep-diff": "^0.3.4",
    "dequeue": "^1.0.5",
    "express": "^4.14.1",
    "mongodb": "^2.2.25",
    "morgan": "^1.7.0",
    "nconf": "^0.8.4",
    "promise": "^7.1.1",
    "socket.io": "^1.7.2",
    "sprintf": "^0.1.5"
  },
  "devDependencies": {},
  "scripts": {
    "prestart": "node server/init.js",
    "start": "node server/serv.js"
  }
}
```

サーバーを起動する2つのスクリプトの場所がわかるので, 一旦[server/serv.js](http://shell2017.picoctf.com:16929/server/serv.js)を見てみる.

```js:serv.js
var express		= require("express");
var app			= express();

app.use(require("body-parser").json());
app.use(require("cookie-parser")());
// app.use(require("morgan")("dev"));

var http		= require("http").Server(app);
var path		= require("path");
var fs			= require("fs");
var Promise		= require("promise");
var logger		= require("./logger");
var sprintf		= require("sprintf");
var nconf		= require("nconf");
var db			= require("./db");
var io			= require("socket.io")(http);

require("./game")(app, io);

nconf.argv().env();

var PORT = nconf.get("port") || 8888;

app.get("/", function(req, res){
	res.status(200);
	res.sendFile(path.join(__dirname, "../public/html/index.html"));
});

app.use(express.static(path.join(__dirname, "..")));

http.listen(PORT, function(){
	logger.info("[server] Listening on *:" + PORT);
});

process.on("unhandledRejection", (err) => {
	logger.error(err.stack);
});
```

gameに関するエンドポイントが[server/game.js](http://shell2017.picoctf.com:16929/server/game.js)にあることがわかる. このソースは長いので, `flag`で検索をかけてみる.

```js:game.js
			case "revealFlag":
				if (entity.items[action.item].effects[i].check == 64) {
					outcome.flag = process.env["PICO_CTF_FLAG"];
				}
				break;
		}
```

`.check`が64ならばflagがもらえそう. ここで?[server/config.js](http://shell2017.picoctf.com:16929/server/config.js)ファイルをみるとflagの生成場所に関するソースが見れる.

```js:config.js
					var r = Math.floor(idx / 5) + 1;
					var c = (idx % 5) + 1;

					return createFlag(idx, { r: r, c: c });
				}),
```

ここで, `idx = 64`で計算すると `r = 13, c = 5`となる.


```
[ -4,  -3,  -3,  -3,  -3,  -3,  -2],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1, flag, -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -5,   1,   1, stair, 1,   1,  -1],
[ -5,   1,   1,   1,   1,   1,  -1],
[ -6,  -7,  -7,  -7,  -7,  -7,  -8]
```
この場所のflagが正しいflagとなる

### TW_GR_E2_EoTDS

同じようなゲームが再び.
4階に行くとフラグが壁に囲まれていてgetできなくなっている.
敵もアイテムを取得できる特性を使う.

今度は`/server/ai.js`の中身を見ると敵の動きが書かれている.

```:ai.js
// If the player is nearby (at most 3 steps) or is in the same room, move toward them
...
// If we're in a corridor, try to keep moving in the same direction
...
// If nothing else, do something random
```
部屋が同じか3ステップ以内ならば近づく.
1直線の場所ならば同じ方向に進み続ける.
そうでなければランダムに進むらしい.

4階で斜め移動を駆使して敵と鬼ごっこをしているとランダムでプレイヤーが通れない場所を通ってくれる.
そこで壁の外から敵に近づいてフラグを取らせて敵を倒すとフラグget.
ただのゲーム.

<img width="597" alt="スクリーンショット 2018-09-20 23.37.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/253063/21097960-08ed-4aff-895f-7829bead1cbc.png">

##  Level3

### Biscuit