XSS (Cross Site Scripting)
해킹 경력에 관심이 있고 해킹할 수 없는 것을 해킹하고 싶다면 - 우리는 인재를 모집합니다! (유창한 폴란드어 필기 및 구사 필수).
방법론
당신이 제어하는 값 (매개변수, 경로, 헤더?, 쿠키?)가 HTML에 반영되거나 JS 코드에 사용되고 있는지 확인합니다.
반영/사용되는 맥락을 찾습니다.
반영된 경우
어떤 기호를 사용할 수 있는지 확인하고, 그에 따라 페이로드를 준비합니다:
원시 HTML에서:
새로운 HTML 태그를 생성할 수 있습니까?
javascript:
프로토콜을 지원하는 이벤트나 속성을 사용할 수 있습니까?보호를 우회할 수 있습니까?
HTML 콘텐츠가 클라이언트 측 JS 엔진 (AngularJS, VueJS, Mavo...)에 의해 해석되고 있다면, 클라이언트 측 템플릿 주입을 악용할 수 있습니다.
JS 코드를 실행하는 HTML 태그를 생성할 수 없다면, Dangling Markup - HTML scriptless injection을 악용할 수 있습니까?
HTML 태그 내부에서:
원시 HTML 맥락으로 나갈 수 있습니까?
JS 코드를 실행하기 위해 새로운 이벤트/속성을 생성할 수 있습니까?
당신이 갇힌 속성이 JS 실행을 지원합니까?
보호를 우회할 수 있습니까?
JavaScript 코드 내부에서:
<script>
태그를 이스케이프할 수 있습니까?문자열을 이스케이프하고 다른 JS 코드를 실행할 수 있습니까?
템플릿 리터럴 ``에 입력이 있습니까?
보호를 우회할 수 있습니까?
실행 중인 Javascript 함수
실행할 함수의 이름을 지정할 수 있습니다. 예:
?callback=alert(1)
사용된 경우:
DOM XSS를 악용할 수 있으며, 입력이 어떻게 제어되는지와 제어된 입력이 어떤 싱크에 사용되는지 주의해야 합니다.
복잡한 XSS 작업을 할 때 알아두면 유용한 내용:
Debugging Client Side JS반영된 값
XSS를 성공적으로 악용하기 위해 가장 먼저 찾아야 할 것은 당신이 제어하는 값이 웹 페이지에 반영되고 있는지입니다.
중간에 반영된 경우: 매개변수의 값이나 경로가 웹 페이지에 반영되고 있다면 반영된 XSS를 악용할 수 있습니다.
저장되고 반영된 경우: 당신이 제어하는 값이 서버에 저장되고 페이지에 접근할 때마다 반영된다면 저장된 XSS를 악용할 수 있습니다.
JS를 통해 접근된 경우: 당신이 제어하는 값이 JS를 사용하여 접근되고 있다면 DOM XSS를 악용할 수 있습니다.
맥락
XSS를 악용하려고 할 때 가장 먼저 알아야 할 것은 당신의 입력이 어디에 반영되고 있는지입니다. 맥락에 따라 다양한 방법으로 임의의 JS 코드를 실행할 수 있습니다.
원시 HTML
당신의 입력이 원시 HTML 페이지에 반영된다면, JS 코드를 실행하기 위해 일부 HTML 태그를 악용해야 합니다: <img , <iframe , <svg , <script
... 이들은 사용할 수 있는 많은 HTML 태그 중 일부에 불과합니다.
또한 클라이언트 측 템플릿 주입을 염두에 두십시오.
HTML 태그 속성 내부
당신의 입력이 태그의 속성 값 내부에 반영된다면 다음을 시도할 수 있습니다:
속성과 태그에서 이스케이프하여 (그럼 원시 HTML에 있게 됩니다) 악용할 새로운 HTML 태그를 생성합니다:
"><img [...]
속성에서 이스케이프할 수 있지만 태그에서 이스케이프할 수 없는 경우 (
>
가 인코딩되거나 삭제된 경우), 태그에 따라 JS 코드를 실행하는 이벤트를 생성할 수 있습니다:" autofocus onfocus=alert(1) x="
속성에서 이스케이프할 수 없는 경우 (
"
가 인코딩되거나 삭제된 경우), 어떤 속성에 당신의 값이 반영되고 있는지에 따라 모든 값을 제어하는지 아니면 일부만 제어하는지에 따라 악용할 수 있습니다. 예를 들어,onclick=
과 같은 이벤트를 제어하면 클릭할 때 임의의 코드를 실행할 수 있습니다. 또 다른 흥미로운 예는href
속성으로,javascript:
프로토콜을 사용하여 임의의 코드를 실행할 수 있습니다:href="javascript:alert(1)"
당신의 입력이 "악용할 수 없는 태그" 내부에 반영된다면,
accesskey
트릭을 시도하여 취약점을 악용할 수 있습니다 (이를 악용하기 위해서는 어떤 형태의 사회 공학이 필요합니다): `" accesskey="x" onclick="alert(1)" x="
클래스 이름을 제어할 경우 Angular가 XSS를 실행하는 이상한 예:
Inside JavaScript code
이 경우 귀하의 입력은 HTML 페이지의 <script> [...] </script>
태그, .js
파일 또는 javascript:
프로토콜을 사용하는 속성 사이에 반영됩니다:
<script> [...] </script>
태그 사이에 반영되는 경우, 귀하의 입력이 어떤 종류의 따옴표 안에 있더라도</script>
를 주입하고 이 컨텍스트에서 탈출할 수 있습니다. 이는 브라우저가 먼저 HTML 태그를 파싱하고 그 다음에 내용을 파싱하기 때문에, 주입된</script>
태그가 HTML 코드 안에 있다는 것을 인식하지 못합니다.JS 문자열 안에 반영되는 경우 마지막 트릭이 작동하지 않으면 문자열에서 탈출하고, 코드를 실행하며 JS 코드를 재구성해야 합니다 (오류가 발생하면 실행되지 않습니다):
'-alert(1)-'
';-alert(1)//
\';alert(1)//
템플릿 리터럴 안에 반영되는 경우
${ ... }
구문을 사용하여 JS 표현식을 삽입할 수 있습니다:var greetings = `Hello, ${alert(1)}`
유니코드 인코딩은 유효한 자바스크립트 코드를 작성하는 데 사용됩니다:
자바스크립트 호이스팅
자바스크립트 호이스팅은 함수, 변수 또는 클래스를 사용한 후에 선언할 수 있는 기회를 참조하여, 선언되지 않은 변수나 함수를 사용하는 XSS 시나리오를 악용할 수 있습니다. 자세한 내용은 다음 페이지를 확인하세요:
JS Hoisting자바스크립트 함수
여러 웹 페이지에는 실행할 함수의 이름을 매개변수로 받아들이는 엔드포인트가 있습니다. 실제로 흔히 볼 수 있는 예는 ?callback=callbackFunc
와 같은 것입니다.
사용자가 직접 제공한 것이 실행되려고 하는지 알아내는 좋은 방법은 매개변수 값을 수정하는 것입니다 (예: 'Vulnerable'로 변경) 그리고 콘솔에서 다음과 같은 오류를 찾는 것입니다:
취약한 경우, 값을 보내기만 해도 경고를 트리거할 수 있습니다: ?callback=alert(1)
. 그러나 이러한 엔드포인트는 내용을 검증하여 문자, 숫자, 점 및 밑줄만 허용하는 것이 매우 일반적입니다 ([\w\._]
).
그러나 이러한 제한이 있더라도 여전히 일부 작업을 수행할 수 있습니다. 이는 유효한 문자를 사용하여 DOM의 모든 요소에 접근할 수 있기 때문입니다:
이를 위한 몇 가지 유용한 함수:
You can also try to trigger Javascript functions directly: obj.sales.delOrders
.
그러나 일반적으로 지정된 함수를 실행하는 엔드포인트는 흥미로운 DOM이 많지 않은 엔드포인트입니다. 같은 출처의 다른 페이지는 더 많은 작업을 수행할 수 있는 더 흥미로운 DOM을 가질 것입니다.
따라서 다른 DOM에서 이 취약점을 악용하기 위해 Same Origin Method Execution (SOME) 취약점이 개발되었습니다:
SOME - Same Origin Method ExecutionDOM
JS 코드가 공격자가 제어하는 데이터인 location.href
를 안전하지 않게 사용하고 있습니다. 공격자는 이를 악용하여 임의의 JS 코드를 실행할 수 있습니다.
Universal XSS
이러한 종류의 XSS는 어디에서나 발견될 수 있습니다. 이는 웹 애플리케이션의 클라이언트 취약점에만 의존하지 않고 모든 컨텍스트에 의존합니다. 이러한 종류의 임의 JavaScript 실행은 RCE를 얻거나, 클라이언트와 서버에서 임의의 파일을 읽는 데 악용될 수 있습니다. 일부 예시:
Server Side XSS (Dynamic PDF)Electron Desktop AppsWAF 우회 인코딩 이미지
원시 HTML 내에서 주입하기
입력이 HTML 페이지 내에서 반영되거나 이 컨텍스트에서 HTML 코드를 이스케이프하고 주입할 수 있는 경우, 첫 번째로 해야 할 일은 <
를 사용하여 새 태그를 생성할 수 있는지 확인하는 것입니다: 해당 문자를 반영해보고 HTML 인코딩되었는지, 삭제되었는지, 또는 변경 없이 반영되었는지 확인하십시오. 마지막 경우에만 이 경우를 악용할 수 있습니다.
이 경우에도 Client Side Template Injection을 염두에 두십시오.
_참고: HTML 주석은****** -->
또는 ****--!>
**로 닫을 수 있습니다._
이 경우 블랙/화이트리스트가 사용되지 않는다면, 다음과 같은 페이로드를 사용할 수 있습니다:
하지만, 태그/속성 블랙/화이트리스트가 사용되고 있다면, 어떤 태그를 생성할 수 있는지 브루트포스해야 합니다. 어떤 태그가 허용되는지 찾은 후, 발견된 유효한 태그 내에서 속성/이벤트를 브루트포스하여 공격할 수 있는 방법을 확인해야 합니다.
태그/이벤트 브루트포스
https://portswigger.net/web-security/cross-site-scripting/cheat-sheet로 가서 _태그를 클립보드에 복사_를 클릭하세요. 그런 다음, Burp intruder를 사용하여 모든 태그를 전송하고 WAF에서 악성으로 발견되지 않은 태그가 있는지 확인하세요. 사용할 수 있는 태그를 발견한 후, 유효한 태그를 사용하여 모든 이벤트를 브루트포스할 수 있습니다(같은 웹 페이지에서 _이벤트를 클립보드에 복사_를 클릭하고 이전과 같은 절차를 따르세요).
사용자 정의 태그
유효한 HTML 태그를 찾지 못했다면, 사용자 정의 태그를 생성하고 onfocus
속성으로 JS 코드를 실행해 볼 수 있습니다. XSS 요청에서 URL을 #
로 끝내야 페이지가 해당 객체에 포커스하고 코드를 실행합니다:
블랙리스트 우회
어떤 종류의 블랙리스트가 사용되고 있다면, 몇 가지 간단한 트릭으로 우회해 볼 수 있습니다:
길이 우회 (작은 XSS)
다양한 환경을 위한 더 많은 작은 XSS 페이로드 여기에서 찾을 수 있습니다 및 여기에서.
The last one is using 2 unicode characters which expands to 5: telsr More of these characters can be found here. To check in which characters are decomposed check here.
Click XSS - Clickjacking
취약점을 악용하기 위해 사용자가 미리 채워진 데이터가 있는 링크나 양식을 클릭해야 하는 경우, Clickjacking을 악용해 볼 수 있습니다 (페이지가 취약한 경우).
Impossible - Dangling Markup
JS 코드를 실행하기 위한 속성이 있는 HTML 태그를 만드는 것이 불가능하다고 생각한다면, Dangling Markup을 확인해야 합니다. 왜냐하면 JS 코드를 실행하지 않고도 취약점을 악용할 수 있기 때문입니다.
Injecting inside HTML tag
Inside the tag/escaping from attribute value
HTML 태그 내부에 있다면, 시도할 수 있는 첫 번째 방법은 태그에서 탈출하고 이전 섹션에서 언급된 기술 중 일부를 사용하여 JS 코드를 실행하는 것입니다. 태그에서 탈출할 수 없다면, 태그 내부에 새로운 속성을 만들어 JS 코드를 실행하려고 시도할 수 있습니다. 예를 들어, (이 예제에서는 속성에서 탈출하기 위해 이중 따옴표를 사용하지만, 입력이 태그 내부에 직접 반영되는 경우에는 필요하지 않습니다):
스타일 이벤트
Within the attribute
속성에서 탈출할 수 없는 경우("
가 인코딩되거나 삭제됨)에도 불구하고, 어떤 속성에 값이 반영되는지에 따라 모든 값 또는 일부만 제어할 수 있다면 이를 악용할 수 있습니다. 예를 들어, onclick=
와 같은 이벤트를 제어할 수 있다면 클릭 시 임의의 코드를 실행할 수 있습니다.
또 다른 흥미로운 예는 href
속성으로, 여기서 javascript:
프로토콜을 사용하여 임의의 코드를 실행할 수 있습니다: href="javascript:alert(1)"
HTML 인코딩/URL 인코딩을 사용한 이벤트 내 우회
HTML 태그 속성의 값 내 HTML 인코딩된 문자는 런타임에 디코딩됩니다. 따라서 다음과 같은 것이 유효합니다(페이로드는 굵게 표시됨): <a id="author" href="http://none" onclick="var tracker='http://foo?
'-alert(1)-'
';">Go Back </a>
모든 종류의 HTML 인코딩이 유효하다는 점에 유의하세요:
URL 인코딩도 작동한다는 점에 유의하세요:
유니코드 인코드를 사용하여 내부 이벤트 우회
특수 프로토콜 속에서
여기에서 javascript:
또는 data:
프로토콜을 사용하여 임의의 JS 코드를 실행할 수 있는 몇 가지 장소가 있습니다. 일부는 사용자 상호작용이 필요하고 일부는 필요하지 않습니다.
이 프로토콜을 주입할 수 있는 장소
일반적으로 javascript:
프로토콜은 href
속성을 허용하는 모든 태그에서 사용할 수 있으며 대부분의 src
속성을 허용하는 태그에서 사용할 수 있습니다 (단, <img>
는 제외).
기타 난독화 기법
이 경우, 이전 섹션의 HTML 인코딩 및 유니코드 인코딩 기법도 유효합니다. 왜냐하면 당신이 속성 안에 있기 때문입니다.
또한 이러한 경우를 위한 또 다른 멋진 트릭이 있습니다: 입력이 javascript:...
안에 있을 때 URL 인코딩이 되어 있더라도, 실행되기 전에 URL 디코딩이 됩니다. 따라서 단일 인용부호를 사용하여 문자열에서 탈출해야 하고 URL 인코딩이 되어 있는 것을 본다면, 상관없습니다, 실행 시간 동안 단일 인용부호로 해석됩니다.
다음에 유의하세요. 페이로드를 인코딩하기 위해 URLencode + HTMLencode
를 어떤 순서로 사용하더라도 작동하지 않습니다, 하지만 페이로드 안에서 혼합할 수 있습니다.
javascript:
와 함께 Hex 및 Octal 인코딩 사용하기
Hex 및 Octal 인코딩을 사용하여 iframe
의 src
속성 안에서 JS를 실행할 HTML 태그를 선언할 수 있습니다:
리버스 탭 나빙
If you can inject any URL in an arbitrary <a href=
tag that contains the target="_blank" and rel="opener"
attributes, check the 다음 페이지에서 이 동작을 악용하세요:
on Event Handlers Bypass
First of all check this page (https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) for useful "on" event handlers. In case there is some blacklist preventing you from creating this even handlers you can try the following bypasses:
XSS in "Unexploitable tags" (hidden input, link, canonical, meta)
From here 이제 숨겨진 입력을 악용할 수 있습니다:
그리고 메타 태그:
여기에서: 희생자가 키 조합을 누르도록 설득할 수 있는 경우, 숨겨진 속성 내에서 XSS 페이로드를 실행할 수 있습니다. Firefox Windows/Linux에서 키 조합은 ALT+SHIFT+X이고, OS X에서는 CTRL+ALT+X입니다. 접근 키 속성에서 다른 키를 사용하여 다른 키 조합을 지정할 수 있습니다. 벡터는 다음과 같습니다:
XSS 페이로드는 다음과 같을 것입니다: " accesskey="x" onclick="alert(1)" x="
블랙리스트 우회
여기서 이미 다양한 인코딩을 사용하는 몇 가지 트릭이 노출되었습니다. 다시 돌아가서 다음을 배울 수 있는 곳을 확인하세요:
HTML 인코딩 (HTML 태그)
유니코드 인코딩 (유효한 JS 코드일 수 있음):
\u0061lert(1)
URL 인코딩
16진수 및 8진수 인코딩
데이터 인코딩
HTML 태그 및 속성에 대한 우회
이전 섹션의 블랙리스트 우회를 읽어보세요.
JavaScript 코드에 대한 우회
다음 섹션의 JavaScript 우회 블랙리스트를 읽어보세요.
CSS-가젯
웹의 아주 작은 부분에서 XSS를 발견하고 상호작용이 필요한 경우(예: 마우스 오버 요소가 있는 푸터의 작은 링크), 해당 요소가 차지하는 공간을 수정하여 링크가 실행될 확률을 극대화할 수 있습니다.
예를 들어, 요소에 다음과 같은 스타일을 추가할 수 있습니다: position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5
하지만 WAF가 스타일 속성을 필터링하는 경우, CSS 스타일링 가젯을 사용할 수 있습니다. 예를 들어,
.test {display:block; color: blue; width: 100%}
및
#someid {top: 0; font-family: Tahoma;}
이제 링크를 수정하여 다음 형식으로 만들 수 있습니다.
<a href="" id=someid class=test onclick=alert() a="">
이 트릭은 https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703에서 가져온 것입니다.
JavaScript 코드 내 주입
이 경우 입력이 .js
파일의 JS 코드 내에 반영되거나 <script>...</script>
태그 사이, JS 코드를 실행할 수 있는 HTML 이벤트 사이, 또는 javascript:
프로토콜을 허용하는 속성 사이에 있을 것입니다.
<script> 태그 이스케이프
코드가 <script> [...] var input = 'reflected data' [...] </script>
내에 삽입된 경우, <script>
태그를 닫는 것을 이스케이프할 수 있습니다:
Note that in this example we haven't even closed the single quote. This is because HTML parsing is performed first by the browser, which involves identifying page elements, including blocks of script. The parsing of JavaScript to understand and execute the embedded scripts is only carried out afterward.
Inside JS code
If <>
are being sanitised you can still escape the string where your input is being located and execute arbitrary JS. It's important to fix JS syntax, because if there are any errors, the JS code won't be executed:
Template literals ``
문자열을 생성하기 위해 JS는 단일 및 이중 따옴표 외에도 백틱 **``
**을 허용합니다. 이는 템플릿 리터럴로 알려져 있으며 ${ ... }
구문을 사용하여 JS 표현식을 내장할 수 있습니다.
따라서 입력이 백틱을 사용하는 JS 문자열 내에서 반영되고 있음을 발견하면, ${ ... }
구문을 악용하여 임의의 JS 코드를 실행할 수 있습니다:
이것은 다음과 같이 악용될 수 있습니다:
인코딩된 코드 실행
유니코드 인코드 JS 실행
JavaScript 우회 블랙리스트 기법
문자열
특수 이스케이프
JS 코드 내의 공백 대체
자바스크립트 주석 (에서 자바스크립트 주석 트릭)
JavaScript 새 줄 (from JavaScript 새 줄 trick)
자바스크립트 공백
주석 안의 Javascript