From c147b2438fca6008c98cb1f5b34232014d0e7b0b Mon Sep 17 00:00:00 2001 From: Allande OYHENART Date: Tue, 9 Aug 2022 11:14:09 +0200 Subject: [PATCH] feat: Add telemetry option to the community connector Telemetry and assistance are now available if you choose this option in the installer --- innosetup/owlyshield-ransom-community.iss | 19 ++- owlyshield_predict/Cargo.toml | 2 +- .../src/connectors/community.rs | 132 +++++++++++++++++- 3 files changed, 138 insertions(+), 15 deletions(-) diff --git a/innosetup/owlyshield-ransom-community.iss b/innosetup/owlyshield-ransom-community.iss index be48285..08eafdd 100644 --- a/innosetup/owlyshield-ransom-community.iss +++ b/innosetup/owlyshield-ransom-community.iss @@ -3,7 +3,7 @@ #define AppId "8C19967B-1D27-4E6A-85CD-5059912C2788" #define AppName "Owlyshield Ransom Community" -#define AppVersion "1.1.0rc-1" +#define AppVersion "1.0.0" #define AppPublisher "SitInCloud" #define AppURL "https://www.owlyshield.com/" #define AgentName "Owlyshield Service" @@ -43,7 +43,7 @@ en.Service=Owlyshield service en.TelemetryHelp=Telemetry and help en.UserInfo=User Information en.EnterInfo=Please enter your information. -en.Username=Email adress: +en.Username=Email address: en.Company=Company/Organization: en.Country=Country: en.Phone=Phone number: @@ -228,15 +228,14 @@ Root: HKLM64; Subkey: "Software\Owlyshield"; ValueType: string; ValueName: "CONF Root: HKLM64; Subkey: "Software\Owlyshield"; ValueType: string; ValueName: "APP_ID"; ValueData: {#AppId}; Flags: uninsdeletekey Root: HKLM64; Subkey: "Software\Owlyshield"; ValueType: string; ValueName: "LANGUAGE"; ValueData: {code:GetLanguageKey}; Flags: uninsdeletekey Root: HKLM64; Subkey: "Software\Owlyshield"; ValueType: string; ValueName: "KILL_POLICY"; ValueData: "KILL"; Flags: uninsdeletekey - +Root: HKLM64; Subkey: "Software\Owlyshield"; ValueType: string; ValueName: "TELEMETRY"; ValueData: 0; Flags: uninsdeletekey; Components: not telemetry +Root: HKLM64; Subkey: "Software\Owlyshield"; ValueType: string; ValueName: "TELEMETRY"; ValueData: 1; Flags: uninsdeletekey; Components: telemetry ; Interface SitinCloud - Telemetry & Help -Root: HKLM64; Subkey: "Software\Owlyshield\SitinCloud"; ValueType: string; ValueName: "CLIENT_ID"; ValueData: {code:GetUserName}; Flags: uninsdeletekey; Components: telemetry -Root: HKLM64; Subkey: "Software\Owlyshield\SitinCloud"; ValueType: string; ValueName: "USER"; ValueData: {code:GetUserName}; Flags: uninsdeletekey; Components: telemetry -Root: HKLM64; Subkey: "Software\Owlyshield\SitinCloud"; ValueType: string; ValueName: "COMPANY"; ValueData: {code:GetUserCompany}; Flags: uninsdeletekey; Components: telemetry -Root: HKLM64; Subkey: "Software\Owlyshield\SitinCloud"; ValueType: string; ValueName: "COUNTRY"; ValueData: {code:GetUserCountry}; Flags: uninsdeletekey; Components: telemetry -Root: HKLM64; Subkey: "Software\Owlyshield\SitinCloud"; ValueType: string; ValueName: "PHONE"; ValueData: {code:GetUserPhone}; Flags: uninsdeletekey; Components: telemetry -Root: HKLM64; Subkey: "Software\Owlyshield\SitinCloud"; ValueType: string; ValueName: "TELEMETRY"; ValueData: 0; Flags: uninsdeletekey; Components: not telemetry -Root: HKLM64; Subkey: "Software\Owlyshield\SitinCloud"; ValueType: string; ValueName: "TELEMETRY"; ValueData: 1; Flags: uninsdeletekey; Components: telemetry +Root: HKLM64; Subkey: "Software\Owlyshield\Telemetry"; ValueType: string; ValueName: "CLIENT_ID"; ValueData: {code:GetUserName}; Flags: uninsdeletekey; Components: telemetry +Root: HKLM64; Subkey: "Software\Owlyshield\Telemetry"; ValueType: string; ValueName: "USER"; ValueData: {code:GetUserName}; Flags: uninsdeletekey; Components: telemetry +Root: HKLM64; Subkey: "Software\Owlyshield\Telemetry"; ValueType: string; ValueName: "COMPANY"; ValueData: {code:GetUserCompany}; Flags: uninsdeletekey; Components: telemetry +Root: HKLM64; Subkey: "Software\Owlyshield\Telemetry"; ValueType: string; ValueName: "COUNTRY"; ValueData: {code:GetUserCountry}; Flags: uninsdeletekey; Components: telemetry +Root: HKLM64; Subkey: "Software\Owlyshield\Telemetry"; ValueType: string; ValueName: "PHONE"; ValueData: {code:GetUserPhone}; Flags: uninsdeletekey; Components: telemetry [Run] Filename: "{app}\vc_redist.x64.exe"; Parameters: "/passive /norestart /showrmui /showfinalerror"; Flags: skipifdoesntexist waituntilterminated diff --git a/owlyshield_predict/Cargo.toml b/owlyshield_predict/Cargo.toml index 59dd195..4b82176 100644 --- a/owlyshield_predict/Cargo.toml +++ b/owlyshield_predict/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "owlyshield_ransom" -version = "1.0.0-rc2" +version = "1.0.0" edition = "2021" license-file = "LICENSE.txt" diff --git a/owlyshield_predict/src/connectors/community.rs b/owlyshield_predict/src/connectors/community.rs index 1a9c9b8..80109d3 100644 --- a/owlyshield_predict/src/connectors/community.rs +++ b/owlyshield_predict/src/connectors/community.rs @@ -6,14 +6,19 @@ use std::path::PathBuf; use std::time::SystemTime; use chrono::{DateTime, Local}; +use curl::easy::Easy; +use registry::{Hive, Security}; +use serde::Serialize; use log::error; use crate::config::{Config, Param}; use crate::connectors::connector::{Connector, ConnectorError}; -use crate::notifications::toast; use crate::process::ProcessRecord; +use crate::notifications::toast; use crate::utils::FILE_TIME_FORMAT; +use std::io::Read; + /// Struct of the [Community] interface. pub struct Community; @@ -22,6 +27,94 @@ impl Community { fn name() -> String { String::from("Community") } + + fn client() -> String { + let regkey = Hive::LocalMachine + .open(r"SOFTWARE\Owlyshield\Telemetry", Security::Read) + .expect("Cannot open registry hive"); + regkey + .value("CLIENT_ID") + .unwrap_or_else(|_| panic!("Cannot open registry key CLIENT_ID")) + .to_string() + } + + fn username() -> String { + let regkey = Hive::LocalMachine + .open(r"SOFTWARE\Owlyshield\Telemetry", Security::Read) + .expect("Cannot open registry hive"); + regkey + .value("USER") + .unwrap_or_else(|_| panic!("Cannot open registry key USER")) + .to_string() + } + + fn company() -> String { + let regkey = Hive::LocalMachine + .open(r"SOFTWARE\Owlyshield\Telemetry", Security::Read) + .expect("Cannot open registry hive"); + regkey + .value("COMPANY") + .unwrap_or_else(|_| panic!("Cannot open registry key COMPANY")) + .to_string() + } + + fn country() -> String { + let regkey = Hive::LocalMachine + .open(r"SOFTWARE\Owlyshield\Telemetry", Security::Read) + .expect("Cannot open registry hive"); + regkey + .value("COUNTRY") + .unwrap_or_else(|_| panic!("Cannot open registry key COUNTRY")) + .to_string() + } + + fn phone() -> String { + let regkey = Hive::LocalMachine + .open(r"SOFTWARE\Owlyshield\Telemetry", Security::Read) + .expect("Cannot open registry hive"); + regkey + .value("PHONE") + .unwrap_or_else(|_| panic!("Cannot open registry key PHONE")) + .to_string() + } +} + +#[derive(Debug, Serialize)] +#[allow(non_snake_case)] +struct Telemetry { + clientId: String, + username: String, + company: String, + country: String, + phone: String, + hostname: String, + numVersion: String, + language: String, + killPolicy: String, +} + +impl Telemetry { + fn from(config: &Config) -> Telemetry { + return Telemetry { + clientId: Community::client(), + username: Community::username(), + company: Community::company(), + country: Community::country(), + phone: Community::phone(), + hostname: hostname::get() + .unwrap() + .to_str() + .unwrap_or("Unknown host") + .to_string(), + numVersion: config[Param::NumVersion].clone(), + language: config[Param::Language].clone(), + killPolicy: config[Param::KillPolicy].clone(), + }; + } + + fn to_json(&self) -> String { + serde_json::to_string(&self).unwrap_or_else(|_| "{}".to_string()) + } } /// Implementation of the methods from [Connector] for the [Community] interface. @@ -31,10 +124,41 @@ impl Connector for Community { } fn on_startup(&self, config: &Config) -> Result<(), ConnectorError> { - match toast(config, "Program Started", "") { - Ok(()) => Ok(()), - Err(e) => Err(ConnectorError::new(Community::name().as_str(), &e)), + let toast = match toast(config, "Program Started", "") { + Ok(()) => "".to_string(), + Err(e) => e, + }; + + if config[Param::Telemetry].clone() == "1" { + let event = Telemetry::from(config).to_json(); + eprintln!("event = {:?}", event); + let mut data = event.as_bytes(); + let mut easy = Easy::new(); + let api_url = "https://api.owlyshield.com/telemetry"; //"telemetry.owlyshield.com"; + easy.url(api_url).unwrap(); + easy.post(true).unwrap(); + easy.post_field_size(data.len() as u64).unwrap(); + let mut transfer = easy.transfer(); + transfer.read_function(|buf| Ok(data.read(buf).unwrap_or(0)))?; + + return match transfer.perform() { + Ok(()) => { + if toast == "" { + Ok(()) + } else { + Err(ConnectorError::new( + Community::name().as_str(), + format!("Connector error: {}", toast).as_str(), + )) + } + }, + Err(e) => Err(ConnectorError::new( + Community::name().as_str(), + format!("Connector error: {}\n{}", toast, e.description()).as_str(), + )), + }; } + Ok(()) } fn on_event_kill(