Skip to content

Commit ab8a349

Browse files
committed
docs: add http example
1 parent db2fc1b commit ab8a349

File tree

10 files changed

+239
-7
lines changed

10 files changed

+239
-7
lines changed

bin/padoracle.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ const MODE = {
3232
--plain, -p Target plain text.
3333
3434
Examples
35-
$ padoracle ./examples/crackme-challenge.js --iv-cipher UGFkT3JhY2xlOml2L2NiYyiFmLTj7lhu4mAJHakEqcIIoYU0lIUXKx+PmTaUHLV0 --size 16
36-
$ padoracle ./examples/crackme-challenge.js --size 16 --plain "{\\"id\\":1,\\"roleAdmin\\":true,\\"name\\":\\"yelo\\",\\"url\\":\\"https://yelo.cc\\"}"
35+
$ padoracle ./examples/0.node/challenge.js --iv-cipher UGFkT3JhY2xlOml2L2NiYyiFmLTj7lhu4mAJHakEqcIIoYU0lIUXKx+PmTaUHLV0 --size 16
36+
$ padoracle ./examples/0.node/challenge.js --size 16 --plain "{\\"id\\":1,\\"roleAdmin\\":true,\\"name\\":\\"yelo\\",\\"url\\":\\"https://yelo.cc\\"}"
37+
$ padoracle ./examples/0.node/challenge.js --size 16 --plain "{\\"roleAdmin\\":1}"
3738
`, {
3839
flags: {
3940
ivCipher: {
File renamed without changes.

examples/crackme/index.js renamed to examples/0.node/crackme/index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
const { Crypto } = require('../../test/helpers/crypto')
1+
const { Crypto } = require('../../common/crypto')
22
const delay = require('delay')
33

4-
const SPEED = 1
4+
const DELAY = process.env.DELAY || 1
55

66
const crackme = (() => {
77
const KEY = Buffer.from('abcdefghijklmnopqrstuvwxyz123456')
@@ -30,8 +30,8 @@ const crackme = (() => {
3030
return createToken()
3131
},
3232
async auth (token) {
33-
if (SPEED) {
34-
await delay(SPEED)
33+
if (DELAY) {
34+
await delay(DELAY)
3535
}
3636
return getSession(token)
3737
},

examples/0.node/readme.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## Get started
2+
3+
### Crack Plain Text
4+
```bash
5+
padoracle ./challenge.js --iv-cipher UGFkT3JhY2xlOml2L2NiYyiFmLTj7lhu4mAJHakEqcIIoYU0lIUXKx+PmTaUHLV0 --size 16
6+
```
7+
8+
### Modify Plain Text
9+
```bash
10+
padoracle ./challenge.js --size 16 --plain "{\"id\":1,\"roleAdmin\":true,\"name\":\"yelo\",\"url\":\"https://yelo.cc\"}"
11+
```

examples/1.http/challenge.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const got = require('got')
2+
3+
const PORT = process.env.PORT || 3000
4+
const ENDPOINT = `http://localhost:${PORT}`
5+
6+
const DECRYPTION_ERROR = 'Unable to decrypt'
7+
8+
const challenge = async (iv, cipher) => {
9+
let response = await got.post(`${ENDPOINT}/flag`, {
10+
body: Buffer.concat([iv, cipher]).toString('base64'),
11+
}).catch((error) => error.response)
12+
if (response.body === DECRYPTION_ERROR) {
13+
return false
14+
}
15+
return true
16+
}
17+
18+
export default challenge

examples/1.http/crackme/index.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
const micro = require('micro')
2+
const { Crypto } = require('../../common/crypto')
3+
4+
const PORT = process.env.PORT || 3000
5+
6+
const KEY = Buffer.from('abcdefghijklmnopqrstuvwxyz123456')
7+
const DEFAULT_IV = Buffer.from('PadOracle:iv/cbc')
8+
const BLOCK_SIZE = DEFAULT_IV.length
9+
10+
const DEFAULT_SESSION = '{"id":100,"roleAdmin":false}'
11+
12+
const crypto = new Crypto(KEY)
13+
14+
function createToken (session = DEFAULT_SESSION, iv = DEFAULT_IV) {
15+
const cipher = crypto.encrypt(iv, session)
16+
return `${Buffer.concat([iv, cipher]).toString('base64')}`
17+
}
18+
19+
function getSession (token) {
20+
let buf = Buffer.from(token, 'base64')
21+
let iv = buf.slice(0, BLOCK_SIZE)
22+
let cipher = buf.slice(BLOCK_SIZE)
23+
return crypto.decrypt(iv, cipher).toString('utf8')
24+
}
25+
26+
const handleErrors = fn => async (req, res) => {
27+
try {
28+
return await fn(req, res)
29+
} catch (err) {
30+
micro.send(res, err.statusCode, err.message)
31+
}
32+
}
33+
34+
const app = async (req) => {
35+
if (req.url === '/token') {
36+
return createToken()
37+
}
38+
if (req.url === '/flag' && req.method === 'POST') {
39+
let body = await micro.text(req)
40+
let session
41+
try {
42+
session = getSession(body)
43+
} catch (error) {
44+
throw micro.createError(400, 'Unable to decrypt')
45+
}
46+
try {
47+
session = JSON.parse(session)
48+
} catch (error) {
49+
throw micro.createError(400, 'Unable to parse JSON')
50+
}
51+
if (!session.roleAdmin) {
52+
throw micro.createError(401, 'Unauthorized')
53+
}
54+
return '{FLAG}'
55+
}
56+
throw micro.createError(404, 'Not found')
57+
}
58+
59+
const server = micro(handleErrors(app))
60+
61+
server.listen(PORT, () => {
62+
console.log(`\nServer is running on ${PORT}`)
63+
console.log('\nApi:')
64+
console.log(`1. Get token: \`curl http://localhost:${PORT}/token\``)
65+
console.log(`2. Get flag: \`curl -X POST http://localhost:${PORT}/flag -d {token}`)
66+
console.log('\nExample:')
67+
console.log(`curl -X POST http://localhost:${PORT}/flag -d $(curl http://localhost:${PORT}/token -s)`)
68+
})

examples/1.http/readme.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## Get started
2+
### Prepair crackme server
3+
```bash
4+
node ./crackme
5+
```
6+
7+
### Crack Plain Text
8+
```bash
9+
padoracle ./challenge.js --iv-cipher $(curl http://localhost:3000/token -s) --size 16
10+
```
11+
12+
### Modify Plain Text
13+
```bash
14+
padoracle ./challenge.js --size 16 --plain "{\"id\":1,\"roleAdmin\":true,\"name\":\"yelo\",\"url\":\"https://yelo.cc\"}"
15+
```
16+
17+
Or just:
18+
```bash
19+
padoracle ./challenge.js --size 16 --plain "{\"roleAdmin\":1}"
20+
# IV (hex): f2f3b43a1a14d81de52c59d3c132201b
21+
# Cipher (hex): ffffffffffffffffffffffffffffffff
22+
# IV-Cipher (base64): 8vO0OhoU2B3lLFnTwTIgG/////////////////////8=
23+
```
24+
25+
### Verify Result
26+
```bash
27+
curl -X POST http://localhost:3000/flag -d "8vO0OhoU2B3lLFnTwTIgG/////////////////////8="
28+
# {FLAG}
29+
```

examples/common/crypto.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const crypto = require('crypto')
2+
3+
class Crypto {
4+
constructor (key, algorithm = `aes-${key.length * 8}-cbc`) {
5+
this.key = key
6+
this.algorithm = algorithm
7+
}
8+
9+
encrypt (iv, plain) {
10+
let cipher = crypto.createCipheriv(this.algorithm, this.key, iv)
11+
return Buffer.concat([cipher.update(plain), cipher.final()])
12+
}
13+
14+
decrypt (iv, cipher) {
15+
let decipher = crypto.createDecipheriv(this.algorithm, this.key, iv)
16+
return Buffer.concat([decipher.update(cipher), decipher.final()])
17+
}
18+
}
19+
20+
exports.Crypto = Crypto

package-lock.json

Lines changed: 84 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
"homepage": "https://github.com/imyelo/padoracle#readme",
3232
"devDependencies": {
3333
"ava": "^1.4.1",
34-
"delay": "^4.2.0"
34+
"delay": "^4.2.0",
35+
"micro": "^9.3.4"
3536
},
3637
"dependencies": {
3738
"esm": "^3.2.25",

0 commit comments

Comments
 (0)