Skip to content

Commit 6a03f85

Browse files
committed
add example ctf challenge
1 parent 0bd9246 commit 6a03f85

File tree

5 files changed

+116
-0
lines changed

5 files changed

+116
-0
lines changed

‎example/README.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## Example
2+
3+
Launch the challenge web server on port 8887:
4+
5+
```
6+
docker-compose up -d
7+
```
8+
9+
[![asciicast](https://asciinema.org/a/aHAYBJpVnStiyYowAHV1W37he.svg)](https://asciinema.org/a/aHAYBJpVnStiyYowAHV1W37he)

‎example/challenge/config.php‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?php
2+
3+
$key = 'aGAdbFD7ABmse367Gk5wVrImvunhIkAlL0Qz1X4Yi17Lcpc9IT4tiG8jfiqJWyc4';
4+
$flag = 'FLAG{78c75409bab501f3973ac6dc7e309b59}';

‎example/challenge/index.php‎

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
require 'config.php'; // $flag $key
4+
5+
6+
function encrypt($data, $key) {
7+
$length = openssl_cipher_iv_length('aes-256-cbc');
8+
$iv = openssl_random_pseudo_bytes($length);
9+
$cipher = openssl_encrypt($data, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
10+
return base64_encode($iv . $cipher);
11+
}
12+
13+
function decrypt($data, $key) {
14+
$length = openssl_cipher_iv_length('aes-256-cbc');
15+
$data = base64_decode($data);
16+
$iv = substr($data, 0, $length);
17+
$cipher = substr($data, $length);
18+
return openssl_decrypt($cipher, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
19+
}
20+
21+
22+
if ($name = @$_POST['name']) {
23+
$data = serialize([
24+
'name' => $name,
25+
'can_see_the_flag' => FALSE,
26+
]);
27+
$session = encrypt($data, $key);
28+
$_COOKIE['session'] = $session;
29+
setcookie('session', $session);
30+
header('Location: .');
31+
exit;
32+
}
33+
34+
$showFlag = FALSE;
35+
$name = NULL;
36+
37+
if ($session = @$_COOKIE['session']) {
38+
$data = decrypt($session, $key);
39+
if ($data === FALSE) {
40+
die('session error');
41+
}
42+
$data = unserialize($data);
43+
$name = $data['name'];
44+
$showFlag = $data['can_see_the_flag'];
45+
}
46+
47+
48+
echo '<title>Find the FLAG</title>';
49+
if ($name) {
50+
echo "<h1>Hi, $name.</h1>";
51+
if ($showFlag) {
52+
echo "This is your flag: <b>$flag</b>";
53+
} else {
54+
echo "You cannot see the flag!";
55+
}
56+
} else {
57+
echo '<h1>Tell me your name!</h1>';
58+
echo '<form method="post">';
59+
echo '<input type="text" name="name" placeholder="name">';
60+
echo '&nbsp;';
61+
echo '<input type="submit" value="Go">';
62+
echo '</form>';
63+
}

‎example/docker-compose.yml‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: '3'
2+
3+
services:
4+
challenge:
5+
image: php:7-apache
6+
volumes:
7+
- ./challenge:/var/www/html:ro
8+
ports:
9+
- 8887:80
10+
11+
networks:
12+
internal:
13+
driver: bridge

‎example/exploit.py‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from padding_oracle import encrypt, decrypt, base64_encode, base64_decode, urlencode, urldecode
2+
import requests
3+
4+
session = 'ZhGw1aD3RzOX%2FliA7Qu1%2FMOqr%2Fa6jB2fN1Cj09yRwfPJkgUEZnhkpmpq5FenYBQLeyED%2BnY1DH0qPkvjcyhIqMjrYVagGRl6OaXs5cwCH2s%3D' # target this
5+
6+
# define the oracle
7+
sess = requests.Session() # connection pooling
8+
def oracle(ciphertext: bytes) -> bool:
9+
resp = sess.get('http://localhost:8887', cookies={'session': base64_encode(ciphertext)})
10+
#print(resp.status_code, resp.text) # let's see what can be a condition
11+
return 'session error' not in resp.text
12+
13+
ciphertext = base64_decode(urldecode(session))
14+
print(ciphertext, len(ciphertext))
15+
16+
block_size = 16
17+
18+
decrypted = decrypt(ciphertext, block_size, oracle, num_threads=64)
19+
print(decrypted)
20+
21+
decrypted = b'a:2:{s:4:"name";s:6:"djosix";s:16:"can_see_the_flag";b:0;}\x06\x06\x06\x06\x06\x06'
22+
modified = b'a:2:{s:4:"name";s:6:"djosix";s:16:"can_see_the_flag";b:1;}' # set can_see_the_flag to 1
23+
24+
encrypted = encrypt(modified, block_size, oracle, 64)
25+
print(encrypted)
26+
print(base64_encode(encrypted))
27+
print(urlencode(base64_encode(encrypted)))

0 commit comments

Comments
 (0)