xss, memo, flag 각각의 페이지가 있다.
분석
자세히 보면 xss 값에 <script>alert(1)</script>가 들어가 있다.
그리고 이에 대해 그대로 그 결과를 보여주었다는 것은
이 웹 페이지 내에서 XSS 공격이 가능하다는 의미이다.
memo를 클릭했을 때는 memo안에 hello 값이 들어가있고,
이를 화면에 출력하고 있다.
이 부분이 중요해 보였다.
'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('<', '<') + '\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 함수를 사용해서 < 부등호를 <로 변환을 할까?
자바스크립트를 이용한 공격을 막기 위해서?
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)에 출력된다.
즉, /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 |