กลับมาอีกครั้งกับการโพสต์เกี่ยวกับการทำ lab hack อย่างในคราวนี้ก็คือ Virtual Machine จาก Vulnhub.com ในชื่อว่า Brainpan สามารถ download ได้จาก link นี้ครับ

Kali: 192.168.56.101

1. เริ่มต้นด้วยการหา IP  เป้าหมายก่อน โดยใช้ nmap

2. scan port 192.168.56.100

พบ port ที่เปิดอยู่คือ 9999, 10000

3. เข้าไปใช้งาน port 9999 พบว่าเป็น service terminal อะไรซักอย่างที่เรายังไม่ทราบว่า password คืออะไร

4. ทดสอบเข้าใช้งาน port 10000 ปรากฏว่าเป็น website ที่แสดงสถิติการโจมตีในรูปแบบต่างๆ

5. scan 192.168.56.100:10000 ด้วย nikto

พบ path ที่ชื่อว่า bin อยู่

6. พอเข้าไปก็พบว่ามีไฟล์ brainpan.exe อยู่

พอลองตรวจสอบดูก็พบว่าเป็น file PE 32bit

พอหา string ภายในไฟล์ก็ไม่ได้อะไร แต่ที่ทำให้เดาได้คือ มันคือ service ที่รันอยู่ port 9999 นั่นเอง

7. พอลองเอามารันใน Windows XP 32bit ก็พบว่าเป็น service ที่รอรับ password ใน port 9999 จริงๆด้วย

8. จากนั้นก็ลองไปเรื่อย ทั้งหา path, ทั้งไล่ดู port อื่น, และอื่นๆ เมื่อไปต่อไม่ได้และสิ้นหนทางก็เลยกลับมาคิดว่าไอ้ exe นี้น่าจะทำอะไรได้ ก็เลยเอามาเข้า Ollydbg เพื่อทำการ debug ดู เลยเริ่มจากการรัน brainpan.exe ก่อน จากนั้นก็เปิด Ollydbg ขึ้นมา

ไปที่ File -> Attach จากนั้นเลือก brainpan.exe

9. เมื่อทำการ attach process ตัว process จะอยู่ในสถานะ pause อยู่ ให้ทำการกดปุ่ม Play สีฟ้า เพื่อให้ตัว process อยู่ในสถานะ Running (ดูสถานะของ process ได้ที่ด้านล่างขวาของ Ollydbg)

10. สร้าง python script สำหรับการส่งตัว A 1000 ตัวไปยัง port 9999

เมื่อส่งไปแล้วให้เรากลับไปดูที่ Ollydbg จะพบว่า Registry EDX และ ESP มีค่า A เต็มไปหมด และตัวที่สำคัญสุดที่เราต้องการไปเปลี่ยนแปลงนั่นคือ EIP นั้นก็ถูกแทนที่ด้วย 41 ซึ่งมืค่าเท่ากับ “A” เต็มไปหมด เพราะตัวโปรแกรมเองมีช่องโหว่ที่ชื่อว่า “Buffer Overflow” นั่นเอง

*** EIP คือ Registry ที่จะชี้ว่าตำแหน่งต่อไปที่เราจะไปทำงานต่อคือตำแหน่งไหน

ซึ่งพอ EIP มันเป็นค่า 41414141 แล้วมันไม่สามารถทำงานต่อได้จึงเกิด error

ประเด็นคือเราต้องการควบคุมตัว EIP เพื่อที่จะได้กำหนดว่าคำสั่งถัดไปที่โปรแกรมจะไปทำงานคือ shellcode หรือคำสั่งของเราคืออะไร ซึ่งตอนนี้เรายังไม่รู้เพราะเราใส่ไป 1000 ตัวอักษร เราไม่รู้ว่า EIP นั้นถูกเขียนทับด้วยค่า A ตรงตำแหน่งตัวอักษรที่เท่าไหร่

11. ใช้ script ที่ชื่อว่า pattern_create.rb สร้าง string ที่มี pattern ขึ้นมา โดยในที่นี้เราจะสร้าง string ที่มี pattern และความยาวไม่เกิน 1000 ตัวอักษรจะใช้คำสั่งเป็น

จากนั้นเอาไปใส่แทนตัว buff แล้วส่งใหม่ พบว่าค่าของ EIP เปลี่ยนไปเป็น “35724134”

12. ใช้ script ที่ชื่อว่า pattern_offset.rb เพื่อหาว่าตำแหน่งที่ว่ามันคือตำแหน่งที่เท่าไหร่ ใช้คำสั่งเป็น

ก็จะทำให้ทราบว่ามันคือเริ่มที่ตำแหน่ง 524 เราก็เอา A*524 + ค่าตำแหน่งที่เราต้องการ

13. ทดสอบเปลี่ยนค่า EIP เป็น “B” ก็จะได้เป็น buff = “A”*524 + “B”*4 + “A”*(1000-524-4) ออกมาเป็น

และถ้าดูจากช่อง Memory มุมล่างขวาจะพบว่า ตำแหน่งที่ C ไปอยู่คือตำแหน่ง 0022F960 ซึ่งคือตำแหน่งเดียวกับ ESP พอดีด้วย

และถ้าดูจากจำนวนแถวของ C จะพบว่ามีทั้งสิ้น 1D4 (4 + (13*16) + (1*256)) = 468 Byte แสดงว่าเราสามารถใส่ shell code ด้านหลังได้ 468 byte นั่นเอง

14. หา bad character ที่จะถูกมองว่าเป็นค่า NULL หรือก็คือว่างเปล่า ทำให้ตัวอักษรที่หลังจากตำแหน่งนั้นๆหายไป โดยการส่งตัวอักษรทั้งหมดไปยังปลายทาง หากว่าตัวอักษรตรงจุดไหนหายไปพร้อมกับทำให้ที่เหลือถูกตั้งทิ้งไปด้วย นั่นหมายความว่าตัวนั้นคือ bad character นั่นเอง

คลิ๊กขวาที่ ESP แล้วเลือก Follow in Dump เพื่อไปดูส่วน memory ได้ง่ายๆ

พบว่าตัวที่เป็น Bad Character คือ 0x00

15. ทีนี้เรารู้ว่า ESP คือตำแหน่งเริ่มของ Shellcode ของเรา ดังนั้นสิ่งที่เราต้องการเปลี่ยน EIP คือการไปยังคำสั่งที่เป็น “JMP ESP” หมายถึงการกระโดดไปทำงานที่ตำแหน่ง ESP นั่นเอง โดยให้ไปที่ View -> Executable Modules -> กดเปิดที่ brainpan แล้ว คลิ๊กขวาภายใน brainpan execution module เลือก Search for -> All commands

กรอกใส่เป็น JMP ESP เพื่อหาตำแหน่งที่เก็บคำสั่ง JMP ESP ไว้

เราก็จะพบว่าตำแหน่งที่ว่าคือ 311712F3 หรือเขียนอ้างอิงเป็น “\xf3\x12\x17\x31” นั่นเอง

16. สร้าง backdoor python file ด้วย metasploit

จะได้ shell code มา ให้เปลี่ยนตรงจุด B และ C เป็น JMP ESP และ Shellcode ตามลำดับ

“\x90” เป็น padding ใส่ไว้ด้านหน้ากันตัว shellcode ถูกทับครับ

สร้าง Listener ของ Metasploit ไว้รอ connection ด้วย

รัน exploit โลด ก็จะได้ shell ครับ

17. ทีนี้ก่อนหน้านี้เราลองกับเครื่องเทสของเราซึ่งเป็น Windows ไปแล้ว ต่อไปจะยิง exploit ไปยังเครื่องจริงๆซึ่งเป็น Linux กันบ้าง เมื่อเปลี่ยน OS ดังนั้นเราต้องสร้าง shellcode ใหม่ครับ

18. ทำ Netcat listener ไว้รอ connection

ยิง แล้วก็จะได้ shell มาครับ

พอเข้าไปได้เสร็จปั้บยังไม่จบ เพราะตัว privilege ที่เราได้คือ puck ซึ่งเราสามารถใช้คำสั่งในสิทธิ์ root ได้คือ

19. พอรันแล้วพบว่าเป็นการใช้งานคำสั่งทั่วไป ซึ่งเราใช้ได้ 2 คำสั่งคือ network และ proclist หรือก็คือ ifconfig กับการ list คำสั่งแต่เนื่องด้วยตัว app ไม่รู้จัก terminal ของเราเลยรันไม่ได้

จะโหลดไฟล์ดังกล่าวกลับมาวิเคราะห์ก็เข้าไปไม่ได้ ก็เลยเบนเป้าไปหาอย่างอื่นก่อน แต่เท่าที่เรารู้คือ /home/anansi/bin/anansi_util น่าสนใจ และ user anansi ก็น่าสนใจเช่นกัน

พยายามทำเรื่อง privilege escalation ต่อโดยการหาไฟล์ที่เป็น sticky bit (ไฟล์ที่จะรันโดยใช้สิทธิ์ของ user ผู้สร้างไฟล์นั้นๆแทนที่จะเป็นใช้สิทธิ์ของ user ได้)โดยใช้คำสั่ง

เจอไฟล์ /usr/local/bin/validate น่าสนใจ

จะเห็นว่าไฟล์นี้เป็นของ anansi ซึ่งเป็นตัวเป้าหมายของเรา และไฟล์นี้ก็เป็น Binary อีกแล้ว คราวนี้ไฟล์ดังกล่าว ถ้าเราได้สิทธิ์ของ anansi มาเราก็อาจจะทำอะไรต่อก็เป็นได้ เมื่อลองรันดูปรากฏว่าตัว validate มันการตรวจสอบอะไรซักอย่าง

ซึ่งไม่ว่าจะใส่อะไรไปมันก็ส่งผลเป็นคำว่า pass หมดเลย

ลองใส่ตัวอักษรเข้าไป 150 ตัวก็ปรากฏว่าเกิด error “Segmentation Fault”

20. หลังจากก่อนหน้าเราทำ buffer overflow ใน Windows มาก่อน คราวนี้ต้องมาทำใน Linux กันต่อสินะ (=_=”) ผมเลย download validate กลับมาที่เครื่อง Kali ก่อนครับจากนั้นค่อยมาหา Buffer Overflow อีกที และตัว debugger ที่คราวนี้เลือกใช้คือ gdb นั่นเอง

ซึ่งตัว Kali ที่ผมใช้ดันเป็น 64bit แต่ตัว Brainpan เป็น 32bit ดังนั้นจำเป็นต้อง add 32bit architecture เข้าไปก่อน โดยใช้คำสั่ง

เปิดใช้งาน validate ผ่าน gdb

21. พอเรารัน validate โดยใช้คำสั่ง

พบว่า EIP มีค่าเป็น 41414141

22. สร้าง pattern string ด้วย patter_create.rb อีกที

พบว่า EIP เปลี่ยนเป็น 39644138

23. หาตำแหน่งตัวอักษรที่กำหนด EIP โดยใช้ pattern_offset

พบว่าตำแหน่งที่เกิดคือ 116

24. ทดสอบกำหนด EIP ด้วยการใส่ A 116 ตัวแล้วตามด้วย B 4 ตัวปรากฏว่า EIP กลายเป็น 42424242 ตามที่เราต้องการ

25. หาว่าเราจะใส่ shell code ของเราไปไว้ตรงไหนของ Registry

x/s เพื่อแสดงค่าภายใน registry ใดๆ

พบว่า EAX คือตัวที่จะเก็บค่าทุกอย่างที่เราเก็บไว้ ซึ่งจากตรงจุดนี้เราสามารถเขียน shell code ขนาด 116 byte ได้นั่นเอง

พอดูใน ESP พบว่าเป็น C ทั้งหมดที่เราใส่ลงไป

26. ต่อไปคือเราจะทำการกำหนด EIP ไปยังตัว JMP ซึ่งการหาตำแหน่งดังกล่าว เราจำเป็นต้อง download ตัวหาว่าใน execution file มี JMP/CALL ตรงไหนบ้าง นั่นคือ JMPBuster นั่นเอง

หรือจะใช้

ก็ได้เหมือนกันครับ

พบว่ามี call eax มีที่ตำแหน่ง 0x080484af และ 0x0804862b แต่ไม่มี jmp esp เลย นั่นหมายความว่าเราคงไม่มีทางเลือก นอกเหนือจากการใส่ shell code ของเราใน EAX

27. สร้าง payload ที่เป็นการรันภายในเครื่อง

หรือจะทำเป็น

จะได้ payload เป็นดังนี้

28. Run exploit เป็น input ของ validate ก็จะได้ session ของ anansi มา

29. ในเมื่อเราเข้าเป็น anansi ได้แล้ว ต่อมาก็คือการแก้ไขโดยการเอา “/bin/bash” ไปใส่ใน /home/anansi/bin/anansi_util

30. กลับไปใช้งาน puck รัน /home/anansi/bin/anansi_util ด้วย sudo อีกที ก็จะได้สิทธิ์ root มา