uploaded the start of the pentest script.

This commit is contained in:
Pyro57000
2023-11-20 10:19:13 -06:00
committed by GitHub
parent 03f9b9ffb8
commit 1a5c05cf8c
3 changed files with 607 additions and 0 deletions

384
start_pentest/src/main.rs Normal file
View File

@@ -0,0 +1,384 @@
/*
Auther: Pyro
Purpose: To automate setting up my notes at the start of a pentest project
Install Instructions: Change the "Pentest_notes" variable below to the directory you keep your pentest notes in. Then run cargo build to compile and copy the binary at ./target/debug/start_pentest to something like /usr/bin
some special instructions for the file formats
the scope.txt file should be in the following format
host 3rd_party approval
example:
192.168.1.1 no yes
192.168.1.2 yes no
etc etc.
*/
use std::fs;
use std::env;
use std::fs::create_dir_all;
use std::io::Write;
use std::path::{Path, PathBuf};
use dirs::home_dir;
fn install(){
let mut install_path: PathBuf = PathBuf::new();
install_path.push(home_dir().expect("error getting home dir"));
install_path.push(".config/pyro_pentest_tools/");
fs::create_dir_all(&install_path).expect("error creating config directory");
install_path.push("start_pentest.conf");
let mut conf_file = fs::File::create(install_path).expect("error creating config file");
let mut project_folder_path = String::new();
let mut porject_note_path = String::new();
println!("path to the project folders directory?");
std::io::stdin().read_line(&mut project_folder_path).expect("error reading project folder from stdin");
println!("path to the project notes directory");
std::io::stdin().read_line(&mut porject_note_path).expect("error reading project note folder form stdin");
write!(conf_file, "project_folder_path:{}
project_notes_path:{}
", project_folder_path.trim_end(), porject_note_path.trim_end()).expect("error writing config file");
std::process::exit(0);
}
fn external(project_folder_path: String,comapny_name: &String, project_name: &String, scope: Vec<&str>){
let mut general_notes = fs::File::create(format!("{}/general.md", &project_folder_path)).expect("error creating general notes file");
let mut attack_notes = fs::File::create(format!("{}/attacks.md", &project_folder_path)).expect("error creating attack notes file");
let mut host_notes = fs::File::create(format!("{}/host_notes.md", &project_folder_path)).expect("error creating host notes file");
let mut finding_notes = fs::File::create(format!("{}/findings.md", &project_folder_path)).expect("error creating findings notes file");
// for tagging
let year = project_name.split("_").collect::<Vec<&str>>()[1];
let project_type = "External";
writeln!(&mut general_notes, "#{} #{} #{} #general", comapny_name, project_type, year).expect("error writing to general notes file");
writeln!(&mut attack_notes, "#{} #{} #{} #attack", comapny_name, project_type, year).expect("error writing tags on attack notes");
writeln!(&mut host_notes, "#{} #{} #{} #host_notes", comapny_name, project_type, year).expect("error writing tag lin in host notes");
writeln!(&mut finding_notes, "#{} #{} #{} #findings", comapny_name, project_type, year).expect("error writing tag line on findings");
writeln!(&mut general_notes, "# Scope").expect("error writing to general notes file");
writeln!(&mut general_notes, "| IP | Third Party | Approval |").expect("error writing to general notes file");
writeln!(&mut general_notes, "| -- | ----------- | -------- |").expect("error writing to general notes file");
for address in &scope{
if address.len() > 0{
let address_vec: Vec<&str> = address.split(" ").collect();
let address_line = format!("| {} | {} | {} |", address_vec[0], address_vec[1], address_vec[2]);
writeln!(&mut general_notes, "{}", address_line).expect("error writing to General Notes File");
}
}
writeln!(&mut general_notes, "# PPC").expect("failed to write general notes");
write!(&mut general_notes, "
Planning call notes:
* methodolgy
* whole month testing window
* start with a vuln scan in nessus pro
* pentesting execution standard framework
* info gathering
* recon
* exlpoitation
* reporting
* primary objective
* reasonable and expected protections are in place
* see if we can get access to the internal network
* if we do get inside
* reach out to the contact and see what they'd want us to know
* questions to ask
* custom objectives
*
* testing main website
* password attacks
* password sprays 3-12 hours
* lock out policy -
## Enumeration in progress
### DNS Bruteforcing
| domain name | IP | inscope? |
| ----------- | -- | -------- |
# Attack Surface Enumeration
| IP | host notes | needs? |
| -- | ---------- | ------ |\n").expect("faile to write pentest notes");
// set up the basics for our attack notes
write!(&mut attack_notes,"
# Directory Bruteforcing
- [ ] example.com
----
# Login attacks
## examle.com/login
- [ ] stuffed
- [ ] sprayed
- [ ] bruteforced
- [ ] default
----
# MSOLspray.py
passwords tried:
* password\n
" ).expect("failed to write attack notes template");
for host in scope{
write!(&mut host_notes, "
# {}
Domain Name:
| port | service | attack_notes |
| ---- | ------- | ------------ |
----
", host).expect("faield to write host notes");
write!(&mut finding_notes, "
# Critical
# High
# Medium
# Low
# informational
").expect("errror writing to findings for external");
}
}
fn internal(project_folder_path: String, comapny_name: &String, project_name: &String, scope: Vec<&str>){
let loot_folder = format!("{}/l00t", project_folder_path);
create_dir_all(&loot_folder).expect("error creating loot directory");
let mut general_notes = fs::File::create(format!("{}/general.md", &project_folder_path)).expect("error creating general notes file");
let mut attack_notes = fs::File::create(format!("{}/attacks.md", &project_folder_path)).expect("error creating attack notes file");
let mut finding_notes = fs::File::create(format!("{}/findings.md", &project_folder_path)).expect("error creating findings notes file");
let mut systeminfo = fs::File::create(format!("{}/systeminfo", &project_folder_path)).expect("error creating systeminfo note file");
let mut netsta = fs::File::create(format!("{}/netstat", &project_folder_path)).expect("error creating netstat file");
let mut creds_notes = fs::File::create(format!("{}/creds.md", &loot_folder)).expect("error creating creds note");
let mut todo_notes = fs::File::create(format!("{}/todo.md", &project_folder_path)).expect("error creating todo notes");
let mut cleanup_notes = fs::File::create(format!("{}/cleanup.md", &project_folder_path)).expect("error creating cleanup notes");
// for tagging notes
let oyear = project_name.split("_").collect::<Vec<&str>>()[0];
let year = format!("year-{}", oyear);
let project_type = "Internal";
writeln!(&mut creds_notes, "#{} #{} #{} #l00t #creds", comapny_name, project_type, year).expect("error writing creds notes");
writeln!(&mut cleanup_notes, "#{} #{} #{} #cleanup", comapny_name, project_type, year).expect("error writing to cleanup notes");
writeln!(&mut general_notes, "#{} #{} #{} #general", comapny_name, project_type, year).expect("error writing to general notes file");
writeln!(&mut attack_notes, "#{} #{} #{} #attack", comapny_name, project_type, year).expect("error writing attack note tags");
writeln!(&mut todo_notes, "#{} #{} #{} #todo", comapny_name, project_type, year).expect("error writing tag line on todo");
writeln!(&mut finding_notes, "#{} #{} #{} #findings", comapny_name, project_type, year).expect("error writing tags line on findings");
writeln!(&mut systeminfo, "#{} #{} #{} #general", comapny_name, project_type, year).expect("error writing tag line for system info");
writeln!(&mut netsta, "#{} #{} #{} #general", comapny_name, project_type, year).expect("error writing tagline in the netstat file");
writeln!(&mut creds_notes, "| System | username | password |").expect("error writing creds notes");
writeln!(&mut creds_notes, "| ------ | -------- | -------- |").expect("error writing creds notes");
writeln!(&mut cleanup_notes, "- [ ] Breach machine C-temp-fr").expect("error writing to cleanup notes");
writeln!(&mut cleanup_notes, "- [ ] (continue to add as needed").expect("error writing ot cleanup notes");
writeln!(&mut general_notes, "# Scope\n").expect("error writing to general notes file");
writeln!(&mut general_notes, "| IP | environment | inscope? |").expect("error writing to general notes file");
writeln!(&mut general_notes, "| -- | ----------- | -------- |").expect("error writing to general notes file");
for address in &scope{
if address.len() > 0{
let address_vec: Vec<&str> = address.split(" ").collect();
let address_line = format!("| {}|{}|{} |", address_vec[0], address_vec[1], address_vec[2]);
writeln!(&mut general_notes, "{}", address_line).expect("error writing to General Notes File");
}
}
let netstat_path = format!("{}/netstat", &project_folder_path);
let systeminfo_path = format!("{}/systeminfo", &project_folder_path);
write!(&mut general_notes, "
On the call:
Introductions
Let them know that their primary contact will be the PM and there should be
Go over general attack strategy/procedure.
We will get a beacon payload by the time the test starts
The beacon payload should be executed on a domain joined windows system.
If the system is not domain joined/no domain - let Seth know as this modifies the standard beacon
Select a user based on a department/role that they would like tested (Marketing, Sales, HR, IT)
This can be a test system with a cloned user, but then we don't get keylogging or screen grabs
The beacon is created using Cobalt Strike and communicates over HTTPS
Since Cobalt Strike is very well signatured, remind them that they may need to add an exclusion in antivirus and/or web filter
We will look at local privilege escalation, conduct portscans, password sprays, targeted vulnerability scanning (NOT NESSUS), lateral movement opportunities, and escalating to DOMAIN ADMIN privilege.
Ask if they want a focus on any particular assets. for example, an old time logging system, or remote access system.
Ask if they have any questions or concerns
Do they have a specific contact
Email any follow-up items from the call to the PM
").expect("error writing PPC text");
write!(&mut attack_notes,"
# current dat (ex: 7/5)
Got Persistence via (schtasks, bat schtasks, startup folder)
```
```
whoami /all
```
```
ipconfig /all
```
```
netstat -ano
[[{}|netstat]]
net accounts
```
```
net accounts /domain
```
```
net localgroup administrators
```
```
Net group \"domain admins\" /domain
```
```
net share
```
```
net use
```
```
systeminfo
[[{}|systeminfo]]
powerup.ps1/sharpup.exe notes.
```
```
", netstat_path, systeminfo_path).expect("error writing to attack notes for internal tests");
write!(&mut finding_notes, "
# normal findings
# data exfil
## [Sarting Username]
").expect("error writing to findings notes on internal");
write!(&mut todo_notes, "
- [ ] local checks
- [ ] find shares
- [ ] snaffle
- [ ] bloodhound
- [ ] admin or RDP?
- [ ] certify
- [ ] password spray
").expect("error writing todo list");
write!(&mut netsta,"
```
```").expect("error writing code block to system info");
write!(&mut systeminfo,"
```
```").expect("error writing code block to system info");
}
fn main() {
// change this to you own pentest notes folder
let mut pentest_notes = String::new();
// change this where you store your files for writing pentests
let mut project_files = String::new();
let args: Vec<String> = env::args().collect();
let usage = "
Welcome!!
This tool uses a config file at ~/.config/pyro_pentesting/tools/start_pentest.conf
If this file does not exist configuration creation function will run promping you for the paths needed for this program to run.
./start_pentest /path/to/scope.txt/file company_name project_name
Please make sure the type of pentest is included in the project name, such as internal, external, or webapp(to be implemented)
example:
start_pentest ./scope.txt victim_company_incorporated 2022_external_pentest
";
let mut config_file_path_buf = PathBuf::new();
config_file_path_buf.push(home_dir().expect("error reading home dir in main()"));
config_file_path_buf.push(".config/pyro_pentest_tools/start_pentest.conf");
println!("checking installation status");
if Path::new(&config_file_path_buf).exists(){
println!("reading existing configuration file");
}
else{
println!("no existing installation found");
install();
}
let config_string = fs::read_to_string(config_file_path_buf).expect("error reading ");
if config_string.contains("folder_path") && config_string.contains("notes_path"){
let config_string_vec: Vec<&str> = config_string.split("\n").collect();
for line in config_string_vec{
if line.contains("folder"){
let line_vec: Vec<&str> = line.split(":").collect();
project_files = line_vec[1].to_owned();
}
else if line.contains("notes"){
let line_vec: Vec<&str> = line.split(":").collect();
pentest_notes = line_vec[1].to_owned();
}
}
}
if args.len() == 4{
// the following two lines make the scope a vector
let scope_content = fs::read_to_string(&args[1]).expect("Error reading scope file");
let scope: Vec<&str> = scope_content.split("\n").collect();
let company_name = &args[2];
let project_name = &args[3];
let project_folder_path = format!("{}/{}/{}", pentest_notes, company_name,project_name);
println!("setting folder creation paths...");
let project_files_folder_path = format!("{}/{}/{}", project_files, company_name, project_name);
let working_folder = format!("{}/working", &project_files_folder_path);
let writing_folder = format!("{}/writing", &project_files_folder_path);
let screeenshot_folder = format!("{}/screenshots",&writing_folder);
let delivery_folder = format!("{}/delivery", &project_files_folder_path);
// make the folders for this project's notes and files
println!("creating directory structure for notes and file folders...");
fs::create_dir_all(&project_folder_path).expect("Error creating project folder");
fs::create_dir_all(&project_files_folder_path).expect("Error creating project file folder");
fs::create_dir_all(&working_folder).expect("error creating working directory");
fs::create_dir_all(&writing_folder).expect("Error creating writing direcotry");
fs::create_dir(&screeenshot_folder).expect("error creating screenshots folder");
fs::create_dir_all(&delivery_folder).expect("Error creating delivery direcotry");
if project_name.contains("internal"){
println!("internal pentest type detected, auto populating notes with internal layout...");
internal(project_folder_path,company_name, project_name, scope);
}
else if project_name.contains("external") {
println!("external pentest type detected, auto populating notes with external layout...");
external(project_folder_path, company_name, project_name, scope);
}
else if project_name.contains("webapp") {
println!("not implemented yet sorry");
println!("default file folder structure used, and empty notes folder created...")
}
else{
println!("unknown project type detected, default folder strucutre and empty note folder created...");
print!("
Known project types:
Internal Penetration Test
External Penetartion Test
If this test is actually one of these types please include the type in the project name parameter, example: 2023_internal_pentest.
If this test is a common test and you would like a default note structure implemented in this script let Kevin \"Kage\" Gunter know and supply an example markdown note sheet.");
}
}
else{
print!("{}", usage);
}
}