PySand

Zadanie

ecsc19_pysand.png

W zadaniu możemy wykonać dowolny pythonowy kod, ale w momencie kiedy coś wywoła audithooka wprowadzonego w pythonie 3.8, rzucony zostanie wyjątek, a program się zakończy.

Rozwiązanie

W PEPie wprowadzającym audit do Pythona jest rozdział o tym że nie jest to sandbox. Ominięcie go nie powinno być więc zbyt trudne. Jest tam także wspomniany inny PEP, który pierwotnie wprowadzał ten pomysł. W sekcji Restricting the Entry Point możemy przeczytać:

Prevent os.system

The spython entry point aborts all os.system calls.

It should be noted here that subprocess.Popen(shell=True) is allowed (though logged via the platform-specific process creation events). This tradeoff is made because it is much simpler to induce a running application to call os.system with a single string argument than a function with multiple arguments, and so it is more likely to be used as part of an exploit. There is also little justification for using os.system in production code, while subprocess.Popen has a large number of legitimate uses. Though logs indicating the use of the shell=True argument should be more carefully scrutinised.

Sysadmins are encouraged to make these kinds of tradeoffs between restriction and detection, and generally should prefer detection.

Innym sposobem na znalezienie możliwej do użycia funkcji jest zajrzenie do dokumentacji Pythona 3.8, ponieważ każda funkcja wywołująca Audit jest tam opisana. Po chwili jej przeglądania, można zauważyć, że np. funkcja os.posix_spawn nie wywoła Audita, więc możemy jej użyć. Stąd pełny payload:

print(sys.modules['os'].posix_spawn("/bin/cat", ["/bin/cat", "/app/flag.txt"], sys.modules['os'].environ))

Otrzymana flaga: ecsc19{Aud1tButDontTrust}