init commit
This commit is contained in:
56
lab5/generate_http_data.py
Normal file
56
lab5/generate_http_data.py
Normal file
@@ -0,0 +1,56 @@
|
||||
import csv
|
||||
import random
|
||||
|
||||
random.seed(42)
|
||||
|
||||
MALICIOUS_TEMPLATES = [
|
||||
"<script>alert('xss')</script>",
|
||||
"<img src=x onerror=alert(1)>",
|
||||
"<svg onload=alert(1)>",
|
||||
"javascript:alert(document.cookie)",
|
||||
"<iframe src='javascript:alert(1)'></iframe>",
|
||||
"'; system('rm -rf /')",
|
||||
"$(cat /etc/passwd)",
|
||||
"`whoami`",
|
||||
"<body onload=alert('xss')>",
|
||||
"../../../../etc/passwd",
|
||||
"<a href=\"javascript:void(0)\" onclick=\"alert(1)\">click</a>",
|
||||
"%3Cscript%3Ealert(1)%3C/script%3E",
|
||||
"; ping -c 10 127.0.0.1;",
|
||||
"<input onfocus=alert(1) autofocus>",
|
||||
]
|
||||
|
||||
BENIGN_TEMPLATES = [
|
||||
"search term: red shoes size {n}",
|
||||
"username: alex_{n}",
|
||||
"comment: I really liked this product, arrived in {n} days",
|
||||
"city: Springfield",
|
||||
"message: see you at {n}pm tomorrow",
|
||||
"review title: Great value for {n} dollars",
|
||||
"address line 2: Apt {n}B",
|
||||
"notes: please call before {n}pm",
|
||||
"tag: outdoor, hiking, {n}-season",
|
||||
"bio: software engineer, {n} years experience",
|
||||
]
|
||||
|
||||
|
||||
def fill(template):
|
||||
return template.format(n=random.randint(2, 30))
|
||||
|
||||
|
||||
def generate(n_per_class=250):
|
||||
rows = []
|
||||
for _ in range(n_per_class):
|
||||
rows.append((random.choice(MALICIOUS_TEMPLATES), 1))
|
||||
rows.append((fill(random.choice(BENIGN_TEMPLATES)), 0))
|
||||
random.shuffle(rows)
|
||||
return rows
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
rows = generate(n_per_class=250)
|
||||
with open("data.csv", "w", newline="", encoding="utf-8") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerow(["text", "label"])
|
||||
writer.writerows(rows)
|
||||
print(f"Wrote {len(rows)} rows to data.csv")
|
||||
60
lab5/generate_sql_data.py
Normal file
60
lab5/generate_sql_data.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import csv
|
||||
import random
|
||||
|
||||
random.seed(42)
|
||||
|
||||
SQLI_TEMPLATES = [
|
||||
"' OR '1'='1",
|
||||
"' OR 1=1 --",
|
||||
"admin'--",
|
||||
"' UNION SELECT username, password FROM users--",
|
||||
"1; DROP TABLE users;--",
|
||||
"' AND SLEEP(5)--",
|
||||
"\" OR \"\"=\"",
|
||||
"1' AND '1'='1' UNION SELECT NULL,NULL--",
|
||||
"'; EXEC xp_cmdshell('dir')--",
|
||||
"' OR 'a'='a",
|
||||
"1 OR 1=1",
|
||||
"' OR EXISTS(SELECT * FROM users)--",
|
||||
"%27%20OR%20%271%27%3D%271",
|
||||
"'/**/OR/**/1=1--",
|
||||
]
|
||||
|
||||
BENIGN_TEMPLATES = [
|
||||
"john.doe@example.com",
|
||||
"Jane O'Brien",
|
||||
"New York, NY",
|
||||
"Sunset Boulevard Apt 4B",
|
||||
"search term: winter jackets",
|
||||
"user123",
|
||||
"2024-05-19",
|
||||
"5 stars, would buy again",
|
||||
"quantity: 3",
|
||||
"order #{n}",
|
||||
"product review for {n}",
|
||||
"phone: 555-01{n}",
|
||||
"comment: great service, thanks!",
|
||||
"coupon code SAVE{n}",
|
||||
]
|
||||
|
||||
|
||||
def fill(template):
|
||||
return template.format(n=random.randint(10, 99))
|
||||
|
||||
|
||||
def generate(n_per_class=250):
|
||||
rows = []
|
||||
for _ in range(n_per_class):
|
||||
rows.append((random.choice(SQLI_TEMPLATES), 1))
|
||||
rows.append((fill(random.choice(BENIGN_TEMPLATES)), 0))
|
||||
random.shuffle(rows)
|
||||
return rows
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
rows = generate(n_per_class=250)
|
||||
with open("data.csv", "w", newline="", encoding="utf-8") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerow(["text", "label"])
|
||||
writer.writerows(rows)
|
||||
print(f"Wrote {len(rows)} rows to data.csv")
|
||||
15
lab5/test_sqli.py
Normal file
15
lab5/test_sqli.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import joblib
|
||||
|
||||
vectorizer = joblib.load("sqli_vectorizer.joblib")
|
||||
clf = joblib.load("sqli_classifier.joblib")
|
||||
|
||||
print("Type text to classify. Ctrl+C or empty line to quit.\n")
|
||||
while True:
|
||||
text = input("> ").strip()
|
||||
if not text:
|
||||
break
|
||||
X = vectorizer.transform([text])
|
||||
pred = clf.predict(X)[0]
|
||||
verdict = "MALICIOUS" if pred == 1 else "benign"
|
||||
print(f"[{verdict}] {text}\n")
|
||||
|
||||
15
lab5/test_xss.py
Normal file
15
lab5/test_xss.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import joblib
|
||||
|
||||
vectorizer = joblib.load("xss_vectorizer.joblib")
|
||||
clf = joblib.load("xss_classifier.joblib")
|
||||
|
||||
print("Type text to classify. Ctrl+C or empty line to quit.\n")
|
||||
while True:
|
||||
text = input("> ").strip()
|
||||
if not text:
|
||||
break
|
||||
X = vectorizer.transform([text])
|
||||
pred = clf.predict(X)[0]
|
||||
verdict = "MALICIOUS" if pred == 1 else "benign"
|
||||
print(f"[{verdict}] {text}\n")
|
||||
|
||||
77
lab5/train_http_model.py
Normal file
77
lab5/train_http_model.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import joblib
|
||||
import csv
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
from scipy.sparse import hstack
|
||||
from sklearn.feature_extraction.text import TfidfVectorizer
|
||||
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
|
||||
from sklearn.model_selection import train_test_split
|
||||
from sklearn.svm import LinearSVC
|
||||
|
||||
sys.path.append(str(Path(__file__).resolve().parent.parent))
|
||||
from common.features import handcrafted_feature_matrix # noqa: E402
|
||||
|
||||
XSS_KEYWORDS = [
|
||||
"<script", "onerror", "onload", "javascript:", "onclick", "onfocus",
|
||||
"<iframe", "<svg", "alert(", "system(", "etc/passwd", "cmd", "eval(",
|
||||
]
|
||||
|
||||
|
||||
def load_data(path="data.csv"):
|
||||
texts, labels = [], []
|
||||
with open(path, newline="", encoding="utf-8") as f:
|
||||
for row in csv.DictReader(f):
|
||||
texts.append(row["text"])
|
||||
labels.append(int(row["label"]))
|
||||
return texts, np.array(labels)
|
||||
|
||||
|
||||
def main():
|
||||
texts, labels = load_data()
|
||||
X_train_txt, X_test_txt, y_train, y_test = train_test_split(
|
||||
texts, labels, test_size=0.25, random_state=42, stratify=labels
|
||||
)
|
||||
|
||||
vectorizer = TfidfVectorizer(analyzer="char_wb", ngram_range=(2, 4), max_features=1500)
|
||||
Xtr_tfidf = vectorizer.fit_transform(X_train_txt)
|
||||
Xte_tfidf = vectorizer.transform(X_test_txt)
|
||||
|
||||
Xtr_hand = handcrafted_feature_matrix(X_train_txt, XSS_KEYWORDS)
|
||||
Xte_hand = handcrafted_feature_matrix(X_test_txt, XSS_KEYWORDS)
|
||||
|
||||
X_train = hstack([Xtr_tfidf, Xtr_hand])
|
||||
X_test = hstack([Xte_tfidf, Xte_hand])
|
||||
|
||||
clf = LinearSVC(random_state=42, max_iter=5000)
|
||||
clf.fit(X_train, y_train)
|
||||
y_pred = clf.predict(X_test)
|
||||
|
||||
print("HTTP / XSS Injection Detection")
|
||||
print(f"Accuracy: {accuracy_score(y_test, y_pred):.3f}")
|
||||
print(classification_report(y_test, y_pred, target_names=["benign", "malicious"]))
|
||||
print("Confusion matrix [[TN FP][FN TP]]:")
|
||||
print(confusion_matrix(y_test, y_pred))
|
||||
|
||||
print("\nTest Samples")
|
||||
samples = [
|
||||
"<script>alert(document.cookie)</script>",
|
||||
"search term: comfortable running shoes",
|
||||
"<img src=x onerror=alert(1)>",
|
||||
"notes: please call before 5pm",
|
||||
]
|
||||
Xd_tfidf = vectorizer.transform(samples)
|
||||
Xd_hand = handcrafted_feature_matrix(samples, XSS_KEYWORDS)
|
||||
Xd = hstack([Xd_tfidf, Xd_hand])
|
||||
preds = clf.predict(Xd)
|
||||
for text, label in zip(samples, preds):
|
||||
verdict = "MALICIOUS" if label == 1 else "benign"
|
||||
print(f"[{verdict}] {text}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
joblib.dump(vectorizer, "xss_vectorizer.joblib")
|
||||
joblib.dump(clf, "xss_classifier.joblib")
|
||||
print("\nSaved model artifacts. Run: python test_model.py")
|
||||
main()
|
||||
77
lab5/train_sqli_model.py
Normal file
77
lab5/train_sqli_model.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import joblib
|
||||
import csv
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
from scipy.sparse import hstack
|
||||
from sklearn.ensemble import RandomForestClassifier
|
||||
from sklearn.feature_extraction.text import TfidfVectorizer
|
||||
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
|
||||
from sklearn.model_selection import train_test_split
|
||||
|
||||
sys.path.append(str(Path(__file__).resolve().parent.parent))
|
||||
from common.features import handcrafted_feature_matrix # noqa: E402
|
||||
|
||||
SQL_KEYWORDS = [
|
||||
"select", "union", "drop", "insert", "update", "delete", "or 1=1",
|
||||
"sleep(", "xp_cmdshell", "--", "exec ", "'or'", "1=1",
|
||||
]
|
||||
|
||||
|
||||
def load_data(path="data.csv"):
|
||||
texts, labels = [], []
|
||||
with open(path, newline="", encoding="utf-8") as f:
|
||||
for row in csv.DictReader(f):
|
||||
texts.append(row["text"])
|
||||
labels.append(int(row["label"]))
|
||||
return texts, np.array(labels)
|
||||
|
||||
|
||||
def main():
|
||||
texts, labels = load_data()
|
||||
X_train_txt, X_test_txt, y_train, y_test = train_test_split(
|
||||
texts, labels, test_size=0.25, random_state=42, stratify=labels
|
||||
)
|
||||
|
||||
vectorizer = TfidfVectorizer(analyzer="char_wb", ngram_range=(2, 4), max_features=1500)
|
||||
Xtr_tfidf = vectorizer.fit_transform(X_train_txt)
|
||||
Xte_tfidf = vectorizer.transform(X_test_txt)
|
||||
|
||||
Xtr_hand = handcrafted_feature_matrix(X_train_txt, SQL_KEYWORDS)
|
||||
Xte_hand = handcrafted_feature_matrix(X_test_txt, SQL_KEYWORDS)
|
||||
|
||||
X_train = hstack([Xtr_tfidf, Xtr_hand])
|
||||
X_test = hstack([Xte_tfidf, Xte_hand])
|
||||
|
||||
clf = RandomForestClassifier(n_estimators=200, random_state=42)
|
||||
clf.fit(X_train, y_train)
|
||||
y_pred = clf.predict(X_test)
|
||||
|
||||
print("SQL Injection Detection")
|
||||
print(f"Accuracy: {accuracy_score(y_test, y_pred):.3f}")
|
||||
print(classification_report(y_test, y_pred, target_names=["benign", "malicious"]))
|
||||
print("Confusion matrix [[TN FP][FN TP]]:")
|
||||
print(confusion_matrix(y_test, y_pred))
|
||||
|
||||
print("\nTest Samples")
|
||||
samples = [
|
||||
"' OR '1'='1' --",
|
||||
"jane.doe@example.com",
|
||||
"1; DROP TABLE orders;--",
|
||||
"search: blue running shoes size 10",
|
||||
]
|
||||
Xd_tfidf = vectorizer.transform(samples)
|
||||
Xd_hand = handcrafted_feature_matrix(samples, SQL_KEYWORDS)
|
||||
Xd = hstack([Xd_tfidf, Xd_hand])
|
||||
preds = clf.predict(Xd)
|
||||
for text, label in zip(samples, preds):
|
||||
verdict = "MALICIOUS" if label == 1 else "benign"
|
||||
print(f"[{verdict}] {text}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
joblib.dump(vectorizer, "sqli_vectorizer.joblib")
|
||||
joblib.dump(clf, "sqli_classifier.joblib")
|
||||
print("\nSaved model artifacts. Run: python test_model.py")
|
||||
main()
|
||||
Reference in New Issue
Block a user