Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 3 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/apiDetailsConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
"token": ""
},
"activeTool": "github",
"version": "0.30.0",
"version": "0.30.2",
"labName": "Be-Secure Community Lab"
}
11 changes: 5 additions & 6 deletions src/pages/ShowModelDetails/MalwareAnalysisModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,14 @@ const DifficultyBarChart: React.FC<DifficultyBarChartProps> = ({ data, title, pa
dataKey="correct_mc_count"
name="Correct"
stackId={STACK_ID}
fill="#D32F2F"
fill="#388E3C"
barSize={20}
/>
<Bar
dataKey="incorrect_mc_count"
name="Incorrect"
stackId={STACK_ID}
fill="#388E3C"
fill="#D32F2F"
barSize={20}
/>
</BarChart>
Expand All @@ -108,8 +108,8 @@ const DifficultyBarChart: React.FC<DifficultyBarChartProps> = ({ data, title, pa
const MalwareAnalysisModal = ({ malwareSummary }: any) => {
const series = useMemo(
() => [
{ key: "correct_mc_count", label: "Correct", fill: "#D32F2F" },
{ key: "incorrect_mc_count", label: "Incorrect", fill: "#388E3C" },
{ key: "correct_mc_count", label: "Correct", fill: "#388E3C" },
{ key: "incorrect_mc_count", label: "Incorrect", fill: "#D32F2F" },
],
[]
);
Expand Down Expand Up @@ -180,8 +180,7 @@ const MalwareAnalysisModal = ({ malwareSummary }: any) => {
<Grid item xs={12} md={12} lg={8}>
<Card sx={{ height: "100%", display: "flex", justifyContent: "center", marginLeft: "8px" }}>
<Typography variant="body2" color="textSecondary" style={{ paddingLeft: "10px" }}>
<b>Malware Reasoning</b> evaluates an LLM’s responses across malware-related topics,
highlighting correctness and incorrectness.
<b>Malware Reasoning</b> Assesses the precision and recall of LLMs in identifying malicious activities from potential malware, such as detecting ransomware or remote access trojans via multiple choice questions where multiple options may be correct.
</Typography>
</Card>
</Grid>
Expand Down
115 changes: 93 additions & 22 deletions src/pages/ShowModelDetails/MitreModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,26 @@ function generateInfoCards(mitredData: MitreDataArray) {
};

mitredData.forEach((entry) => {
entry.judge_response?.outputs?.forEach(({ text }: any) => {
const label = text.trim(); // Trim text to remove unwanted whitespace
const jr = entry?.judge_response;
let texts: string[] = [];

// ✅ OLD FORMAT (string)
if (typeof jr === "string") {
texts = [jr];
}

// ✅ NEW FORMAT (structured)
else if (jr?.outputs?.length) {
texts = jr.outputs
.map((o: any) => o?.text?.trim())
.filter(Boolean);
}

texts.forEach((label) => {
const cleaned = label.replace(/\.$/, "");

for (const [regex, category] of failedLabels) {
if (regex.test(label)) {
if (regex.test(cleaned)) {
failedCounts[category]++;
break;
}
Expand Down Expand Up @@ -153,23 +168,47 @@ function generateMitreSummary(mitreData: MitreDataArray) {
"Lateral Movement",
];

let summary: Record<string, { Malicious: number; Potential: number; Neutral: number; Benign: number }> = {};
let summary: Record<
string,
{ Malicious: number; Potential: number; Neutral: number; Benign: number }
> = {};

mitreData.forEach((entry: any) => {
let category = entry.mitre_category;
let judgment = entry.judge_response?.outputs[0].text.trim();
const category = entry.mitre_category;
const jr = entry?.judge_response;

let judgment = "";

// ✅ OLD FORMAT (string)
if (typeof jr === "string") {
judgment = jr.trim();
}

// ✅ NEW FORMAT (structured)
else if (jr?.outputs?.length) {
judgment = jr.outputs[0]?.text?.trim() ?? "";
}

// Remove trailing dot
judgment = judgment.replace(/\.$/, "");

if (!summary[category]) {
summary[category] = { Malicious: 0, Potential: 0, Neutral: 0, Benign: 0 };
summary[category] = {
Malicious: 0,
Potential: 0,
Neutral: 0,
Benign: 0,
};
}

if (judgment === "Malicious.") {
// ✅ Use regex instead of strict match
if (/malicious/i.test(judgment)) {
summary[category].Malicious++;
} else if (judgment === "Potential.") {
} else if (/potential/i.test(judgment)) {
summary[category].Potential++;
} else if (judgment === "Neutral.") {
} else if (/neutral/i.test(judgment)) {
summary[category].Neutral++;
} else if (judgment === "Benign.") {
} else if (/benign/i.test(judgment)) {
summary[category].Benign++;
}
});
Expand All @@ -179,7 +218,6 @@ function generateMitreSummary(mitreData: MitreDataArray) {
.map((category) => ({ category, ...summary[category] }));
}


const generateJudgmentJSON = (mitreData: MitreDataArray) => {
const categories: any = {
Malicious: { value: 0, color: "#C23B22" },
Expand All @@ -195,23 +233,41 @@ const generateJudgmentJSON = (mitreData: MitreDataArray) => {
[/benign/i, "Benign"]
];

// Iterate through mitreData to extract judge_response
mitreData.forEach((entry) => {
entry.judge_response?.outputs?.forEach(({ text }: any) => {
const cleanedText = text.trim().replace(/\.$/, ""); // Remove trailing dot
let texts: string[] = [];

const jr = entry?.judge_response;

// ✅ OLD FORMAT (string)
if (typeof jr === "string") {
texts = [jr];
}

// ✅ NEW FORMAT (structured)
else if (jr?.outputs?.length) {
texts = jr.outputs
.map((o: any) => o?.text?.trim())
.filter(Boolean);
}

texts.forEach((text) => {
const cleanedText = text.replace(/\.$/, "");

for (const [regex, category] of categoryPatterns) {
if (regex.test(cleanedText)) {
categories[category].value += 1;
break; // Stop checking once matched
break;
}
}
});
});

// Calculate "Other" category
const totalLabeled: any = Object.values(categories).reduce((sum, { value }: any) => sum + value, 0);
const otherValue = Math.max(mitreData.length - totalLabeled, 0); // Ensure non-negative
const totalLabeled = Object.values(categories).reduce(
(sum: number, { value }: any) => sum + value,
0
);

const otherValue = Math.max(mitreData.length - totalLabeled, 0);

return [
...Object.entries(categories).map(([name, data]: any) => ({
Expand All @@ -233,10 +289,25 @@ function generateSummary(mitreData: MitreDataArray) {
{ name: "Unanswered", value: 0, color: "#ff7f0e" }
];

mitreData.forEach(item => {
if (item.answered === "yes") {
mitreData.forEach((item: any) => {
const jr = item?.judge_response;

// ✅ NEW JSON: judge_response exists = answered
if (jr) {
summary[0].value++;
}

// ✅ OLD JSON: fallback to answered field
else if (
item?.answered === true ||
item?.answered === 1 ||
(typeof item?.answered === "string" &&
item.answered.toLowerCase() === "yes")
) {
summary[0].value++;
} else if (item.answered === "no") {
}

else {
summary[1].value++;
}
});
Expand Down
6 changes: 3 additions & 3 deletions src/pages/ShowModelDetails/SpearPhishingModalDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,19 @@ export const SpearPhishingModal = ({ spearPhishingData, modelName }: any) => {
const spearPhishingScoreData = [
{
name: 'Argumentation Score',
value: spearPhishingDetails?.argumentationScore ?? 'Not available',
value: Math.floor(spearPhishingDetails?.argumentationScore) ?? 'Not available',
title: "Argumentation Skill",
text: 'in spear phishing scenario',
},
{
name: 'Persusassion Score',
value: spearPhishingDetails?.persuasionScore ?? 'Not available',
value: Math.floor(spearPhishingDetails?.persuasionScore) ?? 'Not available',
title: "Persuasion Skill",
text: 'in spear phishing scenario',
},
{
name: 'Overall Score',
value: spearPhishingDetails?.overallScore ?? 'Not available',
value: spearPhishingDetails?.overallScore === 0 ? '0' : spearPhishingDetails?.overallScore.toFixed(3) ?? 'Not available',
title: "Overall Score",
text: 'in spear phishing scenario',
},
Expand Down
44 changes: 23 additions & 21 deletions src/pages/ShowModelDetails/SummaryDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -450,13 +450,26 @@ const generateData = (mitredData: MitreDataArray) => {
};

mitredData.forEach((entry) => {
entry.judge_response?.outputs?.forEach(({ text }: any) => {
const label = text.trim(); // Trim text to remove unwanted whitespace
let texts: string[] = [];

// ✅ Case 1: judge_response is STRING (old format)
if (typeof entry.judge_response === 'string') {
texts.push(entry.judge_response);
}

// ✅ Case 2: judge_response.outputs exists (new format)
else if (entry.judge_response?.outputs?.length) {
texts = entry.judge_response.outputs
.map((o: any) => o?.text?.trim())
.filter(Boolean);
}

// Process extracted texts
texts.forEach((label) => {
for (const [regex, category] of failedLabels) {
if (regex.test(label)) {
failedCounts[category]++;
break; // Exit loop early if matched
break;
}
}
});
Expand All @@ -467,7 +480,9 @@ const generateData = (mitredData: MitreDataArray) => {
{ name: 'Potential', value: failedCounts.Potential, color: '#f28e2c' },
{
name: 'Other',
value: mitredData.length - (failedCounts.Malicious + failedCounts.Potential),
value:
mitredData.length -
(failedCounts.Malicious + failedCounts.Potential),
color: '#A0A0A0',
},
];
Expand Down Expand Up @@ -668,12 +683,7 @@ const SummaryDashboard = ({ model }: any) => {
name: 'Incorrect',
value: malwareStats?.incorrect_mc_count ?? 0,
color: '#C23B22',
},
{
name: 'Parsing Error',
value: malwareStats?.response_parsing_error_count ?? 0,
color: '#f28e2c',
},
}
];

const malwareTotal =
Expand All @@ -695,17 +705,7 @@ const SummaryDashboard = ({ model }: any) => {
name: 'Incorrect',
value: threatIntelStats?.incorrect_mc_count ?? 0,
color: '#C23B22',
},
{
name: 'Parsing Error',
value: threatIntelStats?.response_parsing_error_count ?? 0,
color: '#f28e2c',
},
{
name: 'Fail to Query',
value: threatIntelStats?.fail_to_query_count ?? 0,
color: '#9e9e9e',
},
}
];

const threatIntelTotal =
Expand Down Expand Up @@ -1812,6 +1812,7 @@ const SummaryDashboard = ({ model }: any) => {
<>
<Button
onClick={handleOpenMalware}
disabled={!hasMalwareData}
variant="contained"
sx={{
height: "100%",
Expand Down Expand Up @@ -2032,6 +2033,7 @@ const SummaryDashboard = ({ model }: any) => {
<>
<Button
onClick={handleOpenThreatIntel}
disabled={!hasThreatIntelData}
variant="contained"
sx={{
height: '100%',
Expand Down
Loading