ZAP에서 모든 요청에 새로운 헤더나 데이터를 추가하려면 어떻게 해야할까요? 보통은 Replacer 라는 기능을 이용해서 값을 변경하거나 새로 추가할 수 있습니다.
이 과정은 Burpsuite에서도 비슷하게 Match and Replace란 기능을 사용해서 진행하죠.
다만 ZAP Scripting 중 매번 발생하는 요청을 통제할 수 있는 Sender script가 있습니다. 이를 이용하면 스크립트로도 동일하게 구현할 수 있는데요. 오늘은 이 2가지 방법의 차이점과 특징을 살펴보도록 하죠.
Replacer
이름 그대로 값을 Replace 하는 기능입니다. 보통 단축키인 Cmd + R
이나 Options > Replacer
메뉴로 접근해서 Match 할 타입과 String을 지정하고 Replace 할 String을 지정하면 모든 Req/Res(Proxy, Manual Request, Scan 등)에서 이 정책이 적용되어 전송하게 됩니다.
이 때 Reuqest와 Response를 각각 지정할 수 있으며, 아래와 같은 Type을 가지고 있습니다.
- Request
- Request Header (will add if not present)
- Request Header String
- Request Body String
- Response
- Response Header (will add if not present)
- Response Header String
- Response Body String
Sender Script
Sender Script는 ZAP Scripting의 Type 중 하나로 송신 전, 수신 후 해당 스크립트의 이벤트 핸들러에 명시된 기능을 처리해주는 스크립트입니다. Scripts > HTTP Sender 에서 확인하실 수 있습니다.
그래서 작성하기에 따라 여러 기능을 만들 수 있으며 sendingRequest() 와 responseReceived()를 통해 처리가 가능합니다. 스크립팅이기 때문에 당연히 JS, Python, Ruby 등 여러가지 언어로 지원됩니다.
Add header request (.py)
headers = dict({"X-NEW-HEADER": "XXXXXxXX-xxXX-XXXx-xxxX-XXxxXxXXxXxX",
"Cookie": "aaa=1234"});
def sendingRequest(msg, initiator, helper):
for x in list(headers):
msg.getRequestHeader().setHeader(x, headers[x]);
def responseReceived(msg, initiator, helper):
pass;
Add header response (.py)
headers = dict({"Content-Type": "text/plain"});
def sendingRequest(msg, initiator, helper):
pass;
def responseReceived(msg, initiator, helper):
for x in list(headers):
msg.getResponseHeader().setHeader(x, headers[x]);
예를들어 이렇게 AWS Signing Process를 준수하여 x-amz-security-token 헤더를 만들 수도 있겠네요.
Replacer vs Sender Script
비슷한 기능을 수행하기 떄문에 비교해도 크게 차이는 나지 않습니다. 다만 결론을 내어보자면, Replacer는 “ GUI로 인해 쉽게 사용할 수 있다”란 이점이 있고, Sender Script는 좀 더 유연하게 Replace 규칙을 구성할 수 있다는 장점이 있습니다. (당연히 코드니깐)
Replacer | Sender Script | |
---|---|---|
Support Req/Res | O | O |
Support Header | O | O |
Support Body | O | O |
Difficulty | Easy | Medium (언어에 익숙하다면 Easy) |
Support CLI | O | O |
Support Automation | X | O |
Support API | O | X (단 이미 만들어진 것을 로드할 순 있음) |
Save setting? | Auto | Save the file (script file) |
그래서 단순히 테스트 목적으로 필요하다면 Replacer를 적극 활용하시는 것을 추천하고 만약 Replace 하는 값 자체에 변동이 있거나(예를들면 A 서비스에서 매번 키를 가져와야한다던가) 여러 사람에게 공유, 또는 저장해서 관리되는 형태의 Replace 규칙을 만들때는 Sender Script 쪽이 더 적합한 것 같습니다.
For DevOps
CLI Config + Replacer
./zap.sh -config replacer.full_list\\(0\\).description=newUA \
-config replacer.full_list\\(0\\).enabled=true \
-config replacer.full_list\\(0\\).matchtype=REQ_HEADER \
-config replacer.full_list\\(0\\).matchstr=\"User-Agent\" \
-config replacer.full_list\\(0\\).regex=false \
-config replacer.full_list\\(0\\).replacement=\"This is New UA!\"
Automation + Sender Script
./zap.sh -autorun senderScript.yaml