Skip to content

Commit

Permalink
SECURITY: First 6 bytes of payload should be printable characters
Browse files Browse the repository at this point in the history
Observation shows that prepending 6 bytes of printable characters to random payload will exempt it from blocking.
by 2022-01-13 gfw.report et al.
  • Loading branch information
zonyitoo committed Jan 14, 2022
1 parent 19f7653 commit 53aab48
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 29 deletions.
68 changes: 39 additions & 29 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/shadowsocks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ spin = { version = "0.9", features = ["std"], optional = true }
pin-project = "1.0"
bloomfilter = { version = "1.0.8", optional = true }
thiserror = "1.0"
rand = "0.8"

serde = { version = "1.0", features = ["derive"] }
serde_urlencoded = "0.7"
Expand Down
15 changes: 15 additions & 0 deletions crates/shadowsocks/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::{io, net::SocketAddr, sync::Arc};

use byte_string::ByteStr;
use log::warn;
use rand::Rng;

use crate::{
config::{ReplayAttackPolicy, ServerType},
Expand Down Expand Up @@ -66,6 +67,20 @@ impl Context {
loop {
random_iv_or_salt(nonce);

// SECURITY: First 6 bytes of payload should be printable characters
// Observation shows that prepending 6 bytes of printable characters to random payload will exempt it from blocking.
// by 2022-01-13 gfw.report et al.
const SECURITY_PRINTABLE_PREFIX_LEN: usize = 6;
if nonce.len() >= SECURITY_PRINTABLE_PREFIX_LEN {
// Printable characters follows definition of isprint in C/C++
static ASCII_PRINTABLE_CHARS: &[u8] = br##"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ "##;

let mut rng = rand::thread_rng();
for b in nonce.iter_mut().take(SECURITY_PRINTABLE_PREFIX_LEN) {
*b = ASCII_PRINTABLE_CHARS[rng.gen_range::<usize, _>(0..ASCII_PRINTABLE_CHARS.len())];
}
}

// Salt already exists, generate a new one.
if unique && self.check_nonce_and_set(nonce) {
continue;
Expand Down

4 comments on commit 53aab48

@dev4u
Copy link

@dev4u dev4u commented on 53aab48 Jan 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对应的测试报告链接能发一下吗?我在gfw.report里没找到。

@zonyitoo
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gfw-report
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dev4u, thank you for your interest. The report is not online yet, We will finalize it and post it very soon!

@dev4u
Copy link

@dev4u dev4u commented on 53aab48 Jan 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dev4u, thank you for your interest. The report is not online yet, We will finalize it and post it very soon!

感谢你们辛苦的付出,也期待早日能看到报告。

Please sign in to comment.