Web Security/CVE

CVE-2020-7245: CTFd Account Takeover

minpo 2024. 9. 15. 20:31

최근 GRAPE 해킹 동아리에서 CTF문제 사이트를 공개하였다. CTF 문제사이트를 위한 CTF-D라는 라이브리를 사용하였다. 이에 CTF-D에 취약점이 존재하였는지 확인하다. 간단하지만 재미있는 CVE를 찾게 되었다. 위 CVE는 account takeover vulnerability 이다.

아래 사진은 cve에 대한 트윗이다.

아래사진은 이에 대한 댓글이다.

 

account takeover vulnerability이 가능했던 이유는 filter_by라는 함수가 공백을 무시하고 필터링하는 점을 인지하지 못하였기 때문이다

 

아래 사진은 filter_by함수를 leading, trailing space(앞, 뒤 공백)을 테스트 한 결과이다. trailing space만 제거됨.

 

CVE가 존재하여 패치된 register 함수를 보면 다음과 같다.(로그인 기능)

 

패치 후 strip() 함수가 새로 생긴 것을 알 수 있다. 즉, 패치 전에 admin이라는 계정이 존재했을 때, admin\x20\x20이라는 계정을 새로 생성하는 것이 가능하다.

 

reset_password 함수를 보게되면, 패치 전에는 name을 가져와서 역직렬화를 한 뒤, name에 맞는 user를 찾고 이것의 password를 변경하였다.

결론

  1. admin\x20\x20 이라는 이름과 hackeremail@gmail.com이라는 메일로 아이디를 만든다.
  2. hackeremail@gmail.com라는 이메일로 password reset(비밀 번호 재설정)을 요청하게 되면, team(사용자)가 존재하는지 확인한다. 당연히 admin\x20\x20라는 이름으로 회원가입을 했기 때문에 아이디가 존재한다.
  3. 그렇다면, name을 직렬화 한 뒤 url를 만들어서 가입된 이메일로 보내준다.
  4. URL에 들어가서 비밀번호를 바꾸면 이름을 역직렬화 한 뒤, filter_by함수를 통해서 사용자를 구하고 사용자의 비밀번호를 변경한다. 역직렬한 name은 admin\x20\x20이다.
  5. 이때 filter_by는 앞서 말했듯이 공백을 무시하기 때문에 name이 admin인 user와 동일한 결과 값을 가져오게 되고, admin이라는 유저가 먼저 가입하였기 때문에 admin에 관련된 데이터베이스가 추출되게 된다.
  6. 이러한 admin의 데이터베이스를 우리가 입력한 비밀번호를 받아와서 변경한다.

추가적으로 아래 댓글을 분석해보면서, 위 cve가 발생될 수 있는 다른 환경을 찾아보고자 한다. (참고로 TL;DR는 "Too Long; Didn't Read"의 약자로 3줄 요약 이런의미입니다 ㅎㅎ)

 

다음과 같은 문제가 발생되는 경우는 쉽게 mysql 에서 고정 길이를 사용했을 때 찾아볼 수 있다.

create table hacker(
 idx int auto_increment primary key,
 id char(10)
);

 

다음과 같이 char(10)을 사용하게 되면, 10byte의 고정길이가 입렵된다는 소리이다. 만약 10byte 이하로 입력하게 된다면, 남는 바이트만큼 공백으로 채우게 된다(\x20)

또한, mysql에서 공백은 비교시 무시되는데

SELECT * FROM hacker WHERE id = 'admin'; 

 

필드에서 오른쪽 공백은 비교 시 무시되므로 ‘admin’과 ‘admin(공백)’은 같은 결과를 가져오게 된다.

그럼으로 만약 mysql 사용하는 웹 사이트가 Trim()과 같은 함수를 사용하지 않고 아이디를 받고 있다면, 위와 같은 CVE가 발생될 수 있다.

 

출처

https://blog.saika.kr/2020/02/cve-2020-7245-ctfd-account-takeover/

https://github.com/CTFd/CTFd/blob/master/CTFd/auth.py

https://hack-cracker.tistory.com/165