Home Hack The Box - Templated
Post
Cancel

Hack The Box - Templated

Hack The Box Templated 문제를 풀어봅시다.


Description

Can you exploit this simple mistake?


Solve

문제 웹 사이트에 접근하면 다음과 같다. Flask로 만들어진 웹 페이지를 확인할 수 있다.

jinja2

URL에 test 입력시 test라는 문구가 출력된다.

test

SSTI 공격이 가능할 것으로 추측되어 $를 입력 해보니 49가 출력이 된다.

49

쉘을 실행시키기 위해 subprocess.Popen 찾았다. 인덱스는 414이다.

subprocess.Popen

이다음 cat flag.txt를 하여 플래그를 획득할 수있다.

Flag

How is RCE possible?

python에서 모든 객체는 `` 속성을 가집니다.

1
2
3
#<class 'str'>

__mro__를 통해 자신과 자신이 상속받은 클래스, 상속받은 클래스의 상위 클래스까지 순서대로 튜플 타입으로 반환합니다. __base__를 통해 object 클래스에 접근할수도 있습니다.

1
2
#(<class 'str'>, <class 'object'>) #우리는 object 타입을 이용할 것이므로 [1]인덱스를 필요로합니다.

__subclasses__는상속을 받는 클래스가 어떻게 구성이 되어 있는지를 나타냅니다. 엄청나게 많은 클래스들이 나오며 우리가 필요한 클래스 인덱스를 찾아 사용이 가능합니다.

1
2
#[<class 'type'>, <class 'weakref'>, <class 'weakcallableproxy'>, <class 'weakproxy'>, <class 'int'>, <class 'bytearray'>, <class 'bytes'>, <class 'list'>....

414 인덱스에는 subprocess.Popen이 됩니다. subprocess.Popen을 사용하는 이유는subprocess.Popen을 이용하여 쉘 명령을 실행할 수 있습니다. subprocess를 보면 os.system 모듈과 기능을 대체한다고 되어있습니다.

1
2
{ ''.__class__.__mro__[1].__subclasses__()[414] }}
#<class 'subprocess.Popen'>

Popen을 보시면 Popen의 생성자를 알 수 있습니다.

class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, group=None, extra_groups=None, user=None, umask=-1, encoding=None, errors=None, text=None)¶

args에는 id 라는 명령이 들어가며, shell=True를 통해 쉘을 호출합니다. subclasses.Popen는 기본적으로 Shell=False로 지정되기 때문에 shell=True를 통해 쉘을 호출해야합니다.

그리고stdout=-1을 통해 표준출력을 지정합니다. -1은 subprocess.PIPE을 의미합니다. subprocess.PIPE = -1인 이유 마지막으로 communicate()에서 stdout에서 데이터를 읽어옵니다.

1

id

Reference

https://me2nuk.com/SSTI-Vulnerability/ https://watchout31337.tistory.com/177 https://stackoverflow.com/questions/71547832/popen-stdout-value