JWT에서 kid(Key Identifier) 사용 시 발생할 수 있는 문제를 기록
이번 문제의 핵심은 JWT에서 kid를 사용 시 전달되는 데이터는 알고리즘의 키값이 들어있는 path로 이번 문제에서 kid의 값은 0001이니 "/some-dir/0001"에 키값이 담겨있다고 볼 수 있다.
이 kid로 지정된 path의 파일이 아무값도 같지않는다면 signature역시 빈값으로 만들어 전달할 수 있다는 점을 이용해 kid에 /dev/null의 path를 입력하고, payload 내 user에 admin을 삽입하며 signature로는 빈값으로 생성하였다.
해당 값을 JWT로 사용할 경우 admin으로 권한 상승할 수 있다.
두번째로 JWT kid값을 DB에서 찾을 경우가 있는데 아래와 같이 JWT kid값 뒤에 싱글쿼터를 삽입하여 JWT를 생성 후 전달하면 SQL Syntax 에러로 보이는 구문이 보인다.
그렇다면 JWT kid로 전달되는 값이 Query에 어떤식으로 들어가게될까를 예상하며 아래와 같은 쿼리로 추측을 했다.
SELECT key FROM key_table WHERE kid=[kid]
특정 kid값이 JWT에 있던 key1이였으니 아래와같은 쿼리를 실행하도록 kid를 변경한다면 signature를 생성하여 JWT로 권한 상승이 가능해보인다.
SELECT key FROM key_table WHERE kid='not found file' UNION SELECT 'juice'
생성된 JWT를 삽입하면 SQLi가 성공되어 쿼리 결과가 'juice'로 떨어질것이고 서버에서는 juice를 key값으로 서명을 해석하여 변경한 JWT가 정상적으로 작동한다.