Refactored code now working

This commit is contained in:
nik012003
2022-07-12 23:14:32 +02:00
parent 1e94c26fd6
commit e331a31530
9 changed files with 39 additions and 86 deletions

View File

@@ -3,7 +3,7 @@ docker-compose.yml
**/*.pyc
**/__pycache__/
/.vscode/
**/.vscode/**
#Node filters

2
.gitignore vendored
View File

@@ -1,6 +1,6 @@
**/*.pyc
**/__pycache__/
/.vscode/**
**/.vscode/**
/.mypy_cache/**
**/node_modules

View File

@@ -1,5 +0,0 @@
{
"python.linting.pylintEnabled": false,
"python.linting.mypyEnabled": true,
"python.linting.enabled": true
}

View File

@@ -71,7 +71,7 @@ class FiregexTables(IPTables):
def add_output(self, queue_range, proto = None, port = None, ip_int = None):
init, end = queue_range
if init > end: init, end = end, init
self.append_rule(FilterTypes.OUTPUT,"NFQUEUE"
self.append_rule(FilterTypes.OUTPUT,"NFQUEUE",
* (["-p", str(proto)] if proto else []),
* (["-s", str(ip_int)] if ip_int else []),
* (["--sport", str(port)] if port else []),
@@ -92,8 +92,9 @@ class FiregexTables(IPTables):
def get(self) -> List[FiregexFilter]:
res = []
iptables_filters = self.list()
for filter_type in [FilterTypes.INPUT, FilterTypes.OUTPUT]:
for filter in self.list()[filter_type]:
for filter in iptables_filters[filter_type]:
port = filter.sport() if filter_type == FilterTypes.OUTPUT else filter.dport()
queue = filter.nfqueue()
if queue and port:
@@ -133,13 +134,13 @@ class FiregexInterceptor:
def func_wrap(ll_data, ll_proto_id, data, ctx, *args):
pkt_parsed = ip6.IP6(data) if self.ipv6 else ip.IP(data)
try:
data = None
pkt_data = None
if not pkt_parsed[tcp.TCP] is None:
data = pkt_parsed[tcp.TCP].body_bytes
if not pkt_parsed[tcp.TCP] is None:
data = pkt_parsed[udp.UDP].body_bytes
if data:
if func(data):
pkt_data = pkt_parsed[tcp.TCP].body_bytes
elif not pkt_parsed[udp.UDP] is None:
pkt_data = pkt_parsed[udp.UDP].body_bytes
if pkt_data:
if func(pkt_data):
return data, interceptor.NF_ACCEPT
elif pkt_parsed[tcp.TCP]:
pkt_parsed[tcp.TCP].flags &= 0x00

View File

@@ -45,7 +45,7 @@ class FirewallManager:
continue
self.proxy_table[srv.id] = ServiceManager(srv, self.db)
await self.proxy_table[srv.id].next(srv["status"])
await self.proxy_table[srv.id].next(srv.status)
async def _stats_updater(self, callback):
try:
@@ -111,7 +111,7 @@ class ServiceManager:
def __init__(self, srv: Service, db):
self.srv = srv
self.db = db
self.iptables = FiregexTables(self.srv.ipv6)
self.firegextable = FiregexTables(self.srv.ipv6)
self.status = STATUS.STOP
self.filters: Dict[int, FiregexFilter] = {}
self._update_filters_from_db()
@@ -137,22 +137,19 @@ class ServiceManager:
for f in new_filters:
if not f in old_filters:
filter = [ele for ele in regexes if ele.id == f][0]
self.filters[f] = FiregexFilter.from_regex(filter)
self.filters[f] = RegexFilter.from_regex(filter)
def __update_status_db(self, status):
self.db.query("UPDATE services SET status = ? WHERE service_id = ?;", status, self.srv["service_id"])
self.db.query("UPDATE services SET status = ? WHERE service_id = ?;", status, self.srv.id)
async def next(self,to):
async with self.lock:
return self._next(to)
def _next(self, to):
if (self.status, to) == (STATUS.ACTIVE, STATUS.STOP):
self.proxy.stop()
self._set_status(to)
# PAUSE -> ACTIVE
elif (self.status, to) == (STATUS.STOP, STATUS.ACTIVE):
self.proxy.restart()
if (self.status, to) == (STATUS.ACTIVE, STATUS.STOP):
self.stop()
self._set_status(to)
# PAUSE -> ACTIVE
elif (self.status, to) == (STATUS.STOP, STATUS.ACTIVE):
self.restart()
def _stats_updater(self,filter:RegexFilter):
self.db.query("UPDATE regexes SET blocked_packets = ? WHERE regex_id = ?;", filter.blocked, filter.id)
@@ -167,7 +164,7 @@ class ServiceManager:
def start(self):
if not self.interceptor:
self.iptables.delete_by_srv(self.srv)
self.firegextable.delete_by_srv(self.srv)
def regex_filter(pkt, by_client):
try:
for filter in self.filters.values():
@@ -178,11 +175,11 @@ class ServiceManager:
return False
except IndexError: pass
return True
self.interceptor = self.iptables.add(self.srv["proto"], self.srv["port"], self.srv["ip_int"], regex_filter)
self.interceptor = self.firegextable.add(FiregexFilter(self.srv.proto,self.srv.port, self.srv.ip_int, func=regex_filter))
self._set_status(STATUS.ACTIVE)
def stop(self):
self.iptables.delete_by_srv(self.srv)
self.firegextable.delete_by_srv(self.srv)
if self.interceptor:
self.interceptor.stop()
self.interceptor = None

View File

@@ -12,6 +12,9 @@ class Rule():
self.destination = destination
self.details = details
def __repr__(self) -> str:
return f"Rule {self.id} : {self.target}, {self.prot}, {self.opt}, {self.source}, {self.destination}, {self.details}"
def dport(self) -> Union[int, None]:
port = re.findall(r"dpt:([0-9]+)", self.details)
return int(port[0]) if port else None
@@ -49,7 +52,7 @@ class IPTables:
if line.startswith("Chain"):
chain_name = line.split()[1]
res[chain_name] = []
elif line.split()[0].isnumeric():
elif line and line.split()[0].isnumeric():
parsed = re.findall(r"([^ ]*)[ ]{,10}([^ ]*)[ ]{,5}([^ ]*)[ ]{,5}([^ ]*)[ ]{,5}([^ ]*)[ ]+([^ ]*)[ ]+(.*)", line)
if len(parsed) > 0:
parsed = parsed[0]
@@ -60,7 +63,7 @@ class IPTables:
opt=parsed[3].strip(),
source=parsed[4].strip(),
destination=parsed[5].strip(),
details=" ".join(parsed[6:]).strip() if len(parsed[0]) >= 7 else ""
details=" ".join(parsed[6:]).strip() if len(parsed) >= 7 else ""
))
return res

View File

@@ -1,6 +1,7 @@
from typing import Union
import json, sqlite3, os
from hashlib import md5
import base64
class SQLite():
def __init__(self, db_name: str) -> None:
@@ -116,7 +117,7 @@ class Service:
class Regex:
def __init__(self, id: int, regex: str, mode: str, service_id: str, is_blacklist: bool, blocked_packets: int, is_case_sensitive: bool, active: bool):
self.regex = regex
self.regex = base64.b64decode(regex)
self.mode = mode
self.service_id = service_id
self.is_blacklist = is_blacklist

View File

@@ -75,10 +75,6 @@ class FiregexAPI:
req = self.s.get(f"{self.address}api/service/{service_id}/start")
return req.json()["status"] == "ok"
def pause(self,service_id):
req = self.s.get(f"{self.address}api/service/{service_id}/pause")
return req.json()["status"] == "ok"
def stop(self,service_id):
req = self.s.get(f"{self.address}api/service/{service_id}/stop")
return req.json()["status"] == "ok"

View File

@@ -58,11 +58,11 @@ else: puts(f"Test Failed: Couldn't create service ✗", color=colors.red); exit(
#Delete the Service and exit
def exit_test(status_code=0):
#if service_created:
# if(firegex.delete(service)):
# puts(f"Sucessfully delete service with id {service} ✔", color=colors.green)
# else:
# puts(f"Test Failed: Couldn't delete service ✗", color=colors.red); exit(1)
if service_created:
if(firegex.delete(service)):
puts(f"Sucessfully delete service with id {service}", color=colors.green)
else:
puts(f"Test Failed: Couldn't delete service ✗", color=colors.red); exit(1)
sep()
server.terminate()
exit(status_code)
@@ -120,6 +120,7 @@ def checkRegex(regex):
if not sendCheckData(secrets.token_bytes(200) + secret + secrets.token_bytes(200)):
puts(f"The malicious request was successfully blocked ✔", color=colors.green)
n_blocked += 1
sleep(10)
if firegex.get_regex(r["id"])["n_packets"] == n_blocked:
puts(f"The packed was reported as blocked ✔", color=colors.green)
else:
@@ -132,7 +133,7 @@ def checkRegex(regex):
checkRegex(regex)
#Pause the proxy
if(firegex.pause(service)): puts(f"Sucessfully paused service with id {service}", color=colors.green)
if(firegex.stop(service)): puts(f"Sucessfully paused service with id {service}", color=colors.green)
else: puts(f"Test Failed: Coulnd't pause the service ✗", color=colors.red); exit_test(1)
#Check if it's actually paused
@@ -140,49 +141,8 @@ if sendCheckData(secrets.token_bytes(200) + secret + secrets.token_bytes(200)):
puts(f"The request wasn't blocked ✔", color=colors.green)
else:
puts(f"Test Failed: The request was blocked when it shouldn't have", color=colors.red)
#Stop the proxy
if(firegex.stop(service)): puts(f"Sucessfully stopped service with id {service}", color=colors.green)
else: puts(f"Test Failed: Coulnd't stop the service ✗", color=colors.red); exit_test(1)
#Check if proxy is stopped and check if WAIT works
def bindForSeconds(port,delay=4):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1', port))
sock.listen()
puts(f"The test could bind to port {port}", color=colors.green)
sleep(delay)
sock.close()
except Exception as e:
puts(f"The test couldn't bind to port {port}", color=colors.red)
bindingTest = Process(target=bindForSeconds, args=[args.service_port])
bindingTest.start()
sleep(1)
#Restart it
if(firegex.pause(service)): puts(f"Sucessfully started in pause mode ✔", color=colors.green)
else: puts(f"Test Failed: Coulnd't start the service ✗", color=colors.red); exit_test(1)
if firegex.get_service(service)["status"] == "wait":
puts(f"Service started in WAIT mode ✔", color=colors.green)
else:
puts(f"Service started but it's not WAIT mode ✗", color=colors.red); exit_test(1)
bindingTest.join()
sleep(1)
#Check if service started in pause mode successfully
if firegex.get_service(service)["status"] == "pause":
puts(f"Service started in PAUSE mode ✔", color=colors.green)
else:
puts(f"Service is not in PAUSE mode ✗", color=colors.red); exit_test(1)
if sendCheckData(secrets.token_bytes(200) + secret + secrets.token_bytes(200)):
puts(f"The request wasn't blocked ✔", color=colors.green)
else:
puts(f"Test Failed: The request was blocked when it shouldn't have", color=colors.red)
#Restart it and check
#Start firewall
if(firegex.start(service)): puts(f"Sucessfully started service with id {service}", color=colors.green)
else: puts(f"Test Failed: Coulnd't start the service ✗", color=colors.red); exit_test(1)