-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwaf.py
118 lines (99 loc) · 2.85 KB
/
waf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
from datetime import datetime
from threading import Thread
from config import *
from parse import Request
from detect import Detect
from log import log_block
def filter(r, addr):
"""检测web攻击,返回检测结果"""
# uri黑白名单检测
uri = r.uri.split('?')[0]
if WHITE_URI_SWITCH:
if uri not in WHITE_URI_LIST:
return {"status": True, "type": 'not-white-uri'}
if uri in BLACK_URI_LIST and not WHITE_URI_SWITCH:
return {"status": True, "type": 'in-black-uri'}
# 规则匹配
det_data = Detect(r)
result = det_data.run()
# ip白名单允许连接
if result["status"] and WHITE_IP_SWITCH:
if addr[0] in WHITE_IP_LIST:
return {"status": False}
# result = {"status": False}
# print("result: ", result)
return result
def connecting(conn, addr):
"""使用反向代理模式提供waf功能,阻止web攻击"""
# 阻挡ip黑名单连接
if addr[0] in BLACK_IP_LIST:
conn.close()
print("Blocked in black")
return
# 接受客户端请求内容
req = b''
while True:
buf = conn.recv(2048)
req += buf
if len(buf) < 2048:
break
if not req:
conn.close()
return
# 解析http请求,拦截攻击,记录拦截行为
try:
r = Request(req)
except Exception as e:
conn.close()
print(e)
return
result = filter(r, addr)
log_block(addr, result)
if result["status"]:
conn.close()
return
# 向web服务器转发请求,将web服务器返回内容送回客户端
req = req.replace(WAF_IP.encode("utf-8"), ('{}:{}'.format(WEB_IP, WEB_PORT)).encode("utf-8")) \
.replace('keep-alive'.encode("utf-8"), 'close'.encode("utf-8")) \
.replace('gzip'.encode("utf-8"), b'')
#print(req)
s1 = socket.socket()
try:
s1.connect((WEB_IP, WEB_PORT))
s1.sendall(req)
except Exception as e:
print(e)
s1.close()
conn.close()
return
resp = b''
while True:
try:
buf = s1.recv(2048)
except socket.timeout as e:
print("err ", e)
break
if not buf: # or buf.startswith('WebSocket') and buf.endswith('\r\n\r\n'):
break
resp += buf
s1.close()
resp = resp.replace(bytes(WEB_IP, encoding='utf-8'), bytes(WAF_IP, encoding='utf-8'))
conn.send(resp)
conn.close()
def run():
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 80))
s.listen(5)
try:
while 1:
conn, addr = s.accept()
t = Thread(target=connecting, args=(conn, addr))
t.start()
finally:
s.close()
if __name__ == '__main__':
run()