[하루한줄] German Corona-Warn-App sever RCE

URL

Securing the fight against COVID-19

Target

Corona-Warn-App(contect tracking infrastructure of Germany)

Explain

Corona-Warn-App(이하 CWA)은 독일의 접촉자 기록/추적 인프라입니다. 이 앱이 설치된 스마트폰은 블루투스로 식별 payload를 브로드케스트하고, 블루투스의 신호 범위 내에 들어온 다른 디바이스들이 이 payload와 payload를 받은 시각을 2주간 저장합니다. 양성 판정을 받은 사용자는 검사 결과와 이에 대한 키값(Diagnosis key)을 CWA server에 전송할 수 있습니다.

CWA 서버는 Spring boot 프레임워크로 동작하며 Diagnosis key를 받아 처리하는 과정에서 Java Bean Validation 취약점이 존재합니다.

Spring boot app이 입력받은 객체를 validate 한다는 것은 그 객체가 constraint 조건에 만족하는지 확인하는 동작을 뜻합니다. constraint 조건은 ‘@’를 통해 사용합니다.

class Input {

  @Min(1)
  @Max(10)
  private int num;
  
  //...
}

int형 num의 최솟값이 1, 최댓값이 10인 constraint 조건이 걸려있는 코드입니다. @Min()이나 @Max()처럼 built-in 조건만 있는 것이 아니라 custom constraint 또한 존재하고, 이를 이용한 validation을 custom constraint validation이라 부릅니다.

input : ab${12*12}cd
output : ab144cd

custom constraint validation 동작 중 함수buildConstraintViolationWithTemplate()는 메세지 템플릿을 에러 메세지로 변환시켜줍니다. 메세지 템플릿에 ${}를 통해 Expression Language를 삽입할 수 있으며 그 실행결과가 에러 메세지에 반영됩니다. 만약 이 메세지 템플릿의 내용을 해커가 접근할 수 있다면 RCE 취약점입니다.

private void addViolation(ConstraintValidatorContext validatorContext, String message){
    validatorContext.buildConstraintViolationWithTemplate(message).addConstraintViolation();
}

CWA 서버는 buildConstraintViolationWithTemplate()을 호출하며 그 인자인 message는 사용자 입력값(Diagnosis key 속 데이터)이기 때문에 RCE 공격에 취약합니다. 사용자 입력을 sanitizing 하도록 패치되었지만, bypass가 가능하다는 평이 있습니다.