Skip to content
API Documentation
BastionGuard™
AurScan Namespace Reference

Functions

bool isArchBased ()
void initialize (std::function< void(const std::string &)> logCallback, std::function< void(const std::string &)> pkgbuildDetectedCallback)
static bool ends_with (const std::string &s, const std::string &suf)
static bool isRecentlyDetected (const std::string &path)
static void addMonitorRecursively (const std::string &base)
static void addDynamicRootMonitor (const std::string &root)
void startMonitoring ()
void stopMonitoring ()
void scanPKGBUILD (const std::string &path)

Variables

static std::function< void(const std::string &)> logFunc
static std::function< void(const std::string &)> pkgbuildDetectedFunc
static std::vector< Glib::RefPtr< Gio::FileMonitor > > aurMonitors
static std::unordered_set< std::string > recentDetections

Function Documentation

◆ addDynamicRootMonitor()

void AurScan::addDynamicRootMonitor ( const std::string & root)
static

Definition at line 173 of file AurScan.cpp.

174{
175 if (!fs::exists(root)) return;
176
177 auto gfile = Gio::File::create_for_path(root);
178 auto monitor = gfile->monitor_directory(Gio::FileMonitorFlags::WATCH_MOVES);
179
180 monitor->signal_changed().connect(
181 [root](const Glib::RefPtr<Gio::File>& file,
182 const Glib::RefPtr<Gio::File>&,
183 Gio::FileMonitor::Event e)
184 {
185 std::string path = file->get_path();
186 if (path.empty()) return;
187
188
189 if (e == Gio::FileMonitor::Event::CREATED ||
190 e == Gio::FileMonitor::Event::MOVED_IN)
191 {
192 try {
193 if (fs::is_directory(path)) {
194
195 if (logFunc)
196 logFunc(_("🆕 Nuova directory AUR trovata: ") + path);
197
198
200 }
201 }
202 catch (...) {
203 }
204 }
205 });
206
207 aurMonitors.push_back(monitor);
208
209 if (logFunc)
210 logFunc(_("🌱 Monitor root AUR attivo su: ") + root);
211}
#define _(s)
static std::function< void(const std::string &)> logFunc
Definition AurScan.cpp:33
static std::vector< Glib::RefPtr< Gio::FileMonitor > > aurMonitors
Definition AurScan.cpp:36
static void addMonitorRecursively(const std::string &base)
Definition AurScan.cpp:93

References _, addDynamicRootMonitor(), addMonitorRecursively(), aurMonitors, and logFunc.

Referenced by addDynamicRootMonitor(), and startMonitoring().

◆ addMonitorRecursively()

void AurScan::addMonitorRecursively ( const std::string & base)
static

Definition at line 93 of file AurScan.cpp.

94{
95 if (!fs::exists(base)) return;
96
97
98 const std::vector<std::string> skipDirs = {
99 ".git", ".svn", ".hg", "pkg", "src"
100 };
101
102 auto basename = fs::path(base).filename().string();
103 for (const auto& skip : skipDirs) {
104 if (basename == skip)
105 return;
106 }
107
108
109 auto gfile = Gio::File::create_for_path(base);
110 auto monitor = gfile->monitor_directory(
111 Gio::FileMonitorFlags::WATCH_MOVES |
112 Gio::FileMonitorFlags::SEND_MOVED
113 );
114
115 monitor->signal_changed().connect(
116 [base](const Glib::RefPtr<Gio::File>& file,
117 const Glib::RefPtr<Gio::File>&,
118 Gio::FileMonitor::Event e)
119 {
120 std::string path = file->get_path();
121 if (path.empty()) return;
122
123 // Eventi rilevanti
124 if (e != Gio::FileMonitor::Event::CREATED &&
125 e != Gio::FileMonitor::Event::MOVED_IN &&
126 e != Gio::FileMonitor::Event::CHANGES_DONE_HINT)
127 return;
128
129
130 if (ends_with(path, "PKGBUILD")) {
131
132 //
133 if (isRecentlyDetected(path))
134 return;
135
136 if (logFunc)
137 logFunc(_("📦 PKGBUILD rilevato: ") + path);
138
141 }
142 });
143
144 aurMonitors.push_back(monitor);
145
146 if (logFunc)
147 logFunc(_("📁 Monitor AUR attivo su: ") + base);
148
149
150 try {
151 for (auto it = fs::directory_iterator(
152 base,
153 fs::directory_options::skip_permission_denied);
154 it != fs::directory_iterator();
155 ++it)
156 {
157 try {
158 if (it->is_directory())
159 addMonitorRecursively(it->path().string());
160 }
161 catch (...) {
162
163 continue;
164 }
165 }
166 }
167 catch (...) {
168 }
169}
static bool isRecentlyDetected(const std::string &path)
Definition AurScan.cpp:78
static std::function< void(const std::string &)> pkgbuildDetectedFunc
Definition AurScan.cpp:34
static bool ends_with(const std::string &s, const std::string &suf)
Definition AurScan.cpp:70

References _, addMonitorRecursively(), aurMonitors, ends_with(), isRecentlyDetected(), logFunc, and pkgbuildDetectedFunc.

Referenced by addDynamicRootMonitor(), addMonitorRecursively(), and startMonitoring().

◆ ends_with()

bool AurScan::ends_with ( const std::string & s,
const std::string & suf )
static

Definition at line 70 of file AurScan.cpp.

70 {
71 return s.size() >= suf.size() &&
72 s.compare(s.size() - suf.size(), suf.size(), suf) == 0;
73}

References ends_with().

Referenced by addMonitorRecursively(), and ends_with().

◆ initialize()

void AurScan::initialize ( std::function< void(const std::string &)> logCallback,
std::function< void(const std::string &)> pkgbuildDetectedCallback )

Definition at line 58 of file AurScan.cpp.

61{
62 logFunc = logCallback;
63 pkgbuildDetectedFunc = pkgbuildDetectedCallback;
64
65 if (logFunc)
66 logFunc(_("📦 AurScan inizializzato"));
67}

References _, initialize(), logFunc, and pkgbuildDetectedFunc.

Referenced by initialize().

◆ isArchBased()

bool AurScan::isArchBased ( )

Definition at line 40 of file AurScan.cpp.

40 {
41 std::ifstream f("/etc/os-release");
42 if (!f.is_open()) return false;
43
44 std::string line;
45 while (std::getline(f, line)) {
46 if (line.find("ID=") == 0 || line.find("ID_LIKE=") == 0) {
47 if (line.find("arch") != std::string::npos ||
48 line.find("manjaro") != std::string::npos ||
49 line.find("endeavouros") != std::string::npos ||
50 line.find("arco") != std::string::npos)
51 return true;
52 }
53 }
54 return false;
55}

References isArchBased().

Referenced by isArchBased(), and startMonitoring().

◆ isRecentlyDetected()

bool AurScan::isRecentlyDetected ( const std::string & path)
static

Definition at line 78 of file AurScan.cpp.

78 {
79 if (recentDetections.count(path))
80 return true;
81
82 recentDetections.insert(path);
83
84 // Rimuove dopo 1 secondo
85 Glib::signal_timeout().connect_once([path]() {
86 recentDetections.erase(path);
87 }, 1000);
88
89 return false;
90}
static std::unordered_set< std::string > recentDetections
Definition AurScan.cpp:76

References isRecentlyDetected(), and recentDetections.

Referenced by addMonitorRecursively(), and isRecentlyDetected().

◆ scanPKGBUILD()

void AurScan::scanPKGBUILD ( const std::string & path)

Definition at line 258 of file AurScan.cpp.

258 {
259 if (!fs::exists(path)) {
260 if (logFunc) logFunc(_("❌ PKGBUILD non trovato: ") + path);
261 return;
262 }
263
264 std::ifstream file(path);
265 if (!file.is_open()) {
266 if (logFunc) logFunc(_("❌ Impossibile leggere PKGBUILD: ") + path);
267 return;
268 }
269
270 if (logFunc)
271 logFunc(_("🔎 Analisi sicurezza PKGBUILD: ") + path);
272
273 std::string line;
274 int lineNum = 0;
275 bool suspicious = false;
276
277
278 auto isDependencyLine = [](const std::string& l) {
279 return l.find("depends=(") != std::string::npos ||
280 l.find("makedepends=(") != std::string::npos ||
281 l.find("optdepends=(") != std::string::npos ||
282 l.find("checkdepends=(") != std::string::npos ||
283 l.find("provides=(") != std::string::npos ||
284 l.find("conflicts=(") != std::string::npos;
285 };
286
287
288 const std::vector<std::pair<std::string, std::string>> patterns = {
289 {"curl ", _("Uso di curl come comando")},
290 {"curl|", _("Curl pipato verso shell — RCE")},
291 {"curl |", _("Curl pipato verso shell — RCE")},
292 {"wget ", _("Uso di wget come comando")},
293 {"wget|", _("Wget pipato verso shell — RCE")},
294 {"wget |", _("Wget pipato verso shell — RCE")},
295 {"bash -c", _("Esecuzione dinamica tramite bash -c")},
296 {"chmod 777", _("Permessi 777 pericolosi")},
297 {"rm -rf", _("Comando distruttivo rm -rf")},
298 {"sudo ", _("Uso improprio di sudo nel PKGBUILD")},
299 {"| sh", _("Pipe verso sh — RCE")},
300 {"| bash", _("Pipe verso bash — RCE")},
301 {"base64 -d", _("Possibile payload codificato e decodificato")},
302 {"install -m 777", _("Install con permessi insicuri")},
303 {"/etc/", _("Scrittura sospetta in /etc")},
304 {"/usr/bin", _("Scrittura diretta in /usr/bin")},
305 {"python3 -c", _("Exec dinamico con python")},
306 {"System.exec", _("Exec arbitrario")}
307 };
308
309
310 while (std::getline(file, line)) {
311 lineNum++;
312
313 if (isDependencyLine(line))
314 continue;
315
316 for (const auto& [needle, desc] : patterns) {
317 if (line.find(needle) != std::string::npos) {
318 suspicious = true;
319 if (logFunc) {
320 logFunc("⚠️ [" + std::to_string(lineNum) + "] " + desc);
321 logFunc(" → " + line);
322 }
323 }
324 }
325 }
326
327 if (suspicious) {
328 if (logFunc)
329 logFunc(_("🚨 Minacce individuate nel PKGBUILD!"));
330
332 pkgbuildDetectedFunc("INFECTED://" + path);
333
334 } else {
335 if (logFunc)
336 logFunc(_("✅ PKGBUILD pulito."));
337 }
338}
std::vector< Pattern > patterns()

References _, logFunc, pkgbuildDetectedFunc, and scanPKGBUILD().

Referenced by ScanPage::onAurPkgbuildDetected(), and scanPKGBUILD().

◆ startMonitoring()

void AurScan::startMonitoring ( )

Definition at line 213 of file AurScan.cpp.

213 {
214 if (!isArchBased()) {
215 if (logFunc)
216 logFunc(_("🐧 Sistema non Arch-based — AUR disattivato"));
217 return;
218 }
219
220 if (logFunc)
221 logFunc(_("📡 Avvio monitor AUR…"));
222
223 std::vector<std::string> targets = {
224 Glib::get_home_dir() + "/.cache/yay",
225 Glib::get_home_dir() + "/.cache/paru/clone",
226 Glib::get_home_dir() + "/.cache/trizen",
227 Glib::get_home_dir() + "/.cache/pikaur/build"
228 };
229
230 for (auto& d : targets) {
231 if (!fs::exists(d)) continue;
232
233
235
236
238 }
239
240 if (logFunc)
241 logFunc(_("✅ AurScan avviato"));
242}
static void addDynamicRootMonitor(const std::string &root)
Definition AurScan.cpp:173
bool isArchBased()
Definition AurScan.cpp:40

References _, addDynamicRootMonitor(), addMonitorRecursively(), isArchBased(), logFunc, and startMonitoring().

Referenced by startMonitoring().

◆ stopMonitoring()

void AurScan::stopMonitoring ( )

Definition at line 246 of file AurScan.cpp.

246 {
247 for (auto& m : aurMonitors) {
248 try { m->cancel(); }
249 catch (...) {}
250 }
251 aurMonitors.clear();
252
253 if (logFunc)
254 logFunc(_("🛑 AurScan disattivato"));
255}

References _, aurMonitors, logFunc, and stopMonitoring().

Referenced by stopMonitoring().

Variable Documentation

◆ aurMonitors

std::vector<Glib::RefPtr<Gio::FileMonitor> > AurScan::aurMonitors
static

Definition at line 36 of file AurScan.cpp.

Referenced by addDynamicRootMonitor(), addMonitorRecursively(), and stopMonitoring().

◆ logFunc

std::function<void(const std::string&)> AurScan::logFunc
static

◆ pkgbuildDetectedFunc

std::function<void(const std::string&)> AurScan::pkgbuildDetectedFunc
static

Definition at line 34 of file AurScan.cpp.

Referenced by addMonitorRecursively(), initialize(), and scanPKGBUILD().

◆ recentDetections

std::unordered_set<std::string> AurScan::recentDetections
static

Definition at line 76 of file AurScan.cpp.

Referenced by isRecentlyDetected().