Dreamhack [csrf-1]

우선 사이트에 접속하고 파일도 다운받았다. 파일은 파이썬 파일이었다.

차례대로 눌러보니

첫번째메뉴 vuln(csrf) page는 취약점을 알려주는 페이지다.

@app.route("/vuln")
def vuln():
    param = request.args.get("param", "").lower()
    xss_filter = ["frame", "script", "on"]
    for _ in xss_filter:
        param = param.replace(_, "*")
    return param

@app.route() : 외부 웹브라우져에서 웹서버로 접근 시 해당 주소로 입력을 하게 되면 특정 함수가 실행되게 도와줌.

request.args : url 파라미터의 값을 키 = 밸류 쌍으로 가진 딕셔너리

 

xss_filter에 의해서 script가 사용되지 못 한 거 같다.

memo

get으로 전달된 내용이 출력되는거 같고.

notice flag는 access denied가 떴다.

url을 살펴보면 admin이 나와있음을 알 수 있다.

flag를 눌러보니 이런 화면이 나오는데 이걸 어떻게 잘 이용해야 할거 같다.

이제 파이썬 코드를 더 자세히 살펴보겠다.

 

@app.route("/admin/notice_flag")
def admin_notice_flag():
    global memo_text
    if request.remote_addr != "127.0.0.1":
        return "Access Denied"
    if request.args.get("userid", "") != "admin":
        return "Access Denied 2"
    memo_text += f"[Notice] flag is {FLAG}\n"
    return "Ok"

접속 아이피가 127.0.0.1 이 아니면 access denied가 뜨게 되어 있다.

그리고 userid가 admin이 아니어도 접근 할 수 없다.

아이피가 127.0.0.1이고 id가 admin이면 flag가 memo에 출력되게 되어있다.

 

그럼 이제 이걸 어디서 조작해주느냐가 문제인데

일반적인 쿠키값 조작은 안되는것 같았다. 그래서 /flag페이지를 이용해야 할 것 같다.

@app.route("/flag", methods=["GET", "POST"])
def flag():
    if request.method == "GET":
        return render_template("flag.html")
    elif request.method == "POST":
        param = request.form.get("param", "")
        if not check_csrf(param):
            return '<script>alert("wrong??");history.go(-1);</script>'

        return '<script>alert("good");history.go(-1);</script>'

flag페이지에서 get방식으로 전달하면 flag.html이 나오게되고 post방식으로 전달하면 뭔가 될거 같긴하다.

check_csrf가 False인 경우에 아래 wrong을 리턴하게 되므로 True가 되어야 한다.

def read_url(url, cookie={"name": "name", "value": "value"}):
    cookie.update({"domain": "127.0.0.1"})
    try:
        options = webdriver.ChromeOptions()
        for _ in [
            "headless",
            "window-size=1920x1080",
            "disable-gpu",
            "no-sandbox",
            "disable-dev-shm-usage",
        ]:
            options.add_argument(_)
        driver = webdriver.Chrome("/chromedriver", options=options)
        driver.implicitly_wait(3)
        driver.set_page_load_timeout(3)
        driver.get("http://127.0.0.1:8000/")
        driver.add_cookie(cookie)
        driver.get(url)
    except Exception as e:
        driver.quit()
        print(str(e))
        # return str(e)
        return False
    driver.quit()
    return True

def check_csrf(param, cookie={"name": "name", "value": "value"}):
    url = f"http://127.0.0.1:8000/csrf?csrf={urllib.parse.quote(param)}"
    return read_url(url, cookie)

파이썬에 대해서 아직 잘 몰라서 대부분의 코드를 이해하지 못 했지만

post방식을 이용해 전달한 값을 url뒷부분에 붙여주고 있으므로 이를 이용해 뭔가 할 수 있을 것 같다.

read_rul을 보면 쿠키 domain이 127.0.0.1로 업데이트 되고 있는데 이를 이용하면 userid만 admin으로 어떻게 바꾸면 되지 않을까?라고 생각해본다.

 

/notice_flag에 usreid가 admin인 상태를 전달해주면 메모에 바로 flag가 출력될것 같다.

 

그냥 단순하게 /notice_flag?userid=admin 를 입력해서 제출했다.

good이 떴지만 flag는 알아낼 수 없었다.... 이렇게 하는게 아닌 듯하다.

 

여기서부터 막혀서 검색을 했는데 <img>태그를 이용하더라 

<img src=~하고 내가 공격하는 코드를 넣게 되면 img를 로드할때 자동으로 나의 코드가 실행된다고 한다.

 

<img src="/admin/notice_flag?userid=admin"> 라고 입력후 제출을 눌렀더니 띠용

갑자기 먹통이 됐다..... 뭐지?

너무 당황해서 스터디원들한테 저 갑자기 애가 연결할 수 없대요 왜이러죠!!! 하면서 도움요청...

아마 내가 너무 오래 이 페이지를 띄어놔서 그렇다는 답변이 돌아왔다

그냥 아예 창을 껐다가 새로운 포트로 접속하면 된다고 한다.

 

암튼 다시 입력하니까 good이 뜨고 memo에 가보니 따단!

풀었다!

'문제풀이 > 보안 writeup' 카테고리의 다른 글

hackerschool ftz : trainer 2  (0) 2021.07.30
hackerschool ftz : trainer 1  (0) 2021.07.30
websec.fr babysteps level04  (0) 2021.07.19
wargame.kr [SimpleBoard]  (0) 2021.07.03
[root-me] NoSQL Injection - Authentication  (0) 2021.07.02
myoskin