웹 사이트에 접속하면 PicoBrowser를 사용하는 사람들만 접속이 가능하다고 알려준다. 추가로 잼민이가 "너는 누구냐?"라고 한다.
사용하는 browser를 PicoBrowser로 바꿔야 할 것 같은데 어떻게 바꿀 수 있을까. userAgent를 이용하면 browser를 바꿀 수 있다.
userAgent는 browser에서 보내는 HTTP header이다. userAgent에서는 어떤 broswer, OS, 기기를 사용하는지를 알 수 있다.
개발자 도구를 켜고 console 창에 navigator.userAgent를 입력하면 userAgent 정보를 볼 수 있다.
navigator.userAgent
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36'
userAgent를 분석해 보자.
1. Mozilla/5.0
이 부분은 옛날 Netscape 사의 Mozilla browser의 identifier였다고 한다. 요즘에는 웹 표준을 따르고 있다는 의미에서 관습처럼 사용한다. 5.0을 버전을 가리킨다.
2. Macintosh; Intel Mac Os X 10_15_7
Intel 맥을 사용하고 있으며 OS의 버전은 macOS 10.15.7을 사용한다고 알려준다.
나는 사실 ARM 맥을 쓰고 있고, macOS Sequoia 15.0.1 버전을 사용한다. 처음에는 왜 틀린 정보를 저렇게 당당하게 보여주지 라고 생각했다. Mac에서 Rosetta2를 이용하는 경우 ARM 맥을 쓰고 있어도 user-agent에서 intel 칩을 사용한다고 나올 수 있고, browser를 업데이트하지 않으면 낮으면 저렇게 틀린 정보를 보여줄 수 있다고 한다.
3. AppleWebKit/537.36
Safari, Chrome 등과 같은 browser에서 사용하는 rendering engine이다. AppleWebKit은 Apple에서 만들었는데 HTML,CSS,javascript를 처리해서 웹 페이지를 보여주는 데 사용된다.
4. (KHTML, like Gecko)
KHTML 역시 rendering 엔진이다. KDE project에서 KHTML을 만들었다.
Gecko는 Firefox의 rendering 엔진이다. like Gecko는 Firefox처럼 Gecko를 사용하는 여러 browser들과 잘 호환된다는 뜻이다.
이분 글에서 나온 것처럼 개발자 도구를 켜고 Custom user agent를 PicoBrowser로 설정하자. 웹 페이지를 새로고침 하면 다른 사이트에서 오는 사람들은 믿을수가 없다고 한다.
custon userAgent를 쓰다보니 외부에서 접속을 하는 사실이 티가 났나 보다. 우리가 picoCTF 문제 주소로 접속하고 있다는 사실을 보여줘야 한다. 이럴 때 Referer header를 이용한다. Referer는 HTTP header 중 하나로 request가 어디에서 왔는지 request 경로에 대한 정보를 담고 있다. 문제는 내가 사용하고 있는 Brave에서는 개발자도구에서 referer header를 추가하기가 어렵다는 것이다.
여기서부터는 browser만을 이용해서 문제를 풀기가 어렵다고 판단했다. Burp Suite를 사용하던지, Python requests를 사용하던지 다른 도구를 이용하는 방법으로 접근하자. 개인적으로는 Burp Suite가 불편해서 Python requests를 쓰기로 했다.
User-Agent, Referer는 headers argument에 담아서 request를 보내면 된다.
import requests
headers={
'User-Agent':'PicoBrowser',
'Referer':'http://mercury.picoctf.net:1270/'
}
res=requests.get('http://mercury.picoctf.net:1270/',headers=headers)
print(res.text)
이 사이트는 2018년에만 접속할 수 있었다고 한다.
Sorry, this site only worked in 2018.
Date header로 날짜를 설정할 수 있다. 심심해서 크리스마스로 날짜를 설정했다.
import requests
headers={
'User-Agent':'PicoBrowser',
'Referer':'http://mercury.picoctf.net:1270/',
'Date':'2018-12-25'
}
res=requests.get('http://mercury.picoctf.net:1270/',headers=headers)
print(res.text)
그러자 response에서 추적할 수 있는 사용자들은 믿을 수 없다고 한다.
I don't trust users who can be tracked.
여기서 좀 막혔었다. HTTP에서는 DNT(Do Not Track)이라는 header가 있는데 DNT 값을 1로 설정하면 특정 사이트에서 tracking을 못하게 한다.
import requests
headers={
'User-Agent':'PicoBrowser',
'Referer':'http://mercury.picoctf.net:1270/',
'Date':'2018-03-01',
'DNT':'1'
}
res=requests.get('http://mercury.picoctf.net:1270/',headers=headers)
print(res.text)
이번에는 스웨덴 사람들만을 위한 사이트라고 한다.
This website is only for people from Sweden.
스웨덴 ip를 이용해서 request를 보내야 할 것 같다. HTTP의 X-Forwarded-For header를 이용하면 웹 서버에 보내는 ip를 설정할 수 있다. 아무 ip나 설정해도 되는데 보통 0으로 끝나는 ip 들은 특수한 용도로 사용되는 경우가 많아서 1로 끝나는 ip를 골랐다.
import requests
headers={
'User-Agent':'PicoBrowser',
'Referer':'http://mercury.picoctf.net:1270/',
'Date':'2018-03-01',
'DNT':'1',
'X-Forwarded-For':'103.45.246.1',
}
res=requests.get('http://mercury.picoctf.net:1270/',headers=headers)
print(res.text)
스웨덴에 있는 건 맞는데, 스웨덴어를 할 수 있어야 된다고 한다. 언어도 스웨덴어로 바꿔야 된다.
You're in Sweden but you don't speak Swedish?
HTTP header 중에서 언어와 관련이 있는 header는 두 개(Accept-Language, Content-Language)이다.
Accept-Language는 client가 선호하는 언어를 설정할 수 있는 HTTP header이다. Content-Language 역시 web resource를 받는 사람이 선호하는 언어로 설정할 수 있는 HTTP header이다.
Accept-Language, Content-Language 두 header 모두 선호하는 언어를 설정할 수 있다는 공통점이 있다. 차이점은 Accept-Language는 client가 server에게 보내는 header이고 Content-Language는 server가 client에게 보내는 header라는 것이다.
나는 Accept-Language header를 사용하기로 했다. 별 이유는 없다. Accept-Language를 선택한 이유는 그냥 알파벳 순서가 빠르기 때문이다. 구글 검색 결과 스웨덴의 Accept-Language 값은 sv-SE이다.
import requests
headers={
'User-Agent':'PicoBrowser',
'Referer':'http://mercury.picoctf.net:1270/',
'Date':'2018-03-01',
'DNT':'1',
'X-Forwarded-For':'103.45.246.1',
'Accept-Language':'sv-SE'
}
res=requests.get('http://mercury.picoctf.net:1270/',headers=headers)
print(res.text)
response에서는 flag를 제외한 HTML 코드가 많이 나온다.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Who are you?</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<link href="https://getbootstrap.com/docs/3.3/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="jumbotron">
<p class="lead"></p>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<h3 style="color:green">What can I say except, you are welcome</h3>
</div>
</div>
<br/>
<b>picoCTF{http_h34d3rs_v3ry_c0Ol_much_w0w_f56f58a5}</b>
</div>
<footer class="footer">
<p>© PicoCTF</p>
</footer>
</div>
<script>
$(document).ready(function(){
$(".close").click(function(){
$("myAlert").alert("close");
});
});
</script>
</body>
</html>
Flag를 찾기는 했는데 Regular expression을 이용하면 flag만 뽑아 낼 수 있다.
import requests
import re
headers={
'User-Agent':'PicoBrowser',
'Referer':'http://mercury.picoctf.net:1270/',
'Date':'2018-03-01',
'DNT':'1',
'X-Forwarded-For':'103.45.246.1',
'Accept-Language':'sv-SE'
}
res=requests.get('http://mercury.picoctf.net:1270/',headers=headers)
print(re.findall(r'<b>(.*)</b>',res.text)[0])
HTTP header들은 굉장히 멋있다는 뜻의 flag가 나온다. (http headers very cool much wow)
picoCTF{http_h34d3rs_v3ry_c0Ol_much_w0w_f56f58a5}
'picoCTF' 카테고리의 다른 글
Dear Diary (0) | 2024.11.14 |
---|---|
Blast from the past (1) | 2024.11.10 |
No Sql Injection (4) | 2024.11.07 |
ASCII Numbers (3) | 2024.11.06 |
weirdSnake (0) | 2024.11.06 |