ZAP Custom En/Decoder 만들기
ZAP의 확장성은 Scripting Engine의 파워에서 나옵니다. URL, HTML, Base64 등 테스팅 단계에선 인/디코딩을 하는 경우가 굉장히 많은데요. 이 때 사용하는 Encode/Decode/Hash 기능 또한 Scripting으로 확장할 수 있습니다.
사실 ZAP 2.10 버전(2020년 말)에 추가된 기능이지만 당시에는 별도로 리뷰하지 않았었고, 이제서야 글로 풀어봅니다.
왜 더 만드나요?
보안 테스팅 시 잘 알려지지 않은 인코딩을 만날 수도 있고, 키가 알려진 암복호화 로직이 존재할 수도 있습니다. 또한 동적인 값을 통해 인코딩이 필요한 경우도 있습니다. 이럴 때 스크립팅을 통해 기능을 확장한다면 조금 더 편안하게 테스팅할 수 있습니다.
또한 한번 만들어진 결과는 파일로 관리할 수 있기 때문에 쉽게 재 사용할 수도 있고, 공유하여 사용하는 등의 액션도 가능합니다. 그리고 테스팅 이외에 그냥 문자열 처리 목적으로도 충분히 쓸만합니다 :D
EDH
Encode/Decode/Hash 기능은 Command + E 를 통해 단축키로 열거나 상단 메뉴바의 Tools → Encode/Decode/Hash를 눌러 열 수 있습니다.
Structure
맨 위에 Input box가 존재하며 아래 Tab들이 있고, 각 Tab에는 Output을 표시하는 여러개의 Panel이 존재합니다. 하나의 Tab에 속한 여러 Panel은 Input이 들어왔을 때 동시에 처리하여 결과를 보여줍니다.
Default
기본으로 제공해주는 Encoder, Decoder와 Hasher입니다.
Encoder | Decoders | Hashers |
---|---|---|
2 byte Illegal UTF-8 | ASCII Hex Decode | MD5 |
3 byte Illegal UTF-8 | Base 64 Decode | SHA1 |
4 byte Illegal UTF-8 | Base 64 URL Decode | SHA256 |
ASCII Hex Encode | HTML Decode | |
Base 64 Encode | JavaScript Decode | |
Base 64 URL Encode | URL Decode | |
HTML Encode | Full URL Decode | |
JavaScript Encode | ||
URL Encode | ||
Full URL Encode | ||
Unescaped Unicode Text |
Scripting
Basic
EDH가 스크립팅을 지원하기 때문에 우리는 원하는 Encoder, Decoder, Hasher를 추가할 수 있습니다. 언어는 Js, Ruby, Python, Groovy 등 ZAP에서 제공하는 스크립팅을 모두 지원하고 Java에 선언된 process 함수를 통해 동작을 구성할 수 있습니다.
@param {EncodeDecodeScriptHelper}
@param {String} value
@returns {EncodeDecodeResult}
- e.g
return helper.newResult(result)
.
- e.g
아래는 js 코드인데 process 함수에 a를 b로 치환하는 로직을 넣었습니다.
function process(helper, value){
return helper.newResult(value.replaceAll("a", "b").trim());
}
스크립트는 Encode/Decode 카테고리로 넣어주시고 Enable 해줍시다.
그리고 Cmd + e 를 통해 EDH를 열어준 후 테스트를 위해 Tab을 하나 만들어줍시다. 개인적으로 필요할 때 마다 자주 만들어서 사용합니다.
그리고, 새로운 Output도 만들어줍시다. 이 때 아까 만든 스크립트를 지정합니다.
이후에 해당 탭에서 작성하는 데이터는 우리가 만든 코드를 통해 En/Decode 됩니다.
New Hasher
하나 예시로 더 해보죠. HashProcessor를 통해서 기존에 제공하지 않는 해시를 추가해볼 수 있습니다. 꼭 predefined 되지 않아도 Java, Ruby 등 언어에서 각자의 패키지들을 로드해서 사용할 수 있기 때문에 여러가지 형태로 만들어갈 수 있습니다.
var Hasher = Java.type("org.zaproxy.addon.encoder.processors.predefined.HashProcessor");
function process(helper, value){
var output = new Hasher("sha3-256").process(value).getResult();
return helper.newResult(output);
}
Languages
Ruby
def process(helper, vaule)
return helper.newResult(vaule.gsub('a','b'))
end
Python
def process(helper, value):
return helper.newResult(value);
JS(Nashorn)
function process(helper, value){
return helper.newResult(value.replaceAll("a", "b").trim());
}
JS(Graal)
function process(helper, value){
return helper.newResult(value);
}
Groovy
import org.zaproxy.addon.encoder.processors.EncodeDecodeResult
import groovy.transform.Field
@Field final int test = 1
EncodeDecodeResult process(EncodeDecodeScriptHelper helper, String value){
return new helper.newResult(String.valueOf(test++) + "|" + value)
}