건국대학교 수강신청 서비스의 취약점 지적

컴퓨터공학

2020. 08. 20.

방학이 끝나갈 즈음의 대학생에겐 다음 학기를 위한 수강신청 전투가 단연 최고의 관심사 중 하나일 것이다. 수강신청 성공을 위한 10계명이란 내용이 커뮤니티에 공유 됨에 놀랐을 정도. 이런 글을 읽고나면 학생들의 강한 학구열과, 그를 성취하기 위한 코메디 아닌 코메디를 찍어야 된다는 사실에서 비참함을 느끼곤 한다.

에타 게시글

이러한 학생들의 비애를 어루어 만지기 위해선 학교의 수강신청 시스템이 유저 및 합리적 정책에 친화적으로 개선되어야 할 것이다.

그런 맥락에서 본인은 건국대학교 수강신청 시스템을 우회 사용하는 2가지 약점을 발견하게 되었고, 1개의 논란 거리를 학생들에게 전해 들었다. 모교의 수강신청 시스템의 무궁한 발전을 위하여 이 사실을 책장 속에 넣어두지 않고 본 글로써 작성하여 지적코자 한다.

1. 수강신청 서비스 다중 로그인

건국대학교 수강신청 시스템은 오전 9시 30분에 수강신청 기능이 열리기 전에도 미리 로그인을 할 수 있으며, 학생들은 9시 30분 땡 치자마자 수강신청 페이지로 이동한다.

건국대학교 모바일 앱까지 활용한다면 PC와 모바일 총 2개의 단말기에서 수강신청 서비스에 접속해 둘 수 있다. 건국대학교 수강신청은 한 아이디 당 하나의 접속을 표방하곤 있지만, 이는 널리 잘 알려진 사실이다.

여기서 더 나아가 더 많은 수의 단말기로 서비스에 접속하여 대망의 9시 30분에 서버와 클라이언트가 연결 될 더 많은 기회를 확보할 수 있다는 것을 설명하도록 하겠다. 이것은 수강신청 시스템의 세션 관리 정책이 쉽게 우회 가능하기 벌어지는 일이다.

KUPIS 수강신청 서비스의 세션관리 양상

나는 수강신청 서비스가 한 아이디의 접속을 관리할 때 다음과 같은 정책을 쓴다고 추론한다.

  • 서버는 클라이언트의 로그인 요청에 항상 새로운 쿠키를 세팅한다

  • 수강신청 서비스는 최신 쿠키를 갖는 클라이언트에게만 서비스를 제공한다

  • 최신 쿠키와 일치하지 않는 쿠키를 소유한 클라이언트가 발견되면 세션을 파기하여 알려준다

아- 그럼 똑같은 쿠키를 쓰면 되겠네요?

정책을 우회하여 여러 대의 단말에서 수강신청 서비스에 접속하는 법은 간단하다. 하나의 브라우저에서 로그인을 하고, 브라우저에 세팅된 쿠키를 어딘가 기억해 둔다. 그리고 다른 단말기의 브라우저에 기억해둔 쿠키를 그대로 세팅하는 것이다.

이를 실험하기 위해서 크롬과 쿠키 조작을 위한 크롬 익스텐션 EditThisCookie를 사용해 보겠다.

예제: 윈도 PC와 맥북에서 수강신청 동시 접속

1. 윈도우에서 수강신청 시스템 로그인 페이지에서 로그인한다

건국대학교 수강신청 로그인

2. 브라우저에 세팅된 쿠키를 확인한다.

로그인 직후 뜨는 팝업 창이 아니라, 직접 수강신청 시스템 메인 페이지 로 이동바란다. 크롬 익스텐션 버튼을 보기 위해서이다.

EditThisCookie 기능을 연 다음. 문 밖으로 가출하는 버튼을 클릭하면 쿠키 정보가 클립보드에 복사된다.

EditThisCookie로 쿠키를 복사한다

3. 복사된 쿠키 정보를 기억하자.

나는 이메일로 복사한 쿠키 정보를 본인에게 전송했다.

복사한 쿠키

4. (맥 & 크롬) 같은 쿠키 정보를 이쪽 브라우저에도 세팅한다.

다른 컴퓨터에서 수강신청 시스템 로그인 페이지로 이동바란다. 이번에는 EditThisCookie를 연 다음, 문 안으로 들어가는 버튼을 클릭한다.

(맥북) EditThisCookie

그 다음 복사한 쿠키를 그대로 덮어 넣어주고 초록색 체크 버튼을 눌러준다. 이렇게 쿠키 덮어 씌우기가 끝이 났다.

(맥북) 쿠키 덮어쓰기

5. 메인 페이지로 이동한다

쿠키를 덮어 씌었으니 링크를 이용해 수강신청 시스템 메인 페이지로 이동 바란다. 

놀랍게도 내 맥북에서 수강신청 로그인 페이지를 거치지 않고도 시스템에 접속을 할 수 있다. 이제 윈도 PC 뿐만 아니라 맥북에서도 서비스를 정상적으로, 동시에 사용할 수 있다.

서버와 이야기 할 더 많은 기회

단말을 늘려서 시스템을 사용할 수 있다는 것은 9시 30분 치열한 접속 현장에서 수강신청 서버와 통신 성공의 확률을 높이겠다는 걸 의미한다. 하나가 접속이 느려터져서 흰 화면만 뜰 때, 다른 단말기는 접속이 될 수도 있으니까. 또한 이 취약점은 아이디 당 1개의 세션 유지라는 기존 정책을 무색하게 만들어 버린다.

2. 단순한 수강신청 GET 리퀘스트

서버로 보내는 수강신청 요청은 GET 형태의 URL 리퀘스트이다. 그런데 함께 전달해야 할 URL 패러미터가 무척이나 단순한게 골 때린다. 그러므로 수강신청 페이지가 아닌 곳에서 해당 기능을 모사시키는 것이 아주 쉬움을 밝힌다.

수강신청 리퀘스트 원리

KUPIS 수강신청 서비스 페이지의 주소는 아래와 같다.

https://kupis.konkuk.ac.kr/sugang/acd/cour/aply/courLessinApplyReg.jsp

특정 과목을 수강신청 하려면 해당 URL의 후미에 패러미터 strSbjtId=과목번호 를 추가하면 된다. 아래 예시는 3422번 과목을 수강신청하는 리퀘스트이다

https://kupis.konkuk.ac.kr/sugang/acd/cour/aply/courLessinApplyReg.jsp?strSbjtId=3422

수강신청 기능은 위 형식의 URL 리퀘스트를 전송하는 것인데, 서버는 이 요청이 수강신청 매뉴얼의 절차를 따르고 있는 것인지 확인 할 도리가 없다.

그렇다면 자동적으로, 자발적으로, 많은 수강신청 리퀘스트를 전송하는 매크로를 만들 수 있지 않을까?

그렇다. 짤막한 JavaScript 스니펫 몇 줄이면 매크로의 핵심 기능이 구현된다. 매크로가 갖추게 될 유스케이스는 이러할 것이다.

1. 수강신청 본선에서 6-8개의 과목을 순식간에 리퀘스트 하여 남들보다 빠르게 모든 과목을 등록하는 것. 사용자는 희망 과목의 과목번호를 리스트에 등록해 두고. 그럼, 과목 번호 리스트의 각 번호를 URL 패러미터에 실어 리퀘스트를 보낸다.

2. 수강신청 전투가 끝난 뒤에도 리퀘스트를 지속적으로 보내어 남아있을 과목의 빈 자리를 선점하는 것.

URL 요청을 사용하는 매크로는 클라이언트의 뷰를 사용하지 않고 서버에게 직접 리퀘스트를 전송하기 때문에 기존의 수강신청 절차보다 천 보, 만 보 앞 서는 우위를 점하게 된다. 그리고 약 11시 쯤부터 시작되는 서버 쪽의 대량 리퀘스트 세션 차단에 당할 수는 있어도, 브라우저에 캡챠를 띄우는 정책은 먹히지 않는다.

또한 모든 전투 대기원들은 9시 30분을 필두로 수강신청하기 페이지로 이동해야 하지만 URL 리퀘스트는? 그런 게 뭐니. 

수강신청 리퀘스트 자동화 도구 소스 코드

https://github.com/binchoo/kupis-sugang-automator

해당 방식으로 수강신청 리퀘스트를 보낼 수 있는 코드 템플릿을 작성하였다. 깃허브에 배포한다. 라이선스는 GPL 2.0이며 하나의 추가적인 조건을 붙인다. 해당 코드를 실제로 구현하여 수강신청 시간에 사용하지 않겠다는 것이다.

----------------------------------------------------------------------------
ADDITIONAL CONDITION
Copyright (c) 2020 /bin/choo
 
You are prohibited from using the Program in the real course registration process.
You may face the charge of Business Obstruction, also the copyright holder has
no responsibility to your abuse of the Program. The Program is only allowed to be used
to validate the vulnerabilities of the sugang system

지속적으로 수강신청 리퀘스트를 보내도록 명령할 수 있고, UI도 구현되어 있는 Javascript & HTML 기반의 소스코드이다. 본 글에서 지적하였는 서버가 노출하는 GET 리퀘스트를 사용하면 자동 리퀘스트를 구현할 수 있는데 당연히 그런 코드는 퍼블리시 할 수 없다. 그러므로 해당 로직을 보유해야 할 클래스들의 템플릿만을 제공하겠다.

대충 짜본 UI

수강신청 리퀘스트 자동화 도구 데모

템플릿으로부터 해당 기능이 정말로 구현 가능한지 거짓말 하지 않는다. 수강신청이 기간이 아닌 때를 틈타 해당 소스코드 템플릿으로 부터 매크로를 구현할 수 있음을 보여주겠다. 다음 데모 영상은 8개의 쓰레기 과목코드를 넣어 놓고 2.5초마다 일괄적으로 리퀘스트를 전송하는 화면이다.

 

3. 매크로 방지 캡챠 이슈

이번 학기 들어 들려온 소식이다. 버튼 클릭 기반의 매크로를 방지하기 위해 캡챠를 띄우는 정책이 도입되었다고 한다. 그런데 관련하여 불만을 제기하는 학생의 목소리를 몇몇 들었다. 뭘 빠르게 입력하거나 한 게 없는데 캡챠가 떴다는 식이다.

우선 내가 코드를 열어보고 확인해야 신빙성을 확인할 수 있으므로, 수강신청 페이지로 가서 코드를 열람해 보고 싶다. 하지만 지금은 수강신청 기간이 아니라 다음 기회에 진행해 보려 한다!

하지만 2번에서 지적하였듯이 수강신청 리퀘스트는 GET으로 쉽게 사용할 수 있기 때문에 해당 캡챠 정책은 이미 무효한 것으로 판정된다. 그러므로 매크로를 탐지하기 위한 로직은 서버에서 구현되어야 할 필요가 있어 보인다. 또 매크로 행위 판정에 적용되는 기준은 개발자 뇌피셜이 아니고 학생들과 합의되어 결정되어야 할 것이다. 그런 문제를 겪는 학생은 막대한 손해를 감수하는 것이기 때문이다. 이슈가 사실이라면 서비스에 추가된 기능에 대해 검수 과정을 강화하고 이슈를 적극적으로 해결해야 할 것이다.