ZAP Structural Modifier
저는 취약점을 찾을 때 중요한 3가지를 뽑으라고 한다면 아마도 기술에 대한 이해
, 대상에 대한 이해
, 그리고 센스
를 택할 것 같습니다. 물론 이외에도 중요한 요소들은 정말 많겠지만 이 3가지는 일할 때 가장 많이 느끼는 부분이였어요.
갑자기 이런 이야기를 하는건 오늘 주제가 대상에 대한 이해와 연관이 깊기 때문입니다. ZAP에 관련된 부분이지만, Burp 사용자도 충분히 영감을 얻어가실 수 있을거라 생각이 드네요.
ZAP Structural Modifier 입니다. 그럼 시작하죠 🚀
Structural Modifier
ZAP은 Site Tree의 구조를 수정할 수 있는 Structural Modifier 란 기능을 지원하고 있습니다. 이를 이용하면 분석 시 구조를 좀 더 직관적으로 볼 수 있도록 변경할 수 있고, Scanning 시 이를 기반으로 동작하도록 유도할 수 있습니다.
Structural Modifier은 2가지를 지원하고 있습니다.
- Data Driven Nodes
- Structural Parameters
Data Driven Nodes
Data Driven Nodes(DDN)는 정규 표현식을 기반으로 Sites 를 재 구성하는 기능으로 여러 URL 패턴을 하나의 Node로 묶어서 표현할 수 있습니다. 예를들어 웹 서비스의 Pagenation으로 인해 유사한 패턴의 많은 URL이 Sites에 보일 수 있습니다. 이는 우리가 분석하는데 있어서 굉장히 방해가 되죠.
- /comtents/page/1
- /comtents/page/2?sort=1
- /comtents/page/3?sort=1&limit=5
이 때 DDN을 이용하면 Sites에서 하나의 Node로 표현할 수 있습니다. Context > Structure 에서 Data Driven Nodes 타입으로 Modifier를 등록하면 바로 Sites가 변경됩니다.
매번 정규표현식을 직접 작성하기에는 굉장히 불편하기 때문에 유사한 URL을 여러개 선택하여 우클릭 후 Flag as Context 메뉴를 통해 정규표현식 패턴을 등록할 수 있습니다.
DDN 등록 이후 Sites에는 정규표현식에 따라서 URL들이 그룹화되어 표현됩니다.
Structural Parameters
Structural Parameters는 파라미터 이름을 기준으로 Sites의 구조를 재 구성하는 기능입니다.
예를들어 이러한 API 들이 있다고 가정합니다. 이 때 service 파라미터를 기준으로 처리하는 로직이 달라질 수 있다고 한다면 우리의 테스트는 이 파라미터에 따라서 추가적으로 여러 경우의 수를 가지게 됩니다.
- GET /test/users?service=M1&limit=50
- POST /test/setting?service=M1&level=4
- GET /test/users?service=M2&limit=50
- GET /test/users?service=P1&limit=50
그리고 ZAP의 경우 기본적으로 /test/users
라는 하나의 페이지로 묶어서 표현합니다. 그리고 Burpsuite는 모든 URL 패턴을 표기하기 때문에 두건 모두 가독성이 떨어지게 됩니다. 이 때 ZAP에선 Structural Parameters를 이용하여 조금 더 구조화된 Sites를 만들어 이를 해결할 수 있습니다.
Context > Structure 에서 Structural Parameters 파라미터 타입으로 Modifier를 추가합니다. 이 때 Name에 들어가는 값이 파라미터의 이름이 됩니다. 원하는 파라미터로 설정하면 이후부터 Sites에서 아래와 같이 원하는 파라미터를 기준으로 대상을 분리해서 구조를 볼 수 있게 됩니다.
저는 service 파라미터를 기준으로 잡았고, 설정 이후부턴 Sites에서 service 파라미터를 기준으로 분리해서 구조를 표현해줍니다.
SPA 구조의 서비스나 동일한 API, 페이지에서 특정 파라미터를 통해서 분기하는 경우 구조를 알기도 어렵고 테스팅 시 매번 파라미터 값의 의미와 리스트를 알고 있어야하는데, 이렇게 Structural Parameters Modifier를 설정하게 되면 구조를 보는데 있어서 굉장히 편리해집니다.
More custom? AddOn
ZAP 2.10 이후 버전부턴 AddOn에서 이를 컨트롤할 수 있게 인터페이스가 제공됩니다.
public interface Variant {
public void setMessage(HttpMessage msg);
public List<NameValuePair> getParamList();
public String setParameter(
HttpMessage msg, NameValuePair originalPair, String param, String value);
public String setEscapedParameter(
HttpMessage msg, NameValuePair originalPair, String param, String value);
default String getLeafName(String nodeName, HttpMessage msg) {
return null;
}
default List<String> getTreePath(HttpMessage msg) throws URIException {
return null;
}
}
자세한 내용은 ZAP 쪽 코드를 참고해주세요!
Conclusion
이력을 보니 2020년 즉 2.9버전에서 나온 기능이였네요. 미리 알았더라면 정말 유용하게 썼을 기능인데 이제서야 알았다니 아쉬움이 약간 남습니다. 물론 약간은 번거로울 수 있는 작업이겠지만, 결국 나중에 들어갈 삽질 시간을 줄일 수 있고 잘 습관 들이면 시야를 늘릴 수 있을 것 같단 생각이 듭니다.
References
- https://www.zaproxy.org/docs/desktop/start/features/structmods/
- https://github.com/zaproxy/zaproxy/blob/main/zap/src/main/java/org/parosproxy/paros/core/scanner/Variant.java