| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | ||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 |
- echo 명령어
- 패키지
- Linked List
- 생성형AI
- pandas
- 성능평가지표
- 방콕
- 태국
- gdgm
- 레이블인코딩
- SK쉴더스
- 블록(Block)
- 보안공부
- OT후기
- 클래스
- 예외처리
- 함수
- dropna
- 루키즈
- List
- Package
- node.js
- 수업복습
- 꽉뚝짝 시장
- 지도학습
- git push -u
- 루키즈33기
- 데이터분포
- tunder client
- sqld
- Today
- Total
개발 블로그
[HackTheBox] Spookifier 본문
https://app.hackthebox.com/challenges/Spookifier
Hack The Box
app.hackthebox.com
먼저 코드를 받았음. routes.py, main.py, util.py 를 위주로 확인을 했음.
그 중에 util.py 에서 처음 보는 모듈을 확인함.
from mako.template import Template
font1 = {
'A': '𝕬',
'B': '𝕭',
'C': '𝕮',
'D': '𝕯',
'E': '𝕰',
'F': '𝕱',
'G': '𝕲',
'H': '𝕳',
'I': '𝕴',
'J': '𝕵',
'K': '𝕶',
'L': '𝕷',
'M': '𝕸',
'N': '𝕹',
'O': '𝕺',
'P': '𝕻',
'Q': '𝕼',
'R': '𝕽',
'S': '𝕾',
'T': '𝕿',
'U': '𝖀',
'V': '𝖁',
'W': '𝖂',
'X': '𝖃',
'Y': '𝖄',
'Z': '𝖅',
'a': '𝖆',
'b': '𝖇',
'c': '𝖈',
'd': '𝖉',
'e': '𝖊',
'f': '𝖋',
'g': '𝖌',
'h': '𝖍',
'i': '𝖎',
'j': '𝖏',
'k': '𝖐',
'l': '𝖑',
'm': '𝖒',
'n': '𝖓',
'o': '𝖔',
'p': '𝖕',
'q': '𝖖',
'r': '𝖗',
's': '𝖘',
't': '𝖙',
'u': '𝖚',
'v': '𝖛',
'w': '𝖜',
'x': '𝖝',
'y': '𝖞',
'z': '𝖟',
' ': ' '
}
font2 = {
'A': 'ᗩ',
'B': 'ᗷ',
'C': 'ᑢ',
'D': 'ᕲ',
'E': 'ᘿ',
'F': 'ᖴ',
'G': 'ᘜ',
'H': 'ᕼ',
'I': 'ᓰ',
'J': 'ᒚ',
'K': 'ᖽᐸ',
'L': 'ᒪ',
'M': 'ᘻ',
'N': 'ᘉ',
'O': 'ᓍ',
'P': 'ᕵ',
'Q': 'ᕴ',
'R': 'ᖇ',
'S': 'S',
'T': 'ᖶ',
'U': 'ᑘ',
'V': 'ᐺ',
'W': 'ᘺ',
'X': '᙭',
'Y': 'Ɏ',
'Z': 'Ⱬ',
'a': 'ᗩ',
'b': 'ᗷ',
'c': 'ᑢ',
'd': 'ᕲ',
'e': 'ᘿ',
'f': 'ᖴ',
'g': 'ᘜ',
'h': 'ᕼ',
'i': 'ᓰ',
'j': 'ᒚ',
'k': 'ᖽᐸ',
'l': 'ᒪ',
'm': 'ᘻ',
'n': 'ᘉ',
'o': 'ᓍ',
'p': 'ᕵ',
'q': 'ᕴ',
'r': 'ᖇ',
's': 'S',
't': 'ᖶ',
'u': 'ᑘ',
'v': 'ᐺ',
'w': 'ᘺ',
'x': '᙭',
'y': 'Ɏ',
'z': 'Ⱬ',
' ': ' '
}
font3 = {
'A': '₳',
'B': '฿',
'C': '₵',
'D': 'Đ',
'E': 'Ɇ',
'F': '₣',
'G': '₲',
'H': 'Ⱨ',
'I': 'ł',
'J': 'J',
'K': '₭',
'L': 'Ⱡ',
'M': '₥',
'N': '₦',
'O': 'Ø',
'P': '₱',
'Q': 'Q',
'R': 'Ɽ',
'S': '₴',
'T': '₮',
'U': 'Ʉ',
'V': 'V',
'W': '₩',
'X': 'Ӿ',
'Y': 'y̷',
'Z': 'z̷',
'a': '₳',
'b': '฿',
'c': '₵',
'd': 'Đ',
'e': 'Ɇ',
'f': '₣',
'g': '₲',
'h': 'Ⱨ',
'i': 'ł',
'j': 'J',
'k': '₭',
'l': 'Ⱡ',
'm': '₥',
'n': '₦',
'o': 'Ø',
'p': '₱',
'q': 'Q',
'r': 'Ɽ',
's': '₴',
't': '₮',
'u': 'Ʉ',
'v': 'V',
'w': '₩',
'x': 'Ӿ',
'y': 'y̷',
'z': 'z̷',
' ': ''
}
font4 = {
'A': 'A',
'B': 'B',
'C': 'C',
'D': 'D',
'E': 'E',
'F': 'F',
'G': 'G',
'H': 'H',
'I': 'I',
'J': 'J',
'K': 'K',
'L': 'L',
'M': 'M',
'N': 'N',
'O': 'O',
'P': 'P',
'Q': 'Q',
'R': 'R',
'S': 'S',
'T': 'T',
'U': 'U',
'V': 'V',
'W': 'W',
'X': 'X',
'Y': 'Y',
'Z': 'Z',
'a': 'a',
'b': 'b',
'c': 'c',
'd': 'd',
'e': 'e',
'f': 'f',
'g': 'g',
'h': 'h',
'i': 'i',
'j': 'j',
'k': 'k',
'l': 'l',
'm': 'm',
'n': 'n',
'o': 'o',
'p': 'p',
'q': 'q',
'r': 'r',
's': 's',
't': 't',
'u': 'u',
'v': 'v',
'w': 'w',
'x': 'x',
'y': 'y',
'z': 'z',
'1': '1',
'2': '2',
'3': '3',
'4': '4',
'5': '5',
'6': '6',
'7': '7',
'8': '8',
'9': '9',
'0': '0',
'!': '!',
'@': '@',
'#': '#',
'$': '$',
'%': '%',
'^': '^',
'&': '&',
'*': '*',
'(': '(',
')': ')',
'-': '-',
'_': '_',
'+': '+',
'=': '=',
'{': '{',
'}': '}',
'[': '[',
']': ']',
'\\': '\\',
'|': '|',
';': ';',
':': ':',
'\'': '\'',
'"': '"',
'<': '<',
',': ',',
'>': '>',
'.': '.',
'?': '?',
'/': '/',
' ': ' ',
}
def generate_render(converted_fonts):
result = '''
<tr>
<td>{0}</td>
</tr>
<tr>
<td>{1}</td>
</tr>
<tr>
<td>{2}</td>
</tr>
<tr>
<td>{3}</td>
</tr>
'''.format(*converted_fonts)
return Template(result).render()
def change_font(text_list):
text_list = [*text_list]
current_font = []
all_fonts = []
add_font_to_list = lambda text,font_type : (
[current_font.append(globals()[font_type].get(i, ' ')) for i in text], all_fonts.append(''.join(current_font)), current_font.clear()
) and None
add_font_to_list(text_list, 'font1')
add_font_to_list(text_list, 'font2')
add_font_to_list(text_list, 'font3')
add_font_to_list(text_list, 'font4')
return all_fonts
def spookify(text):
converted_fonts = change_font(text_list=text)
return generate_render(converted_fonts=converted_fonts)
음, 일단 util.py 파일 전체를 다 가져오긴 했지만 내가 본 부분은
from mako.template import Template
이 부분과
def generate_render(converted_fonts):
result = '''
<tr>
<td>{0}</td>
</tr>
<tr>
<td>{1}</td>
</tr>
<tr>
<td>{2}</td>
</tr>
<tr>
<td>{3}</td>
</tr>
'''.format(*converted_fonts)
return Template(result).render()
def change_font(text_list):
text_list = [*text_list]
current_font = []
all_fonts = []
add_font_to_list = lambda text,font_type : (
[current_font.append(globals()[font_type].get(i, ' ')) for i in text], all_fonts.append(''.join(current_font)), current_font.clear()
) and None
add_font_to_list(text_list, 'font1')
add_font_to_list(text_list, 'font2')
add_font_to_list(text_list, 'font3')
add_font_to_list(text_list, 'font4')
return all_fonts
def spookify(text):
converted_fonts = change_font(text_list=text)
return generate_render(converted_fonts=converted_fonts)
이 부분임. 위에 mako templete 이라는 처음 보는 모듈을 사용하여 Template에 담아서 렌더링 하여 출력하는 것 같았음.
그래서 먼저 mako templete을 구글링 함.
https://itinformation.tistory.com/606
Server-side Template Injection(SSTI) template 별 점검 방법
Template 별 점검 방법 * Smarty (unsecured) - PHP - 기본 Injection 확인 구문 >> {5*5} //연산 결과 : 25 >> a{*comment*}b //주석 결과 : ab - PHP 코드를 사용하는 구문 {php}$d="bHM=";system(base64_decode(str_pad(strtr($d,'-_','+/'),
itinformation.tistory.com
그랬더니 이런 사이트를 만났음.
그래서 먼저 VM 서버에 접속하여

이걸 검색해봤더니 결과가 출력됨.

그래서 바로 SSTI 취약점인 것을 알아내었음.
그 뒤에 이제 해당 티스토리를 참고하여 플래그를 알아내려고 했음.

이거 위주로 봤는데 어째서인지 잘 안되었음.. <% %> 과 ${}에 대한 파악이 제대로 되지 않아서 였음.
<%...%> mako -> 파이썬 코드 블록
${...} -> 표현식
다양한 시도 끝에 이것을 해냄.
<%f=open('/flag.txt','r')%>${f.read()}
다른 스터디원들의 얘기를 들어보니 os 모듈을 불러와서 popen을 사용한 팀원도 있었음.
'Study > Web Hacking' 카테고리의 다른 글
| [DreamHeck] XSS Filtering Bypass Advanced (0) | 2026.08.06 |
|---|---|
| [DreamHeck] web-HTTP-CLI (0) | 2026.08.05 |
| [DreamHeck] DreamDocs (0) | 2026.07.28 |
| [DreamHeck] Are you admin? (0) | 2026.07.24 |
| [DreamHeck] Image Uploader (0) | 2026.07.23 |