Skip to content

Commit

Permalink
Complete error handling in application, WhiteBeam 0.1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
noproto committed Feb 2, 2020
1 parent 92a390a commit 8c4b834
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 36 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!---
WhiteBeam Client version 0.1.0
WhiteBeam Client version 0.1.1
Open source EDR with application whitelisting
Expand All @@ -8,7 +8,7 @@ Copyright 2019, noproto
<p align="center">
<img src="https://gist.githubusercontent.com/noproto/ea7d62cd578afdd1bac2e96078c0e6b2/raw/cf895a5fef1f2295671653ece9155f4e1f0478e4/WhiteBeam.svg?sanitize=true" alt="WhiteBeam">
<br>
<img src="https://img.shields.io/badge/release-0.1.0-lightgrey?style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAE/UlEQVR42uWbXYhVVRTH/8u5MxbVpJRUZhgZYxoSpQ8lfUCURvnQBz2YBEMmGRURBD4UaBAU0cdYYdmXToSB0DwZhYgDRoVYic4kiqkTUmGTk4NjM87cub8e7r4wne65Z997zzn3Xuf/NnPP3mf9/2etvdZeZx+pCPg/9iomAGNF5h9XAgDeAw4B4xPuNd9nYDGMAeurNKgUhmMmfxA4DeQC91lYraFHEiBfQB/wfJXEdwODRYgXcFtcxm6NmTzOVf8EhiogvtGNzUXcY0m5Bpea8ETEPF8DZ6kMI2WQPwIMe857fxxPbKIox4uMXwYc8HgaURgEPixh5zEgW86Ecbnsz87dcAYcBTonjO8nXgwG7PsCGK1koiBXCxHglKSLywzDUUl/SbpMUpPqD1kzaw7+c0rIxTdJOlzmDVokzaxT8n2SFhX7oagAZnZU0kJJu9T46JR0nZnt8xbAiXBa0p2SbpbkW6kdqCPi/ZLuNbN2MzsbytNzUZwpaY9z8UbAdknLzWygCBeZWbQHBLzhd0mzJW2rc+Ijkp6WtDSMvO9DD/MEAU8GNhf1gv1AWwm7BbQCz8Sx0bgeOFknxMeBDiATQf5G4DDwqQ/BSzyuOQ/YWWPyfcDiCI8V8CjwjxuzyUeA48DtHtcZ8GwMJW8l2ApcFEH+AmBLYNxHvqVwFlgHmMf181IMiVPAI2Fl/YSnPg/oLTJ+Y7l7gW5gumdIfJkw+R3A5Z4uPxQyx4ZKNkP9wB2eIbEqAeLDwJpS3uiItwAfRMz1TqW7wRzwOjDFY/w1wImYyPcCCzzS8xyXCqPQUe12eE8pN5wwR4tbqCpFzqW3Zg/yy13/zwdvxNEPGATu86wZHqqgcPoDWOoRbhknUjl4Lc4e3idhBUhgviuAX8pIb5dGzNcEXAnsrcCzXolTgEJ3aLbHnBng/QivWh212Lp5lgB/VxhaL8ctAK7KeqyKdtt3wEqPsc3Aq1Uuqi8lIUABW4CpHvNPc9ePAt94rPLmxnwbQ1ZZm6QAuE5tm2fN0A7M8Mgmi4CBmNLqi14doSpwtaT9QHtEjwEz22xm/SXIXyhppaTdkqbHZN940gJI0lRJm4Au4PwKt9wzJH0uaUPMdqYiQAEPSDrk9Ub2v+TnS/pJ0rIEbEpVAEm6StI+4LmonaVLcSsk9UialZA9qQsgSRlJb0raHraHB1oldUj6LGG7aiJAAXdJ+iGYJdzf3ZKeSsGGmgogSW2SDrpmSxPwoKQf3dsopS1ARrWBSVoraYWkOVW1qstHrh4EKODaGtwzW+sQqDVyk12ASe8B45NdgAWTWQAkjdVTFkg79leb2cc+ApBybk4aZyQ9bGZfBX8IC4Ge4GrZwBiQdHcx8qECmNkNkjYrf/KrkdEnabGZfV+qJI3am5+S1NqAIdEr6R4z+63URZFZwMymKX9kLtdA5Lsl3RpF3jsNmtlc5c8HNcK60KX86bDBeBNovju7Bvi1Ts8IAbzt8/I2DjF2lHtIOWHkgHXpllTwVsSHCWkhCzyefk3pGpzu3WCtQmLI9y110mJ01UCEk6VOiKUtQAZ4wr2xTSMkjgFz63O7BbsS9oYeYFZdJ2LghZDvA6tFd+NsvOEW56pxhURXY3YgoDOGkHi3sdsw+a/IBhuiwElYiG1leEMWWHXuNeXyp0JGIsifObc7k/mTpD1hBc7kadHC+kCW6Evbhn8B9AX59hwJv14AAAAASUVORK5CYII=" alt="Release 0.1.0">
<img src="https://img.shields.io/badge/release-0.1.1-lightgrey?style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAE/UlEQVR42uWbXYhVVRTH/8u5MxbVpJRUZhgZYxoSpQ8lfUCURvnQBz2YBEMmGRURBD4UaBAU0cdYYdmXToSB0DwZhYgDRoVYic4kiqkTUmGTk4NjM87cub8e7r4wne65Z997zzn3Xuf/NnPP3mf9/2etvdZeZx+pCPg/9iomAGNF5h9XAgDeAw4B4xPuNd9nYDGMAeurNKgUhmMmfxA4DeQC91lYraFHEiBfQB/wfJXEdwODRYgXcFtcxm6NmTzOVf8EhiogvtGNzUXcY0m5Bpea8ETEPF8DZ6kMI2WQPwIMe857fxxPbKIox4uMXwYc8HgaURgEPixh5zEgW86Ecbnsz87dcAYcBTonjO8nXgwG7PsCGK1koiBXCxHglKSLywzDUUl/SbpMUpPqD1kzaw7+c0rIxTdJOlzmDVokzaxT8n2SFhX7oagAZnZU0kJJu9T46JR0nZnt8xbAiXBa0p2SbpbkW6kdqCPi/ZLuNbN2MzsbytNzUZwpaY9z8UbAdknLzWygCBeZWbQHBLzhd0mzJW2rc+Ijkp6WtDSMvO9DD/MEAU8GNhf1gv1AWwm7BbQCz8Sx0bgeOFknxMeBDiATQf5G4DDwqQ/BSzyuOQ/YWWPyfcDiCI8V8CjwjxuzyUeA48DtHtcZ8GwMJW8l2ApcFEH+AmBLYNxHvqVwFlgHmMf181IMiVPAI2Fl/YSnPg/oLTJ+Y7l7gW5gumdIfJkw+R3A5Z4uPxQyx4ZKNkP9wB2eIbEqAeLDwJpS3uiItwAfRMz1TqW7wRzwOjDFY/w1wImYyPcCCzzS8xyXCqPQUe12eE8pN5wwR4tbqCpFzqW3Zg/yy13/zwdvxNEPGATu86wZHqqgcPoDWOoRbhknUjl4Lc4e3idhBUhgviuAX8pIb5dGzNcEXAnsrcCzXolTgEJ3aLbHnBng/QivWh212Lp5lgB/VxhaL8ctAK7KeqyKdtt3wEqPsc3Aq1Uuqi8lIUABW4CpHvNPc9ePAt94rPLmxnwbQ1ZZm6QAuE5tm2fN0A7M8Mgmi4CBmNLqi14doSpwtaT9QHtEjwEz22xm/SXIXyhppaTdkqbHZN940gJI0lRJm4Au4PwKt9wzJH0uaUPMdqYiQAEPSDrk9Ub2v+TnS/pJ0rIEbEpVAEm6StI+4LmonaVLcSsk9UialZA9qQsgSRlJb0raHraHB1oldUj6LGG7aiJAAXdJ+iGYJdzf3ZKeSsGGmgogSW2SDrpmSxPwoKQf3dsopS1ARrWBSVoraYWkOVW1qstHrh4EKODaGtwzW+sQqDVyk12ASe8B45NdgAWTWQAkjdVTFkg79leb2cc+ApBybk4aZyQ9bGZfBX8IC4Ge4GrZwBiQdHcx8qECmNkNkjYrf/KrkdEnabGZfV+qJI3am5+S1NqAIdEr6R4z+63URZFZwMymKX9kLtdA5Lsl3RpF3jsNmtlc5c8HNcK60KX86bDBeBNovju7Bvi1Ts8IAbzt8/I2DjF2lHtIOWHkgHXpllTwVsSHCWkhCzyefk3pGpzu3WCtQmLI9y110mJ01UCEk6VOiKUtQAZ4wr2xTSMkjgFz63O7BbsS9oYeYFZdJ2LghZDvA6tFd+NsvOEW56pxhURXY3YgoDOGkHi3sdsw+a/IBhuiwElYiG1leEMWWHXuNeXyp0JGIsifObc7k/mTpD1hBc7kadHC+kCW6Evbhn8B9AX59hwJv14AAAAASUVORK5CYII=" alt="Release 0.1.1">
<a href="https://github.com/noproto/WhiteBeam/blob/master/LICENSE" title="License"><img src="https://img.shields.io/github/license/noproto/WhiteBeam?style=for-the-badge&color=lightgrey" alt="MIT Licensed"></a>
<a href="https://github.com/noproto/WhiteBeam/security/policy" title="Security"><img src="https://img.shields.io/badge/bounty-$1K-green?style=for-the-badge" alt="Bounty $1K"></a>
<a href="https://discord.gg/GYSVqYx" target="_blank" title="Chat"><img src="https://img.shields.io/discord/641744447289294859?style=for-the-badge" alt="Chat"></a>
Expand Down Expand Up @@ -37,7 +37,7 @@ Open source EDR with application whitelisting
| Platform | URL | Hash(es) |
| --------------- | ------------------------------------------------------------------ | -------- |
| Linux (x86_64) | https://dist.whitebeamsec.com/linux/x86_64/WhiteBeam_latest.tar.gz | [SHA-256](https://dist.whitebeamsec.com/linux/x86_64/WhiteBeam_latest.SHA256) |
| Linux (i686) | *Available February 1st* | *N/A* |
| Linux (i686) | *Available February 2nd* | *N/A* |
| Linux (aarch64) | *Available February 8th* | *N/A* |

Install WhiteBeam: `./install.sh`
Expand Down
13 changes: 7 additions & 6 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ gpg --keyserver hkp://pgp.mit.edu:80 --recv-keys 4A3F1233C01563F808B8355125ECFD1

**Current security vulnerability rewards** (will be provided at the discretion of the lead developers):

| Vulnerability | Reward |
| -------------------------------------------- | -------------- |
| Remote code execution (RCE) | $1000, Credits |
| Local privilege escalation (LPE) | $500, Credits |
| Bypass whitelisting on chal.whitebeamsec.com | $250, Credits |
| Cryptographic vulnerability | $150, Credits |
| Vulnerability | Reward |
| --------------------------------------------- | -------------- |
| Remote code execution (RCE) | $1000, Credits |
| Local privilege escalation (LPE) | $500, Credits |
| Bypass whitelisting on chal.whitebeamsec.com | $250, Credits |
| Cryptographic vulnerability | $150, Credits |
| Remote denial of service (DoS), service crash | $25 |

Past security advisories can be found here: https://github.com/noproto/WhiteBeam/security/advisories

Expand Down
2 changes: 1 addition & 1 deletion src/application/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# General info
[package]
name = "whitebeam"
version = "0.1.0"
version = "0.1.1"
authors = ["noproto"]
edition = "2018"

Expand Down
56 changes: 31 additions & 25 deletions src/application/common/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,28 @@ fn key_array_from_slice(bytes: &[u8]) -> [u8; SECRETKEYBYTES] {
array
}

fn generate_client_private_key(save_path: &Path) {
fn generate_client_private_key(save_path: &Path) -> Result<(), std::io::Error> {
let (_public_key, private_key) = box_::gen_keypair();
let private_key_bytes: &[u8] = private_key.as_ref();
let mut key_file = platform::path_open_secure(save_path);
key_file.write_all(private_key_bytes).unwrap();
Ok(key_file.write_all(private_key_bytes)?)
}

fn get_server_public_key() -> PublicKey {
fn get_server_public_key() -> Result<PublicKey, Box<dyn Error>> {
let conn: rusqlite::Connection = db::db_open();
let public_key_string: String = db::get_config(&conn, String::from("server_key"));
let public_key_bytes: &[u8] = &hex::decode(&public_key_string).unwrap();
PublicKey::from_slice(public_key_bytes).unwrap()
let public_key_bytes: &[u8] = &hex::decode(&public_key_string)?;
match PublicKey::from_slice(public_key_bytes) {
Some(public_key) => Ok(public_key),
None => Err("Invalid server public key".into())
}
}

fn get_client_public_private_key() -> Result<(PublicKey, SecretKey), Box<dyn Error>> {
let key_file_path: &Path = &platform::get_data_file_path("client.key");
let gen_key: bool = !key_file_path.exists();
if gen_key {
generate_client_private_key(key_file_path);
generate_client_private_key(key_file_path)?;
}
let mut key_file = std::fs::File::open(key_file_path)?;
let mut private_key_bytes: Vec<u8> = Vec::new();
Expand All @@ -74,7 +77,7 @@ pub struct Message {
pub parameters: Vec<String>
}

fn json_encode_message(action: String, parameters: Vec<String>) -> String {
fn json_encode_message(action: String, parameters: Vec<String>) -> Result<String, serde_json::Error> {
let expires = time::get_timestamp()+3600;
let version = env!("CARGO_PKG_VERSION").to_string();
let message_object = Message {
Expand All @@ -83,12 +86,12 @@ fn json_encode_message(action: String, parameters: Vec<String>) -> String {
action: action,
parameters: parameters
};
serde_json::to_string(&message_object).unwrap()
Ok(serde_json::to_string(&message_object)?)
}

fn json_decode_message(json: String) -> Message {
let message_object: Message = serde_json::from_str(&json).unwrap();
message_object
fn json_decode_message(json: String) -> Result<Message, serde_json::Error> {
let message_object: Message = serde_json::from_str(&json)?;
Ok(message_object)
}

#[derive(Serialize, Deserialize, Debug)]
Expand All @@ -98,26 +101,29 @@ pub struct CryptoBox {
pub ciphertext: String
}

fn json_encode_crypto_box(pubkey: String, nonce: String, ciphertext: String) -> String {
fn json_encode_crypto_box(pubkey: String, nonce: String, ciphertext: String) -> Result<String, serde_json::Error> {
let crypto_box_object = CryptoBox {
pubkey: pubkey,
nonce: nonce,
ciphertext: ciphertext
};
serde_json::to_string(&crypto_box_object).unwrap()
Ok(serde_json::to_string(&crypto_box_object)?)
}

#[allow(dead_code)]
fn json_decode_crypto_box(json: String) -> CryptoBox {
let crypto_box_object: CryptoBox = serde_json::from_str(&json).unwrap();
crypto_box_object
fn json_decode_crypto_box(json: String) -> Result<CryptoBox, serde_json::Error> {
let crypto_box_object: CryptoBox = serde_json::from_str(&json)?;
Ok(crypto_box_object)
}

fn nonce_array_from_slice(bytes: &[u8]) -> [u8; NONCEBYTES] {
fn nonce_array_from_slice(bytes: &[u8]) -> Result<[u8; NONCEBYTES], String> {
if bytes.len() != NONCEBYTES {
return Err("Invalid nonce".into());
}
let mut array = [0; NONCEBYTES];
let bytes = &bytes[..array.len()]; // Panics if not enough data
let bytes = &bytes[..array.len()];
array.copy_from_slice(bytes);
array
Ok(array)
}

/*
Expand All @@ -126,13 +132,13 @@ Encryption

fn generate_ciphertext(plaintext: &[u8], nonce: Nonce) -> Result<Vec<u8>, Box<dyn Error>> {
let (_client_public_key, client_private_key) = get_client_public_private_key()?;
let server_public_key = get_server_public_key();
let server_public_key = get_server_public_key()?;
Ok(box_::seal(plaintext, &nonce, &server_public_key, &client_private_key))
}

fn decrypt_server_ciphertext(ciphertext: &[u8], nonce: Nonce) -> Result<Vec<u8>, Box<dyn Error>> {
let (_client_public_key, client_private_key) = get_client_public_private_key()?;
let server_public_key = get_server_public_key();
let server_public_key = get_server_public_key()?;
// Verification and decryption
match box_::open(ciphertext, &nonce, &server_public_key, &client_private_key) {
Ok(plaintext) => Ok(plaintext),
Expand All @@ -151,10 +157,10 @@ pub fn get_client_public_key() -> Result<PublicKey, Box<dyn Error>> {

pub fn generate_crypto_box_message(action: String, parameters: Vec<String>) -> Result<String, Box<dyn Error>> {
let (client_public_key, _client_private_key) = get_client_public_private_key()?;
let message = json_encode_message(action, parameters);
let message = json_encode_message(action, parameters)?;
let nonce = box_::gen_nonce();
let ciphertext: Vec<u8> = generate_ciphertext(message.as_bytes(), nonce)?;
Ok(json_encode_crypto_box(hex::encode(client_public_key), hex::encode(nonce), hex::encode(ciphertext)))
Ok(json_encode_crypto_box(hex::encode(client_public_key), hex::encode(nonce), hex::encode(ciphertext))?)
}

pub fn process_request(crypto_box_object: CryptoBox) -> Result<Message, Box<dyn Error>> {
Expand All @@ -163,7 +169,7 @@ pub fn process_request(crypto_box_object: CryptoBox) -> Result<Message, Box<dyn
if db::get_seen_nonce(&conn, &crypto_box_object.nonce) {
return Err("Invalid message".into());
}
let nonce_array: [u8; NONCEBYTES] = nonce_array_from_slice(&hex::decode(crypto_box_object.nonce)?);
let nonce_array: [u8; NONCEBYTES] = nonce_array_from_slice(&hex::decode(crypto_box_object.nonce)?)?;
let nonce = Nonce(nonce_array);
let plaintext: String = String::from(
std::str::from_utf8(
Expand All @@ -173,7 +179,7 @@ pub fn process_request(crypto_box_object: CryptoBox) -> Result<Message, Box<dyn
)?
)?
);
let server_message = json_decode_message(plaintext);
let server_message = json_decode_message(plaintext)?;
let expiry = time::get_timestamp();
if server_message.expires < expiry {
// Message has expired
Expand Down
2 changes: 1 addition & 1 deletion src/library/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# General info
[package]
name = "libwhitebeam"
version = "0.1.0"
version = "0.1.1"
authors = ["noproto"]
edition = "2018"

Expand Down

0 comments on commit 8c4b834

Please sign in to comment.