Skip to content

Commit

Permalink
fix libs & impl brand spoofing
Browse files Browse the repository at this point in the history
  • Loading branch information
Outfluencer committed Dec 21, 2024
1 parent 639c303 commit 751a151
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 64 deletions.
10 changes: 6 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ codegen-units = 1
base64 = "0.22.1"
byteorder = "1.5.0"
cesu8 = "1.1.0"
openssl = { version = "0.10", features = ["vendored"] }
digest = "0.10.7"
either = "1.13.0"
env_logger = "0.11.5"
Expand All @@ -42,10 +41,13 @@ slotmap = "1.0.7"
tokio = { version = "1.42.0", features = ["full"] }
urlencoding = "2.1.3"
uuid = { version = "1.11.0", features = ["v4"] }
reqwest = { version = "0.12.9" }
paste = "1.0.15"
const_format = "0.2.34"
flate2 = { version = "1.0.35", features = ["zlib-ng"], default-features = false }

openssl = { version = "0.10", features = ["vendored"] }
reqwest = { version = "0.12.9" }

[target.'cfg(not(target_os = "windows"))'.dependencies]
flate2 = { version = "1.0.35", features = ["zlib-ng"], default-features = false }

[target.'cfg(target_os = "windows")'.dependencies]
flate2 = { version = "1.0.35", features = ["cloudflare_zlib"], default-features = false }
4 changes: 2 additions & 2 deletions src/server/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl EstablishedBackend {
compression_threshold,
&mut decryption,
).await;

if let Err(e) = res {
self_handle.disconnect(&e.to_string()).await;
break;
Expand Down Expand Up @@ -187,7 +187,7 @@ impl EstablishedBackend {
None,
address,
);

log::info!("[{}] <-> [{}]: connected", player_name, server_name);

let disconnect_lock = handle.disconnect_wait.clone();
Expand Down
5 changes: 1 addition & 4 deletions src/server/encryption.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//use aes::{cipher::{inout::InOutBuf, BlockDecryptMut, BlockEncryptMut, KeyIvInit}, Aes128};

use openssl::symm::{Cipher, Crypter, Mode};

pub struct PacketEncryption {
Expand Down Expand Up @@ -28,7 +26,6 @@ impl PacketEncryption {
}
}
}

pub struct PacketDecryption {
cipher: Crypter
}
Expand All @@ -55,4 +52,4 @@ impl PacketDecryption {
).unwrap();
}
}
}
}
126 changes: 73 additions & 53 deletions src/server/packet_handler.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::{future::Future, io::Cursor, pin::Pin, sync::{atomic::Ordering, Arc}};

use crate::{chat::Text, server::{packets::{self, Packet}, ProxyServer}, util::IOResult};

use crate::{chat::Text, server, server::{packets::{self, Packet}, ProxyServer}, util::IOResult};
use crate::server::packets::{ClientCustomPayload, ServerCustomPayload};
use crate::util::EncodingHelper;
use crate::version::R1_13;
use self::{command::CommandSender, packets::{TabCompleteRequest, TabCompleteResponse}};

use super::{brigadier::{ArgumentProperty, CommandNode, CommandNodeType, Commands, StringParserType, SuggestionsType}, command, packet_ids::{ClientPacketType, PacketRegistry, ServerPacketType}, packets::{ClientSettings, Kick, ProtocolState, SystemChatMessage, UnsignedClientCommand}, proxy_handler::ConnectionHandle, PlayerSyncData, SlotId};
Expand All @@ -10,64 +12,67 @@ pub struct ClientPacketHandler;

impl ClientPacketHandler {
pub async fn handle_packet(packet_id: i32, buffer: &[u8], version: i32, player_id: SlotId, client_handle: &ConnectionHandle, sync_data: &Arc<PlayerSyncData>) -> IOResult<bool> {
match PacketRegistry::instance().get_client_packet_type(client_handle.protocol_state(), version, packet_id) {
Some(packet_type) => match packet_type {
ClientPacketType::FinishConfiguration => {
client_handle.set_protocol_state(ProtocolState::Game);
if let Some(packet_type) = PacketRegistry::instance().get_client_packet_type(client_handle.protocol_state(), version, packet_id) { match packet_type {
ClientPacketType::FinishConfiguration => {
client_handle.set_protocol_state(ProtocolState::Game);
}
ClientPacketType::ConfigurationAck => {
client_handle.set_protocol_state(ProtocolState::Config);
if sync_data.is_switching_server.load(Ordering::Relaxed) {
sync_data.config_ack_notify.notify_one();
return Ok(false);
}
ClientPacketType::ConfigurationAck => {
client_handle.set_protocol_state(ProtocolState::Config);
if sync_data.is_switching_server.load(Ordering::Relaxed) {
sync_data.config_ack_notify.notify_one();
return Ok(false);
}
}
ClientPacketType::ClientSettings => {
let packet = ClientSettings::decode(&mut Cursor::new(buffer), version)?;
*sync_data.client_settings.lock().await = Some(packet);
},
ClientPacketType::ClientCustomPayload => {
let packet = ClientCustomPayload::decode(&mut Cursor::new(buffer), version)?;
if (version < R1_13 && packet.channel == "MC|Brand") || (version >= R1_13 && packet.channel == "minecraft:brand") {
*sync_data.brand_packet.lock().await = Some(packet);
}
ClientPacketType::ClientSettings => {
let packet = ClientSettings::decode(&mut Cursor::new(buffer), version)?;
*sync_data.client_settings.lock().await = Some(packet);
}
ClientPacketType::UnsignedClientCommand => {
let packet = UnsignedClientCommand::decode(&mut Cursor::new(buffer), version)?;
let line = packet.message;
let command_name = line.split_ascii_whitespace().next().unwrap_or("").to_string();
if ProxyServer::instance().command_registry().get_command_by_name(&command_name).is_none() {
return Ok(true);
}
ClientPacketType::UnsignedClientCommand => {
let packet = UnsignedClientCommand::decode(&mut Cursor::new(buffer), version)?;
let line = packet.message;
let command_name = line.split_ascii_whitespace().next().unwrap_or("").to_string();
if ProxyServer::instance().command_registry().get_command_by_name(&command_name).is_none() {
return Ok(true);
tokio::task::spawn_blocking(move || { // Needs to be blocking because commands are executed synchronously
if ProxyServer::instance().command_registry().execute(&CommandSender::Player(player_id), &line) {
return true;
} else {
log::debug!("Command not found '{}' passing command to server", line);
}
tokio::task::spawn_blocking(move || { // Needs to be blocking because commands are executed synchronously
if ProxyServer::instance().command_registry().execute(&CommandSender::Player(player_id), &line) {
return true;
} else {
log::debug!("Command not found '{}' passing command to server", line);
}
false
});
return Ok(false);
}
ClientPacketType::TabCompleteRequest => {
let packet = TabCompleteRequest::decode(&mut Cursor::new(buffer), version)?;
let cursor = packet.cursor;
if cursor.starts_with("/") {
let transaction_id = packet.transaction_id;
let response = tokio::task::spawn_blocking(move || { // Needs to be blocking because commands are executed synchronously
ProxyServer::instance().command_registry().tab_complete(&CommandSender::Player(player_id), &cursor[1..])
}).await?;
false
});
return Ok(false);
}
ClientPacketType::TabCompleteRequest => {
let packet = TabCompleteRequest::decode(&mut Cursor::new(buffer), version)?;
let cursor = packet.cursor;
if cursor.starts_with("/") {
let transaction_id = packet.transaction_id;
let response = tokio::task::spawn_blocking(move || { // Needs to be blocking because commands are executed synchronously
ProxyServer::instance().command_registry().tab_complete(&CommandSender::Player(player_id), &cursor[1..])
}).await?;
if let Some(response) = response {
if let Some(response) = response {
if let Some(response) = response {
let packet = packets::get_full_server_packet_buf(&TabCompleteResponse {
transaction_id,
commands: None, // TODO: Implement for versions < R1_13
suggestions: Some(response),
}, version, client_handle.protocol_state())?.unwrap();
let _ = client_handle.queue_packet(packet, false).await;
}
return Ok(false);
let packet = packets::get_full_server_packet_buf(&TabCompleteResponse {
transaction_id,
commands: None, // TODO: Implement for versions < R1_13
suggestions: Some(response),
}, version, client_handle.protocol_state())?.unwrap();
let _ = client_handle.queue_packet(packet, false).await;
}
return Ok(false);
}
}
_ => {}
},
None => {}
}
}
_ => {}
} }
Ok(true)
}
}
Expand Down Expand Up @@ -136,10 +141,25 @@ impl ServerPacketHandler {
commands.nodes[commands.root_index].childrens.push(node_index);
}
}
if let Some(packet_buf) = packets::get_full_server_packet_buf(&commands, version, server_handle.protocol_state()).unwrap() {
if let Some(packet_buf) = packets::get_full_server_packet_buf(&commands, version, server_handle.protocol_state())? {
let _ = client_handle.queue_packet(packet_buf, false).await;
}
return Ok(false);
},
ServerPacketType::ServerCustomPayload => {
let mut packet = ServerCustomPayload::decode(&mut Cursor::new(buffer), version)?;
if (version < R1_13 && packet.channel == "MC|Brand") || (version >= R1_13 && packet.channel == "minecraft:brand") {
let server_brand = EncodingHelper::read_string(&mut Cursor::new(&mut packet.data), u16::MAX as usize)?;
packet.data.clear();
EncodingHelper::write_string(&mut packet.data, format!("{} -> {}", server::NAME, server_brand).as_str())?;
if let Some(packet_buf) = packets::get_full_server_packet_buf(&packet, version, server_handle.protocol_state())? {
let _ = client_handle.queue_packet(packet_buf, false).await;
}
return Ok(false);
}

// TODO hanlde bungeecord plugin messages

}
_ => {}
} }
Expand Down
55 changes: 54 additions & 1 deletion src/server/packet_ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ pub enum ServerPacketType {
LoginSuccess, // login
SetCompression, // login

Kick, // config, game
StartConfiguration, // game
Kick, // config, game
ServerCustomPayload,
FinishConfiguration, // config
BundleDelimiter, // game
SystemChatMessage, // game
Expand All @@ -38,6 +39,8 @@ pub enum ClientPacketType {

LoginAcknowledged, // last packet before config mode

ClientCustomPayload, // config / game

ConfigurationAck, // game
FinishConfiguration, // config
ClientSettings, // config game
Expand Down Expand Up @@ -186,6 +189,13 @@ impl PacketRegistry {
Client, Config, ClientSettings;
(R1_20_2, 0x00)
}

begin! {
Client, Config, ClientCustomPayload;
(R1_20_2, 0x01)
(R1_20_5, 0x02)
}

begin! {
Client, Config, FinishConfiguration;
(R1_20_2, 0x02)
Expand All @@ -196,6 +206,11 @@ impl PacketRegistry {
Server, Config, CookieRequest;
(R1_20_5, 0x00)
}
begin! {
Server, Config, ServerCustomPayload;
(R1_20_2, 0x00)
(R1_20_5, 0x01)
}

begin! {
Server, Config, Kick;
Expand Down Expand Up @@ -245,10 +260,48 @@ impl PacketRegistry {
(R1_21_2, 0x0E)
}

begin! {
Client, Game, ClientCustomPayload;
(R1_8, 0x17 )
(R1_9, 0x09 )
(R1_12, 0x0A )
(R1_12_1, 0x09 )
(R1_13, 0x0A )
(R1_14, 0x0B )
(R1_17, 0x0A )
(R1_19, 0x0C )
(R1_19_1, 0x0D )
(R1_19_3, 0x0C )
(R1_19_4, 0x0D )
(R1_20_2, 0x0F )
(R1_20_3, 0x10 )
(R1_20_5, 0x12 )
(R1_21_2, 0x14 )
}

begin! {
Server, Game, CookieRequest;
(R1_20_5, 0x16)
}

begin! {
Server, Game, ServerCustomPayload;
(R1_8, 0x3F )
(R1_9, 0x18 )
(R1_13, 0x19 )
(R1_14, 0x18 )
(R1_15, 0x19 )
(R1_16, 0x18 )
(R1_16_2, 0x17 )
(R1_17, 0x18 )
(R1_19, 0x15 )
(R1_19_1, 0x16 )
(R1_19_3, 0x15 )
(R1_19_4, 0x17 )
(R1_20_2, 0x18 )
(R1_20_5, 0x19 )
}

begin! {
Server, Game, Kick;
(R1_8, 0x40)
Expand Down
Loading

0 comments on commit 751a151

Please sign in to comment.