About codeql
CodeQL은 소스코드를 “데이터베이스처럼” 질의해서 취약점이나 코드 품질 문제를 찾는 정적 분석 도구다. GitHub는 CodeQL을 “코드를 데이터처럼 질의한다”고 설명하고, 개발자의 보안 점검 자동화와 보안 연구자의 variant analysis(같은 유형의 취약점 변종 찾기)에 쓰인다고 안내한다. 지원 언어와 프레임워크는 최신 릴리스 기준으로 정해져 있고, 보통 GitHub code scanning, CodeQL CLI, VS Code 확장과 함께 사용한다
작동 원리
CodeQL은 소스 코드의 각 요소를 데이터베이스 형태로 추상화하여 저장하는 정적 분석 도구이다.
이를 통해 사용자는 쿼리를 작성해 복잡한 코드 구조 속에서 특정 조건을 만족하는 패턴을 정교하게 찾아낼 수 있다.
예를 들어, 미사용 변수, 잠재적 버그, SQL 인젝션과 같은 보안 취약점도 쿼리 기반으로 탐지할 수 있다.
동작 과정
- 소스 코드를 CodeQL 데이터베이스로 변환
- 쿼리를 이용한 분석 및 패턴 탐색
- 결과를 바탕으로 취약점 및 코드 품질 이슈 확인
실습
Click 라이브러리에서 역직렬화 가젯을 찾아보는 방식으로 codeql 실습을 진행하였다.
java.util.PriorityQueue.readObject()
java.util.PriorityQueue.heapify()
java.util.PriorityQueue.siftDown()
java.util.PriorityQueue.siftDownUsingComparator()
org.apache.click.control.Column$ColumnComparator.compare()
org.apache.click.control.Column.getProperty()
org.apache.click.control.Column.getProperty()
org.apache.click.util.PropertyUtils.getValue()
org.apache.click.util.PropertyUtils.getObjectPropertyValue()
java.lang.reflect.Method.invoke()
com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties()
→ 대략적인 역직렬화 체인
일단 첫번째로 sink를 정의하였다.
from Callable c0, MethodAccess ma
where c0 instanceof RecursiveCallToDangerousMethod and
ma.getMethod() instanceof DangerousMethod and
ma.getEnclosingCallable() = c0
select c0, ma

위에서 정의한 sink 대로 codeql을 실행해보니까 위와 같은 결과를 얻을 수 있었다.
sink를 찾았기 때문에 source를 분석해보았다.
from Callable c0
where c0 instanceof RecursiveCallToDangerousMethod and
c0 instanceof Source
select c0
source를 찾는 쿼리는 위와 같이 작성하였고, 우리가 찾고 싶은 source는 RecursiveCallToDangerousMethod 이다. 해당 source가 아니면 Runtime.exec와 같은 메서드에 접근이 되지 않기 때문이다.

sink ↔ source가 compare로 이어져있다는 것을 알아냈다. 따라서 우리가 찾은 sink와 source 사이에 어떤 체인이 연결되어 있는지 분석해야한다.
from Callable c0, Callable c1, Callable c2, Callable c3, Callable c4,
MethodAccess ma
where c0 instanceof RecursiveCallToDangerousMethod and
ma.getMethod() instanceof DangerousMethod and
ma.getEnclosingCallable() = c0 and
c1.polyCalls(c0) and
c1 instanceof RecursiveCallToDangerousMethod and
c2.polyCalls(c1) and
c2 instanceof RecursiveCallToDangerousMethod and
c3.polyCalls(c2) and
c3 instanceof RecursiveCallToDangerousMethod and
c4.polyCalls(c3) and
c4 instanceof RecursiveCallToDangerousMethod and
c4 instanceof Source
select c4, c3, c2, c1, c0, ma
위와 같은 쿼리를 사용하여 sink 와 source 사이에 존재하는 chain들을 분석하였다.

위의 결과를 통해 Click 라이브러리에 존재하는 역직렬화 체인을 찾을 수 있었다.