diff --git a/bridges/CybermonitBridge.php b/bridges/CybermonitBridge.php new file mode 100755 index 00000000..250fed50 --- /dev/null +++ b/bridges/CybermonitBridge.php @@ -0,0 +1,152 @@ + [ + 'name' => 'feed_type', + 'type' => 'list', + 'values' => [ + 'Leaks' => 'Leaks', + 'CVEs' => 'CVEs', + 'DDoS' => 'DDoS', + 'Ransomware' => 'Ransomware', + 'Releases' => 'Releases', + 'EOL' => "EOL" + ] + ] + ]]; + + public function getURI() { + switch ($this->getKey("feed_type")) { + case 'Leaks': + return 'https://pypbbsgyhtlerxdyfuvv.supabase.co/storage/v1/object/dane/leak.json'; + break; + case 'CVEs': + return 'https://pypbbsgyhtlerxdyfuvv.supabase.co/storage/v1/object/dane/2025.json'; + break; + case 'DDoS': + return 'https://pypbbsgyhtlerxdyfuvv.supabase.co/storage/v1/object/dane/ddos.json'; + break; + case 'Ransomware': + return 'https://pypbbsgyhtlerxdyfuvv.supabase.co/storage/v1/object/dane/ransomware.json'; + break; + case 'EOL': + return 'https://pypbbsgyhtlerxdyfuvv.supabase.co/storage/v1/object/dane/eol.json'; + break; + case 'Releases': + return 'https://pypbbsgyhtlerxdyfuvv.supabase.co/storage/v1/object/dane/releases.json'; + break; + default: + return 'https://cybermonit.com'; + break; + } + } + + public function collectData() + { + $opts = array( + 'accept: */*', + 'apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InB5cGJic2d5aHRsZXJ4ZHlmdXZ2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDAxMjUwNzAsImV4cCI6MjA1NTcwMTA3MH0.xmcCqJUgvRtVsp6XmaH1YmUeerqZRZNQ_XmCnpOEFAo', + 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InB5cGJic2d5aHRsZXJ4ZHlmdXZ2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDAxMjUwNzAsImV4cCI6MjA1NTcwMTA3MH0.xmcCqJUgvRtVsp6XmaH1YmUeerqZRZNQ_XmCnpOEFAo', + 'origin: https://cybermonit.com', + 'referer: https://cybermonit.com', + 'user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/6.8.2 Chrome/122.0.6261.171 Safari/537.36', + 'x-client-info: supabase-js-web/2.49.1', + ); + $html = getContents($this->getURI(), $opts); + $data = json_decode($html, true); + array_walk_recursive($data, function(&$item, $key) { + $item = htmlspecialchars($item); + }); + + switch ($this->getKey("feed_type")) { + case 'Leaks': + foreach ($data as $obj) { + $this->items[] = [ + 'title' => sprintf("%s - %s", empty($obj['domain']) ? 'Unknown' : $obj['domain'], $obj['data_leaked']), + 'timestamp' => $obj['breach_date'], + 'uri' => "https://cybermonit.com/leaks", + 'categories' => ['leaks'], + 'content' => $obj['description'], + 'uid' => sha1(sprintf("%s.%s.%s", $obj['domain'], $obj['breach_date'], self::SALT)) + ]; + } + break; + case 'CVEs': + foreach ($data as $obj) { + $this->items[] = [ + 'title' => sprintf("%s (%s %s) - %s", $obj['cve_id'], $obj['score'], $obj['severity_en'], substr($obj['description'], 0, 150).'[...]'), + 'timestamp' => $obj['publishedDate'], + 'uri' => "https://cybermonit.com/cve", + "categories" => ['CVEs'], + 'content' => $obj['description'], + 'uid' => sha1(sprintf("%s.%s.%s", $obj['cve_id'], $obj['publishedDate'], self::SALT)) + ]; + } + break; + case 'DDoS': + foreach ($data['targets'] as $obj) { + $this->items[] = [ + 'title' => sprintf("%s", $obj['host']), + 'timestamp' => null, + 'uri' => "https://cybermonit.com/ddos", + "categories" => ['DDoS'], + "content" => sprintf("IP: %s
Type: %s
Method: %s
Port: %s
Use SSL: %s", $obj['ip'], $obj['type'], $obj['method'], $obj['port'], $obj['use_ssl'] == 1 ? "True" : "False"), + 'uid' => sha1(sprintf("%s.%s.%s", $obj['host'], $obj['ip'], self::SALT)) + ]; + } + break; + case 'Ransomware': + foreach ($data as $obj) { + $this->items[] = [ + 'title' => sprintf("%s attack on %s (%s)", $obj['group'], $obj['victim'], $obj['country']), + 'timestamp' => $obj['attackdate'], + "categories" => ['Ransomware', $obj['group']], + 'uri' => "https://cybermonit.com/ransomware", + "content" => "Ransomware attack ({$obj['group']}) on {$obj['victim']}, country: {$obj['country']}", + 'uid' => sha1(sprintf("%s.%s.%s", $obj['victim'], $obj['attackdate'], self::SALT)) + ]; + } + break; + case 'Releases': + foreach ($data as $obj) { + $this->items[] = [ + 'title' => sprintf("%s %s", $obj['nazwa_projektu'], $obj['wersja']), + 'timestamp' => $obj['data_wydania'], + 'categories' => ['Releases'], + 'uri' => $obj['url_zdjecia'], + 'content' => sprintf("%s updated to version %s. Project URL: %s, Release notes: %s", $obj['nazwa_projektu'], $obj['wersja'], $obj['url_projektu'], $obj['url_zdjecia']), + 'uid' => sha1(sprintf("%s.%s.%s", $obj['nazwa_projektu'], $obj['data_wydania'], self::SALT)) + ]; + } + break; + case 'EOL': + foreach ($data as $key => $v) { + $val = $v[0]; + $this->items[] = [ + 'title' => sprintf("%s %s %s", $key, $val['cycle'], $val['lts'] == true ? 'LTS' : ''), + 'timestamp'=> null, + 'categories'=> ['EOL'], + 'uri' => $this->getURI(), + 'content' => sprintf("Product: %s
Version: %s
Release date: %s
End of life: %s", $key, $val['cycle'], $val['releaseDate'], $val['eol']), + 'uid' => sha1(sprintf("%s.%s.%s", $key, $val['eol'], self::SALT)) + ]; + } + break; + default: + break; + } + usort($this->items, function($a, $b) { + if ($a['timestamp'] == $b['timestamp']) { + return 0; + } + return ($a['timestamp'] > $b['timestamp']) ? -1 : 1; + }); + } +} diff --git a/bridges/FeedProxyBridge.php b/bridges/FeedProxyBridge.php new file mode 100755 index 00000000..4cb01fa4 --- /dev/null +++ b/bridges/FeedProxyBridge.php @@ -0,0 +1,50 @@ + +TEXT; + + const PARAMETERS = [ + [ + 'feed_name' => [ + 'name' => 'Feed name', + 'type' => 'text', + 'exampleValue' => 'FeedProxy', + ], + 'feed_1' => [ + 'name' => 'Feed url', + 'type' => 'text', + 'required' => true, + 'exampleValue' => 'https://lorem-rss.herokuapp.com/feed?unit=day' + ], + 'limit' => self::LIMIT, + ] + ]; + + /** + * TODO: Consider a strategy which produces a shorter feed url + */ + public function collectData() + { + $limit = (int)($this->getInput('limit') ?: 99); + $feed = $this->getInput('feed_1'); + $this->collectExpandableDatas($feed, $limit); + + // Sort by timestamp, uri, title in descending order + usort($this->items, function ($a, $b) { + $t1 = $a['timestamp'] ?? $a['uri'] ?? $a['title']; + $t2 = $b['timestamp'] ?? $b['uri'] ?? $b['title']; + return $t2 <=> $t1; + }); + } + + public function getName() + { + return $this->getInput('feed_name') ?: 'FeedProxy'; + } +} diff --git a/bridges/OSVBridge.php b/bridges/OSVBridge.php new file mode 100755 index 00000000..9becaa6f --- /dev/null +++ b/bridges/OSVBridge.php @@ -0,0 +1,54 @@ +find('.vuln-table-row') as $element) { + $item = []; + $link = $element->find('.vuln-table-cell > a', 0); + if (empty($link)) continue; + $time = $element->find('span.vuln-table-cell',3)->find('relative-time',0); + $summary = $element->find('.vuln-summary',0); + $tags = $element->find('ul.tags > li',0); + + $item['uri'] = self::MAIN_DOMAIN . $link->href; + $item['title'] = $link->innertext; + $item['title'] .= sprintf(" - %s", trim($summary->innertext)); + + $item['timestamp'] = $time->datetime; + $packages = ""; + foreach ($element->find('ul.packages > li',0) as $pack) { + $packages .= !empty($pack->innertext) ? "
  • $pack->innertext
  • " : ""; + } + $tagsout = ""; + foreach ($element->find('ul.tags > li > span') as $tag) { + $tagsout .= !empty($tag->innertext) ? "
  • {$tag->innertext}
  • " : ""; + } + + $item['content'] = "{$link->innertext} - {$summary->innertext}
    Published: {$time->innertext}
    Packages:
    Tags: "; + $item['uid'] = $link->innertext; + + $this->items[] = $item; + } + } + public function collectData() + { + $html = getSimpleHTMLDOM($this->getURI()); + $this->parseItems($html); + usort($this->items, function($a, $b) { + if ($a['timestamp'] == $b['timestamp']) { + return 0; + } + return ($a['timestamp'] > $b['timestamp']) ? -1 : 1; + }); + } +}