added material
This commit is contained in:
@@ -0,0 +1,324 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "71d433a3-8db5-455c-b518-c8c91e5b18e2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import json\n",
|
||||
"import requests\n",
|
||||
"from sklearn.linear_model import LogisticRegression\n",
|
||||
"import os\n",
|
||||
"\n",
|
||||
"# Replace <EVALUATOR_IP> and <PORT> with the correct values\n",
|
||||
"evaluator_base_url = \"http://154.57.164.81:30900\"\n",
|
||||
"# Example: evaluator_base_url = \"http://127.0.0.1:5000\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "7049870b-0c71-49ca-9baf-6b2cef2994f0",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Data loaded successfully from single .npz file.\n",
|
||||
"X_train shape: (700, 2)\n",
|
||||
"y_train shape: (700,)\n",
|
||||
"X_test shape: (300, 2)\n",
|
||||
"y_test shape: (300,)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"dataset_filename = \"label_flipping_dataset.npz\"\n",
|
||||
"\n",
|
||||
"try:\n",
|
||||
" data = np.load(dataset_filename)\n",
|
||||
" X_train = data[\"Xtr\"]\n",
|
||||
" y_train = data[\"ytr\"]\n",
|
||||
" X_test = data[\"Xte\"]\n",
|
||||
" y_test = data[\"yte\"]\n",
|
||||
" print(\"Data loaded successfully from single .npz file.\")\n",
|
||||
" print(f\"X_train shape: {X_train.shape}\")\n",
|
||||
" print(f\"y_train shape: {y_train.shape}\")\n",
|
||||
" print(f\"X_test shape: {X_test.shape}\")\n",
|
||||
" print(f\"y_test shape: {y_test.shape}\")\n",
|
||||
" data.close()\n",
|
||||
"except FileNotFoundError:\n",
|
||||
" print(f\"Error: Dataset file '{dataset_filename}' not found.\")\n",
|
||||
" print(\"Make sure the .npz data file is in the correct directory.\")\n",
|
||||
" raise\n",
|
||||
"except KeyError as e:\n",
|
||||
" print(f\"Error: Could not find expected array key '{e}' in the .npz file.\")\n",
|
||||
" raise"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "ab16fc6b-f5bb-4090-aba4-d0fafba2329d",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Flipping 420 labels (60.0%).\n",
|
||||
"Shape of poisoned labels: (700,)\n",
|
||||
"Number of labels flipped: 420\n",
|
||||
"Original labels at flipped indices (first 5): [1 1 0 1 1]\n",
|
||||
"Poisoned labels at flipped indices (first 5): [0 0 1 0 0]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Implement your attack code in this stub\n",
|
||||
"def flip_labels(y, poison_percentage, seed):\n",
|
||||
" if not 0 <= poison_percentage <= 1:\n",
|
||||
" raise ValueError(\"poison_percentage must be between 0 and 1.\")\n",
|
||||
"\n",
|
||||
" n_samples = len(y)\n",
|
||||
" n_to_flip = int(n_samples * poison_percentage)\n",
|
||||
"\n",
|
||||
" if n_to_flip == 0:\n",
|
||||
" print(\"Warning: Poison percentage is 0 or too low to flip any labels.\")\n",
|
||||
" # Return unchanged labels and empty indices if no flips are needed\n",
|
||||
" return y.copy(), np.array([], dtype=int)\n",
|
||||
"\n",
|
||||
" # Use the defined SEED for the random number generator\n",
|
||||
" rng_instance = np.random.default_rng(seed)\n",
|
||||
" # Select unique indices to flip\n",
|
||||
" flipped_indices = rng_instance.choice(n_samples, size=n_to_flip, replace=False)\n",
|
||||
" \n",
|
||||
" # Create a copy to avoid modifying the original array\n",
|
||||
" y_poisoned = y.copy()\n",
|
||||
"\n",
|
||||
" # Get the original labels at the indices we are about to flip\n",
|
||||
" original_labels_at_flipped = y_poisoned[flipped_indices]\n",
|
||||
"\n",
|
||||
" # Apply the flip: if original was 0, set to 1; otherwise (if 1), set to 0\n",
|
||||
" y_poisoned[flipped_indices] = np.where(original_labels_at_flipped == 0, 1, 0)\n",
|
||||
"\n",
|
||||
" print(f\"Flipping {n_to_flip} labels ({poison_percentage * 100:.1f}%).\")\n",
|
||||
"\n",
|
||||
" return y_poisoned, flipped_indices\n",
|
||||
"# ------------------------------------------------------------------------\n",
|
||||
"# --- The rest is templated and you should not need to change anything ---\n",
|
||||
"# ------------------------------------------------------------------------\n",
|
||||
"poison_rate = 0.60\n",
|
||||
"random_seed = 1337\n",
|
||||
"y_train_poisoned, flipped_idx = flip_labels(y_train, poison_rate, random_seed)\n",
|
||||
"\n",
|
||||
"print(f\"Shape of poisoned labels: {y_train_poisoned.shape}\")\n",
|
||||
"print(f\"Number of labels flipped: {len(flipped_idx)}\")\n",
|
||||
"print(f\"Original labels at flipped indices (first 5): {y_train[flipped_idx[:5]]}\")\n",
|
||||
"print(\n",
|
||||
" f\"Poisoned labels at flipped indices (first 5): {y_train_poisoned[flipped_idx[:5]]}\"\n",
|
||||
")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "95fabebd-46b6-46d8-8cd3-b1dc69c87545",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Model trained successfully on poisoned data.\n",
|
||||
"Extracted weights (shape): (1, 2)\n",
|
||||
"Extracted intercept (shape): (1,)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"model = LogisticRegression(random_state=random_seed)\n",
|
||||
"model.fit(X_train, y_train_poisoned)\n",
|
||||
"print(\"Model trained successfully on poisoned data.\")\n",
|
||||
"weights = model.coef_\n",
|
||||
"intercept = model.intercept_\n",
|
||||
"print(f\"Extracted weights (shape): {weights.shape}\")\n",
|
||||
"print(f\"Extracted intercept (shape): {intercept.shape}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "176d29b4-3afe-4397-87d8-7d1d7fc1b9ad",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Checking evaluator health at: http://154.57.164.81:30900/health\n",
|
||||
"\n",
|
||||
"--- Health Check Response ---\n",
|
||||
"Status: healthy\n",
|
||||
"Message: Evaluator API running.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"health_check_url = f\"{evaluator_base_url}/health\"\n",
|
||||
"print(f\"Checking evaluator health at: {health_check_url}\")\n",
|
||||
"if \"<EVALUATOR_IP>\" in evaluator_base_url:\n",
|
||||
" print(\"\\n--- WARNING ---\")\n",
|
||||
" print(\n",
|
||||
" \"Please update the 'evaluator_base_url' variable with the correct IP and Port before running!\"\n",
|
||||
" )\n",
|
||||
" print(\"-------------\")\n",
|
||||
"else:\n",
|
||||
" try:\n",
|
||||
" response = requests.get(health_check_url, timeout=10)\n",
|
||||
" response.raise_for_status()\n",
|
||||
" health_status = response.json()\n",
|
||||
" print(\"\\n--- Health Check Response ---\")\n",
|
||||
" print(f\"Status: {health_status.get('status', 'N/A')}\")\n",
|
||||
" print(f\"Message: {health_status.get('message', 'No message received.')}\")\n",
|
||||
" if health_status.get(\"status\") != \"healthy\":\n",
|
||||
" print(\n",
|
||||
" \"\\nWarning: Evaluator service reported an unhealthy status. It might still be starting up or encountered an issue (like loading data).\"\n",
|
||||
" )\n",
|
||||
" except requests.exceptions.ConnectionError as e:\n",
|
||||
" print(f\"\\nConnection Error: Could not connect to {health_check_url}.\")\n",
|
||||
" print(\"Please check:\")\n",
|
||||
" print(\" 1. The evaluator URL (IP address and port) is correct.\")\n",
|
||||
" print(\" 2. The evaluator Docker container is running.\")\n",
|
||||
" print(\n",
|
||||
" \" 3. There are no network issues (firewalls, etc.) blocking the connection.\"\n",
|
||||
" )\n",
|
||||
" except requests.exceptions.Timeout:\n",
|
||||
" print(f\"\\nTimeout Error: The request to {health_check_url} timed out.\")\n",
|
||||
" print(\n",
|
||||
" \"The server might be taking too long to respond or there could be network issues.\"\n",
|
||||
" )\n",
|
||||
" except requests.exceptions.RequestException as e:\n",
|
||||
" print(f\"\\nError during health check request: {e}\")\n",
|
||||
" print(\"Check the URL format and ensure the server is running.\")\n",
|
||||
" except json.JSONDecodeError:\n",
|
||||
" print(\"\\nError: Could not decode JSON response from health check.\")\n",
|
||||
" print(\"The server might have sent an invalid response.\")\n",
|
||||
" print(\n",
|
||||
" f\"Raw response status: {response.status_code}, Raw response text: {response.text}\"\n",
|
||||
" )\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"\\nAn unexpected error occurred during health check: {e}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "1d792cad-56e0-413b-8e1e-08d9e0ac1468",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Attempting submission to: http://154.57.164.81:30900/evaluate\n",
|
||||
"Payload: {\"weights\": [[-0.12683149742377367, 0.02548467051700444]], \"intercept\": [0.29202685494234054]}\n",
|
||||
"\n",
|
||||
"--- Evaluator Response ---\n",
|
||||
"Attack Successful!\n",
|
||||
"Accuracy evaluated by server: 0.0033\n",
|
||||
"Flag: HTB{l4b3l_fl1pp1ng_pwnz_d3f4ult}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"evaluator_url = f\"{evaluator_base_url}/evaluate\"\n",
|
||||
"payload = {\"weights\": weights.tolist(), \"intercept\": intercept.tolist()}\n",
|
||||
"print(f\"Attempting submission to: {evaluator_url}\")\n",
|
||||
"if \"<EVALUATOR_IP>\" in evaluator_base_url:\n",
|
||||
" print(\"\\n--- WARNING ---\")\n",
|
||||
" print(\n",
|
||||
" \"Please update the 'evaluator_base_url' variable with the correct IP address and Port before running this cell!\"\n",
|
||||
" )\n",
|
||||
" print(\"-------------\")\n",
|
||||
"else:\n",
|
||||
" print(f\"Payload: {json.dumps(payload)}\")\n",
|
||||
" try:\n",
|
||||
" response = requests.post(evaluator_url, json=payload, timeout=30)\n",
|
||||
" response.raise_for_status()\n",
|
||||
" result = response.json()\n",
|
||||
" print(\"\\n--- Evaluator Response ---\")\n",
|
||||
" if result.get(\"success\"):\n",
|
||||
" print(\"Attack Successful!\")\n",
|
||||
" print(f\"Accuracy evaluated by server: {result.get('accuracy'):.4f}\")\n",
|
||||
" print(f\"Flag: {result.get('flag')}\")\n",
|
||||
" else:\n",
|
||||
" print(\"Evaluation Failed.\")\n",
|
||||
" accuracy_val = result.get(\"accuracy\")\n",
|
||||
" accuracy_str = f\"{accuracy_val:.4f}\" if accuracy_val is not None else \"N/A\"\n",
|
||||
" print(f\"Accuracy evaluated by server: {accuracy_str}\")\n",
|
||||
" print(f\"Message: {result.get('message')}\")\n",
|
||||
" print(\n",
|
||||
" \"Hints: Did you poison exactly 60% of the data? Did you use the seed 1337 for flipping labels?\"\n",
|
||||
" )\n",
|
||||
" except requests.exceptions.ConnectionError as e:\n",
|
||||
" print(\n",
|
||||
" f\"\\nConnection Error: Could not connect to the evaluator API at {evaluator_url}.\"\n",
|
||||
" )\n",
|
||||
" print(\"Please check:\")\n",
|
||||
" print(\" 1. The evaluator URL (IP address and port) is correct.\")\n",
|
||||
" print(\" 2. The evaluator Docker instance is spawned.\")\n",
|
||||
" print(\n",
|
||||
" \" 3. There are no network issues (firewalls, etc.) blocking the connection.\"\n",
|
||||
" )\n",
|
||||
" except requests.exceptions.Timeout:\n",
|
||||
" print(f\"\\nTimeout Error: The request to {evaluator_url} timed out.\")\n",
|
||||
" print(\"The server might be slow, or there could be network issues.\")\n",
|
||||
" except requests.exceptions.RequestException as e:\n",
|
||||
" print(f\"\\nError connecting to evaluator API: {e}\")\n",
|
||||
" print(\"Please check the evaluator URL and ensure the instance is spawned.\")\n",
|
||||
" except json.JSONDecodeError:\n",
|
||||
" print(\"\\nError decoding JSON response from the evaluator.\")\n",
|
||||
" print(\"The server might have sent an invalid response.\")\n",
|
||||
" print(\n",
|
||||
" f\"Raw response status: {response.status_code}, Raw response text: {response.text}\"\n",
|
||||
" )\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"\\nAn unexpected error occurred: {e}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4aabb361-8bbe-409d-888f-acab35ee3d97",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
Reference in New Issue
Block a user