diff --git a/Gemfile b/Gemfile index dd163ea6e..fdf4215bb 100644 --- a/Gemfile +++ b/Gemfile @@ -40,6 +40,7 @@ gem 'CFPropertyList' gem 'artii' gem 'rest-client' gem 'retryable' +gem 'sqlite3' #development only gems go here group :test, :development do diff --git a/Gemfile.lock b/Gemfile.lock index 264047eb1..46e9f73f1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -160,6 +160,7 @@ GEM smbhash (1.0.2) spidr (0.6.1) nokogiri (~> 1.3) + sqlite3 (1.4.4) sshkey (2.0.0) text (1.3.1) thor (0.19.4) @@ -186,7 +187,6 @@ DEPENDENCIES bcrypt braille! cinch - concurrent-ruby (= 1.1.9) credy digest-siphash duplicate @@ -218,6 +218,7 @@ DEPENDENCIES scrypt sha3 smbhash + sqlite3 sshkey wordlist yard diff --git a/lib/helpers/constants.rb b/lib/helpers/constants.rb index d0e0029d7..6100123bf 100644 --- a/lib/helpers/constants.rb +++ b/lib/helpers/constants.rb @@ -50,8 +50,7 @@ ASCII_ART_DIR = "#{ROOT_DIR}/lib/resources/ascii_art" EVIL_PLANS_DIR = "#{ROOT_DIR}/lib/resources/narrative/evil_plans" PASSWORDLISTS_DIR = "#{ROOT_DIR}/lib/resources/passwordlists" WS_ATTACK_DIR = "#{ROOT_DIR}/lib/resources/ws_attacks" -STYLING_DIR = "#{ROOT_DIR}/lib/resources/website_styling" -SAMP_DBS_DIR = "#{ROOT_DIR}/lib/resources/sample_databases" +SQLITE_DIR = "#{ROOT_DIR}/lib/resources/sqlite" # Path to build puppet modules LOCAL_PUPPET_DIR = "#{MODULES_DIR}build/puppet" @@ -63,6 +62,8 @@ CYBOK_FILENAME = "cybok.xml" SPOILER_ADMIN_FILENAME = "spoiler_admin_pass" IP_ADDRESSES_FILENAME = "IP_addresses.json" +INTERESTS_DIR = "#{ROOT_DIR}/lib/resources/interests" +TMP_DIR = "/tmp" ## PACKER CONSTANTS ## diff --git a/lib/resources/linelists/linux_commands b/lib/resources/linelists/linux_commands new file mode 100644 index 000000000..aaf18256c --- /dev/null +++ b/lib/resources/linelists/linux_commands @@ -0,0 +1,93 @@ +locate test2 +curl -I http://google.com +whoami +passwd +which ls +uptime +touch /tmp/ +tail -n 100 /var/log/messages +stat /bin/ls +tar -cvf archive.tar ~ +tar -xvf archive.tar -C ~ +traceroute google.com +uname -a +uptime -p +wc -l /var/log/messages +watch -n 1 ls +wget http://google.com +who +id +zip -r archive.zip ~ +unzip archive.zip -d ~ +rsync -avz ~ /tmp/ +ps -ef | grep "firefox" +netstat -antp | grep "80" +ifconfig -a +ip a +ip a s +hostnamectl set-hostname server +dig google.com +cat /proc/cpuinfo +ls /usr/bin +du -h /home/user +mkdir test +mkdir tmp +awk '{print $2}' /proc/meminfo +df -h +du -sh * +free -m +grep -i "test" file.txt +killall -9 firefox +hostname -i +hostname -I +nc -l 4444 +passwd +ping -c 5 8.8.8.8 +ps -aux | grep "firefox" +rmdir tmp +ssh-keygen -t rsa -b 4096 +touch -d "1 day ago" test.txt +uptime -s +uname -r +whois google.com +zip -r archive.zip ~ +locate whoami +find . -type d -empty -delete +cat /proc/mdstat +route +ping 8.8.8.8 +md5sum +dig google.com +traceroute google.co.uk +clear +du -sh +debsums -c +debsums +v4l2-ctl -c white_balance_temperature=3000 +top +kill -9 2342 +kill -9 436 +kill -9 4693 +kill -9 85803 +man usermod +gem list +xwininfo +man sync +sync +traceroute6 google.com +traceroute6 google.co.uk +dhclient -h +man +konsole +dolphin +firefox +kate +uptime +date +ps aux +jobs +crotab -e +chmod 700 ~ +ls /tmp +ls -la /tmp +ls -la diff --git a/lib/resources/linelists/sudo_commands b/lib/resources/linelists/sudo_commands new file mode 100644 index 000000000..578f530b6 --- /dev/null +++ b/lib/resources/linelists/sudo_commands @@ -0,0 +1,168 @@ +sudo apt-get update +sudo apt-get install chromium-browser +sudo apt-get remove chromium-browser +sudo apt-get install gimp +sudo apt-get remove gimp +sudo apt-get install openssh-server +sudo apt-get remove openssh-server +sudo apt-get install python3 +sudo apt-get remove python3 +sudo apt-get install vlc +sudo apt-get remove vlc +sudo apt-get install apache2 +sudo apt-get remove apache2 +sudo apt-get install mysql-server +sudo apt-get remove mysql-server +sudo apt-get install php +sudo apt-get remove php +sudo apt-get install nodejs +sudo apt-get remove nodejs +sudo apt-get install npm +sudo apt-get remove npm +sudo apt-get install git +sudo apt-get remove git +sudo apt-get install vim +sudo apt-get remove vim +sudo apt-get install emacs +sudo apt-get remove emacs +sudo apt-get install curl +sudo apt-get remove curl +sudo apt-get install wget +sudo apt-get remove wget +sudo apt-get install tar +sudo apt-get remove tar +sudo apt-get install zip +sudo apt-get remove zip +sudo apt-get install unzip +sudo apt-get remove unzip +sudo apt-get install python +sudo apt-get remove python +sudo apt-get install python-pip +sudo apt-get remove python-pip +sudo apt-get install python3-pip +sudo apt-get remove python3-pip +sudo apt-get install virtualenv +sudo apt-get remove virtualenv +sudo apt-get install docker +sudo apt-get remove docker +sudo apt-get install postgresql +sudo apt-get remove postgresql +sudo apt-get install mongodb +sudo apt-get remove mongodb +sudo apt-get install redis-server +sudo apt-get remove redis-server +sudo apt-get install memcached +sudo apt-get remove memcached +sudo apt-get install gcc +sudo apt-get remove gcc +sudo apt-get install make +sudo apt-get remove make +sudo apt-get install nginx +sudo apt-get remove nginx +sudo systemctl restart apache2 +sudo systemctl stop nginx +sudo systemctl start networking +sudo systemctl restart mysql +sudo systemctl stop postfix +sudo systemctl start ssh +sudo systemctl restart php7.4-fpm +sudo systemctl stop cups +sudo systemctl start cron +sudo systemctl restart memcached +sudo systemctl stop docker +sudo systemctl start docker +sudo systemctl restart redis-server +sudo systemctl stop bluetooth +sudo systemctl start bluetooth +sudo systemctl restart postfix +sudo systemctl stop apache2 +sudo systemctl start nginx +sudo systemctl restart ssh +sudo systemctl stop networking +sudo systemctl start postgresql +sudo systemctl restart mariadb +sudo systemctl stop exim4 +sudo systemctl start exim4 +sudo systemctl restart ufw +sudo systemctl stop ufw +sudo systemctl start apache2 +sudo systemctl restart nginx +sudo systemctl stop rpcbind +sudo systemctl start rpcbind +sudo systemctl restart squid +sudo systemctl stop ssh +sudo systemctl start networking.service +sudo systemctl restart bind9 +sudo systemctl stop apache2.service +sudo systemctl start php7.3-fpm.service +sudo systemctl restart sshd +sudo systemctl stop systemd-timesyncd +sudo systemctl start systemd-timesyncd +sudo systemctl restart named +sudo systemctl restart rsyslog +sudo systemctl stop rsyslog +sudo systemctl start vsftpd +sudo systemctl restart clamav-daemon +sudo systemctl stop clamav-daemon +sudo systemctl start postfix.service +sudo systemctl restart postfix.service +sudo systemctl stop nginx.service +sudo ufw enable +sudo ufw disable +sudo chown -R user:user /tmp/asdf32 +sudo chmod -R 755 /tmp +sudo systemctl status networking +sudo apt-get upgrade +sudo apt-get dist-upgrade +sudo apt-get autoremove +sudo apt-get clean +sudo find . -type f -exec rm {} ; +sudo tar -xvf archive.tar -C /extract/ +sudo tail -f /var/log/messages +sudo chmod 700 /tmp/sdf435 +sudo passwd +sudo mount /dev/sdb1 /mnt/usb +sudo umount /mnt/usb +sudo chattr +i /var/log/messages +sudo crontab -e +sudo dpkg -i d456.deb +sudo dpkg --configure -a +sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys keynumber +sudo apt-get install build-essential +sudo apt-get install python3-pip +sudo systemctl reload networking +sudo visudo +sudo mount /dev/sdb1 /mnt/usb +sudo mount -t ext4 /dev/sda1 /mnt/data +sudo mount /dev/cdrom /mnt/cdrom +sudo mount /dev/sdb2 /mnt/backup +sudo mount -o loop /mnt/cdrom/image.iso /mnt/iso +sudo mount /dev/sdc1 /mnt/external +sudo mount -t vfat /dev/sda2 /mnt/usb_drive +sudo mount -t ntfs-3g /dev/sdb1 /mnt/win_drive +sudo mount -t iso9660 /dev/cdrom /mnt/cdrom +sudo mount /dev/sdb1 /mnt/backup -o rw,user +sudo mount -t tmpfs -o size=1G tmpfs /mnt/ramdisk +sudo mount -t exfat /dev/sdc1 /mnt/external_drive +sudo mount -t ext4 /dev/sda1 /mnt/ubuntu +sudo mount -t ntfs /dev/sda1 /mnt/windows +sudo mount -t btrfs /dev/sdb1 /mnt/btrfs +sudo mount /dev/sdc1 /mnt/usb_drive +sudo mount -t vfat /dev/sdc1 /mnt/flash_drive +sudo mount -t ext2 /dev/sdb1 /mnt/data +sudo mount -t udf /dev/sr0 /mnt/dvd +sudo mount /dev/sdb1 /mnt/storage -o rw,uid=1000,gid=1000 +sudo mount -t ext4 /dev/sda3 /mnt/home +sudo mount -t ntfs /dev/sdb1 /mnt/ntfs_drive -o ro,umask=0222 +sudo mount -t ext4 /dev/sdb2 /mnt/backup -o noatime +sudo mount -t ext4 /dev/sda1 /mnt/root +sudo mount -t vboxsf -o uid=1000,gid=1000 share_name /mnt/share +sudo mount -t exfat-fuse /dev/sdb1 /mnt/exfat_drive +sudo mount -t ext4 /dev/sda1 /mnt/linux +sudo mount -t btrfs /dev/sda1 /mnt/btrfs_drive +sudo mount -t udf /dev/sr0 /mnt/cdrom +sudo mount +sudo snap remove discord +sudo snap set system refresh.retain=2 +sudo dhclient +sudo -i diff --git a/lib/resources/linelists/top_50_sudo_commands b/lib/resources/linelists/top_50_sudo_commands deleted file mode 100644 index ec52718c8..000000000 --- a/lib/resources/linelists/top_50_sudo_commands +++ /dev/null @@ -1,50 +0,0 @@ -sudo apt-get update -sudo apt-get install packagename -sudo apt-get remove packagename -sudo systemctl restart servicename -sudo systemctl stop servicename -sudo systemctl start servicename -sudo ufw enable/disable -sudo ufw allow/deny port-number -sudo useradd -m -s /bin/bash username -sudo usermod -aG groupname username -sudo groupadd groupname -sudo userdel username -sudo chown -R username:groupname /path/to/folder -sudo chmod -R 755 /path/to/folder -sudo systemctl enable/disable servicename -sudo systemctl status servicename -sudo apt-get upgrade -sudo apt-get dist-upgrade -sudo apt-get autoremove -sudo apt-get clean -sudo add-apt-repository ppa:repositoryname -sudo sed -i 's/oldstring/newstring/g' /path/to/file -sudo find /path/to/search/ -type f -exec rm {} ; -sudo tar -xvf archive.tar -C /path/to/extract/ -sudo tail -f /var/log/messages -sudo chmod 700 /path/to/file -sudo chgrp groupname /path/to/file -sudo passwd username -sudo chsh -s /bin/bash username -sudo ln -s /path/to/file /path/to/link -sudo mount /dev/sdb1 /mnt/usb -sudo umount /mnt/usb -sudo chattr +i /path/to/file -sudo crontab -e -sudo dpkg -i packagename.deb -sudo dpkg --configure -a -sudo service ssh restart -sudo service apache2 restart -sudo service mysql restart -sudo service postfix restart -sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys keynumber -sudo apt-get install -y packagename -sudo apt-get install -f -sudo apt-get install build-essential -sudo apt-get install python3-pip -sudo usermod -L username -sudo usermod -U username -sudo systemctl reload servicename -sudo systemctl mask/unmask servicename -sudo visudo diff --git a/lib/resources/linelists/top_90_linux_commands b/lib/resources/linelists/top_90_linux_commands deleted file mode 100644 index 94f0364fd..000000000 --- a/lib/resources/linelists/top_90_linux_commands +++ /dev/null @@ -1,88 +0,0 @@ -locate filename -chgrp groupname filename -chroot /path/to/chroot/ -scp /path/to/source user@destination:/path/to/destination/ -service servicename start/stop/restart -curl -I http://example.com -useradd username -usermod -aG groupname username -groupadd groupname -passwd username -whoami -which commandname -uptime -touch filename -tail -n 100 /var/log/messages -su username -stat filename -sed -n '10,20p' file.txt -sed -i '1d' file.txt -tar -cvf archive.tar /path/to/folder/ -tar -xvf archive.tar -C /path/to/extract/ -traceroute google.com -uname -a -uptime -p -userdel username -wc -l file.txt -watch -n 1 command -wget http://example.com/file -who -zip -r archive.zip /path/to/folder/ -unzip archive.zip -d /path/to/extract/ -rsync -avz /path/to/source/ user@destination:/path/to/destination/ -ps -ef | grep "process name" -netstat -antp | grep "port number" -ifconfig -a -hostnamectl set-hostname newhostname -find /path/to/search/ -type d -exec chmod 755 {} ; -dig example.com -curl -o filename http://example.com/file -cat /proc/cpuinfo -awk '{print $2}' /proc/meminfo -adduser username groupname -apt-get update -apt-get install packagename -apt-get remove packagename -df -h -du -sh * -free -m -head -n 10 file.txt -tail -n 10 file.txt -grep -i "search term" file.txt -lsof -i tcp:port-number -killall processname -hostname -i -mount -t cifs //192.168.1.100/share /mnt/cifs -o username=user,password=password -nc -l port-number -nl file.txt -passwd root -ping -c 5 8.8.8.8 -ps -aux | grep "process name" -rmdir dirname -sed -i '/search term/d' file.txt -ssh-keygen -t rsa -b 4096 -ssh-copy-id user@hostname -systemctl status servicename -systemctl start/stop/restart servicename -tar -czvf archive.tar.gz /path/to/folder -tar -xzvf archive.tar.gz -C /path/to/extract/ -touch -d "1 day ago" file.txt -uptime -s -uname -r -uniq file.txt -usermod -L username -usermod -U username -visudo -whois example.com -xargs -I {} mv {} /path/to/destination/ < filelist.txt -zip -r archive.zip /path -locate filename -chgrp groupname filename -chroot /path/to/chroot/ -scp /path/to/source user@destination:/path/to/destination/ -service servicename start/stop/restart -curl -I http://example.com -useradd username -usermod -aG groupname username -groupadd groupname -passwd username diff --git a/lib/resources/sqlite/places.sqlite.blank b/lib/resources/sqlite/places.sqlite.blank new file mode 100644 index 000000000..1c78f793e Binary files /dev/null and b/lib/resources/sqlite/places.sqlite.blank differ diff --git a/modules/generators/challenges/hidden_zip_in_image_file/secgen_local/local.rb b/modules/generators/challenges/hidden_zip_in_image_file/secgen_local/local.rb deleted file mode 100644 index 1dc27837e..000000000 --- a/modules/generators/challenges/hidden_zip_in_image_file/secgen_local/local.rb +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/ruby -require_relative '../../../../../lib/objects/local_string_encoder.rb' - -class HideZipInImgChallenge < StringEncoder - attr_accessor :base64_image - attr_accessor :zip_file - - def initialize - super - self.module_name = 'Hidden Zip in Image File Challenge Generator' - self.base64_image = '' - self.zip_file = '' - end - - def encode_all - # Decode the base64 image data into raw contents - raw_image_contents = Base64.strict_decode64(self.base64_image) - raw_zip_contents = Base64.strict_decode64(self.zip_file) - - # Append data to the end of the file - contents_with_data = raw_image_contents + raw_zip_contents - - # Re-encode in base64 and return - self.outputs << Base64.strict_encode64(contents_with_data) - end - - def get_options_array - super + [['--base64_image', GetoptLong::REQUIRED_ARGUMENT], - ['--zip_file', GetoptLong::REQUIRED_ARGUMENT]] - end - - def process_options(opt, arg) - super - case opt - when '--base64_image' - self.base64_image << arg; - when '--zip_file' - self.zip_file << arg; - end - end - - def encoding_print_string - 'base64_image: ' + print_string_padding + - 'zip_file: ' + self.zip_file.to_s - end -end - -HideZipInImgChallenge.new.run \ No newline at end of file diff --git a/modules/generators/compression/zip/secgen_local/local.rb b/modules/generators/compression/zip/secgen_local/local.rb index f00a303d7..ae1ca570a 100644 --- a/modules/generators/compression/zip/secgen_local/local.rb +++ b/modules/generators/compression/zip/secgen_local/local.rb @@ -2,6 +2,7 @@ require_relative '../../../../../lib/objects/local_string_encoder.rb' require 'rubygems' require 'zip' +require 'securerandom' class ZipGenerator < StringEncoder attr_accessor :file_name @@ -14,11 +15,12 @@ class ZipGenerator < StringEncoder self.file_name = '' self.strings_to_leak = [] self.password = '' - Dir.mkdir '../tmp/' unless Dir.exists? '../tmp/' end def encode_all - zip_file_path = GENERATORS_DIR + 'compression/zip/tmp/archive' + Time.new.strftime("%Y%m%d_%H%M%S") + '.zip' + zip_file_path = "/tmp/zip#{SecureRandom.hex(6)}.zip" + + # zip_file_path = GENERATORS_DIR + 'compression/zip/tmp/archive' + Time.new.strftime("%Y%m%d_%H%M%S") + '.zip' file_contents = '' data = self.strings_to_leak.join("\n") diff --git a/modules/generators/compression/zip/secgen_metadata.xml b/modules/generators/compression/zip/secgen_metadata.xml index b6bfe8b48..4052b24cb 100644 --- a/modules/generators/compression/zip/secgen_metadata.xml +++ b/modules/generators/compression/zip/secgen_metadata.xml @@ -31,4 +31,4 @@ base64_zip_file - \ No newline at end of file + diff --git a/modules/generators/content/bash_history/secgen_local/local.rb b/modules/generators/content/bash_history/secgen_local/local.rb index b4dea553f..86494bdba 100644 --- a/modules/generators/content/bash_history/secgen_local/local.rb +++ b/modules/generators/content/bash_history/secgen_local/local.rb @@ -1,13 +1,9 @@ #!/usr/bin/ruby require_relative '../../../../../lib/objects/local_string_generator.rb' -require 'erb' +# require 'erb' require 'fileutils' class BashHistoryGenerator < StringGenerator - attr_accessor :command_sample - attr_accessor :sudo_sample attr_accessor :password_sample - LOCAL_DIR = File.expand_path('../../',__FILE__) - TEMPLATE_PATH = "#{LOCAL_DIR}/templates/bash_history.md.erb" def initialize super @@ -17,7 +13,7 @@ class BashHistoryGenerator < StringGenerator def get_options_array super + [['--password', GetoptLong::OPTIONAL_ARGUMENT]] end - + def process_options(opt, arg) super case opt @@ -27,35 +23,22 @@ class BashHistoryGenerator < StringGenerator end def generate - sudo_array = File.readlines('../../../../../lib/resources/linelists/top_50_sudo_commands') - command_array = File.readlines('../../../../../lib/resources/linelists/top_90_linux_commands') - if self.password_sample != '' - self.sudo_sample = sudo_array.sample(5) - self.command_sample = command_array.sample(20) - counter = 4 - sudo_count = 0 - while counter != 20 - randInt = rand(sudo_sample.length) - command_sample.insert(randInt, sudo_sample[randInt]) - if sudo_count == 0 - command_sample.insert(5, self.password_sample) - sudo_count += 1 - end - counter += 4 + sudo_array = File.readlines("#{LINELISTS_DIR}/sudo_commands") + command_array = File.readlines("#{LINELISTS_DIR}/linux_commands") + + # choose some random command samples + sudo_sample = sudo_array.sample(5) + command_sample = command_array.sample(20) + # if we have a password to leak, we can put it after a sudo command + unless self.password_sample.empty? + sudo_sample[0] += "#{self.password_sample}\n" end - else - self.command_sample = command_array.sample(30) - end - template_out = ERB.new(File.read(TEMPLATE_PATH), 0, '<>-') - self.outputs << template_out.result(self.get_binding) + # copy to a flat array + commands = [*sudo_sample, *command_sample] + # output a shuffled array joined with new lines + self.outputs << commands.shuffle.join end - # Returns binding for erb files (access to variables in this classes scope) - # @return binding - def get_binding - binding - end end BashHistoryGenerator.new.run - diff --git a/modules/generators/content/bash_history/secgen_metadata.xml b/modules/generators/content/bash_history/secgen_metadata.xml index 00122edf3..376d36137 100644 --- a/modules/generators/content/bash_history/secgen_metadata.xml +++ b/modules/generators/content/bash_history/secgen_metadata.xml @@ -4,10 +4,11 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.github/cliffe/SecGen/generator"> - Password List File Generator + Bash History Generator Jack Biggs + Z. Cliffe Schreuders MIT - Creates a bash history file in which sudo password is leaked. + Creates a bash history file in which a sudo password is leaked. string_generator local_calculation @@ -16,4 +17,12 @@ password generated_strings + + + data acquisition + + + Command history + + diff --git a/modules/generators/content/bash_history/templates/bash_history.md.erb b/modules/generators/content/bash_history/templates/bash_history.md.erb deleted file mode 100644 index db49e5d2f..000000000 --- a/modules/generators/content/bash_history/templates/bash_history.md.erb +++ /dev/null @@ -1,8 +0,0 @@ -<% - command_sample.each { |cmd| -%> - <%= cmd %> - <% - } -%> - diff --git a/modules/generators/challenges/exif/exif.pp b/modules/generators/image/exif/exif.pp similarity index 100% rename from modules/generators/challenges/exif/exif.pp rename to modules/generators/image/exif/exif.pp diff --git a/modules/generators/challenges/exif/manifests/.no_puppet b/modules/generators/image/exif/manifests/.no_puppet similarity index 100% rename from modules/generators/challenges/exif/manifests/.no_puppet rename to modules/generators/image/exif/manifests/.no_puppet diff --git a/modules/generators/challenges/exif/secgen_local/local.rb b/modules/generators/image/exif/secgen_local/local.rb similarity index 88% rename from modules/generators/challenges/exif/secgen_local/local.rb rename to modules/generators/image/exif/secgen_local/local.rb index b8fd99f64..ac192db6d 100644 --- a/modules/generators/challenges/exif/secgen_local/local.rb +++ b/modules/generators/image/exif/secgen_local/local.rb @@ -1,6 +1,7 @@ #!/usr/bin/ruby require_relative '../../../../../lib/objects/local_string_encoder.rb' require 'mini_exiftool_vendored' +require 'securerandom' class ExifModifiedGenerator < StringEncoder attr_accessor :base64_image @@ -20,14 +21,15 @@ class ExifModifiedGenerator < StringEncoder raw_image_contents = Base64.strict_decode64(self.base64_image) # Store the raw_image_contents as a temporary image file called 'tmp.jpg' - tmp_file_path = GENERATORS_DIR + 'challenges/exif/secgen_local/tmp.jpg' + tmp_file_path = "/tmp/#{SecureRandom.hex(6)}.jpg" File.open(tmp_file_path, 'wb') { |f| f.write(raw_image_contents) } image = MiniExiftool.new(tmp_file_path) - image[self.exif_field] = self.strings_to_leak[0] + image[self.exif_field] = self.strings_to_leak.join('-') image.save self.outputs << Base64.strict_encode64(File.binread(tmp_file_path)) + File.delete(tmp_file_path) end def get_options_array @@ -55,4 +57,4 @@ class ExifModifiedGenerator < StringEncoder end end -ExifModifiedGenerator.new.run \ No newline at end of file +ExifModifiedGenerator.new.run diff --git a/modules/generators/challenges/exif/secgen_metadata.xml b/modules/generators/image/exif/secgen_metadata.xml similarity index 86% rename from modules/generators/challenges/exif/secgen_metadata.xml rename to modules/generators/image/exif/secgen_metadata.xml index 4049cfa32..d83e96fb0 100644 --- a/modules/generators/challenges/exif/secgen_metadata.xml +++ b/modules/generators/image/exif/secgen_metadata.xml @@ -37,11 +37,9 @@ generated_image - - METADATA + + artifact analysis + Encoding and alternative data formats - - METADATA - - + diff --git a/modules/generators/challenges/hidden_strings_in_image_file/hidden_strings_in_image_file.pp b/modules/generators/image/hidden_data_in_image_file/hidden_data_in_image_file.pp similarity index 100% rename from modules/generators/challenges/hidden_strings_in_image_file/hidden_strings_in_image_file.pp rename to modules/generators/image/hidden_data_in_image_file/hidden_data_in_image_file.pp diff --git a/modules/generators/challenges/hidden_strings_in_image_file/manifests/.no_puppet b/modules/generators/image/hidden_data_in_image_file/manifests/.no_puppet similarity index 100% rename from modules/generators/challenges/hidden_strings_in_image_file/manifests/.no_puppet rename to modules/generators/image/hidden_data_in_image_file/manifests/.no_puppet diff --git a/modules/generators/challenges/hidden_strings_in_image_file/secgen_local/local.rb b/modules/generators/image/hidden_data_in_image_file/secgen_local/local.rb similarity index 55% rename from modules/generators/challenges/hidden_strings_in_image_file/secgen_local/local.rb rename to modules/generators/image/hidden_data_in_image_file/secgen_local/local.rb index 763d44b70..5c16ac66d 100644 --- a/modules/generators/challenges/hidden_strings_in_image_file/secgen_local/local.rb +++ b/modules/generators/image/hidden_data_in_image_file/secgen_local/local.rb @@ -4,20 +4,28 @@ require_relative '../../../../../lib/objects/local_string_encoder.rb' class HideStringsInImgChallenge < StringEncoder attr_accessor :base64_image attr_accessor :strings_to_leak + attr_accessor :binary_base64_to_leak def initialize super self.module_name = 'Hidden Strings in Image File Challenge Generator' self.base64_image = '' self.strings_to_leak = [] + self.binary_base64_to_leak = '' end def encode_all # Decode the base64 image data into raw contents raw_image_contents = Base64.strict_decode64(self.base64_image) - + contents_with_data = '' # Append data to the end of the file - contents_with_data = raw_image_contents + strings_to_leak.join + unless self.strings_to_leak.empty? + contents_with_data += raw_image_contents.force_encoding("UTF-8") + self.strings_to_leak.join.force_encoding("UTF-8") + end + unless binary_base64_to_leak.empty? + contents_with_data += raw_image_contents.force_encoding("UTF-8") + self.strings_to_leak.join.force_encoding("UTF-8") + contents_with_data += Base64.strict_decode64(self.binary_base64_to_leak).force_encoding("UTF-8") + end # Re-encode in base64 and return self.outputs << Base64.strict_encode64(contents_with_data) @@ -25,7 +33,8 @@ class HideStringsInImgChallenge < StringEncoder def get_options_array super + [['--base64_image', GetoptLong::REQUIRED_ARGUMENT], - ['--strings_to_leak', GetoptLong::REQUIRED_ARGUMENT]] + ['--strings_to_leak', GetoptLong::OPTIONAL_ARGUMENT], + ['--binary_base64_to_leak', GetoptLong::OPTIONAL_ARGUMENT]] end def process_options(opt, arg) @@ -35,13 +44,16 @@ class HideStringsInImgChallenge < StringEncoder self.base64_image << arg; when '--strings_to_leak' self.strings_to_leak << arg; + when '--binary_base64_to_leak' + self.binary_base64_to_leak << arg; end end def encoding_print_string 'base64_image: ' + print_string_padding + 'strings_to_leak: ' + self.strings_to_leak.to_s + 'binary_base64_to_leak: ' + self.binary_base64_to_leak.to_s end end -HideStringsInImgChallenge.new.run \ No newline at end of file +HideStringsInImgChallenge.new.run diff --git a/modules/generators/challenges/hidden_strings_in_image_file/secgen_metadata.xml b/modules/generators/image/hidden_data_in_image_file/secgen_metadata.xml similarity index 60% rename from modules/generators/challenges/hidden_strings_in_image_file/secgen_metadata.xml rename to modules/generators/image/hidden_data_in_image_file/secgen_metadata.xml index 635c7f384..e4388bc3e 100644 --- a/modules/generators/challenges/hidden_strings_in_image_file/secgen_metadata.xml +++ b/modules/generators/image/hidden_data_in_image_file/secgen_metadata.xml @@ -5,9 +5,10 @@ xsi:schemaLocation="http://www.github/cliffe/SecGen/generator"> Hidden Strings in Image File Thomas Shaw + Z. Cliffe Schreuders MIT - Makes use of a random image, encodes a string_to_leak (flag) then inserts the data to decode into the end - of the image file in ascii. + Makes use of a random image, encodes a string_to_leak (flag) then inserts the strings to decode into the end + of the image file in ascii, followed by any binary data (such as a zip file). hidden_data_in_image_file @@ -18,10 +19,12 @@ windows Inspect the file's raw hex. Example tools: hexedit/hexeditor - Look at the end of the file for something to decode. + Look at the end of the file for something to extract or decode. base64_image strings_to_leak + + binary_base64_to_leak @@ -35,13 +38,19 @@ - generated_image + base64_encoded_image - - STEGANOGRAPHY + + artifact analysis + Steganography + Encoding and alternative data formats + data recovery and file content carving + storage forensics + data abstraction layers + data acquisition + STEGANOGRAPHY - diff --git a/modules/generators/challenges/hidden_zip_in_image_file/manifests/.no_puppet b/modules/generators/image/steghide/manifests/.no_puppet similarity index 100% rename from modules/generators/challenges/hidden_zip_in_image_file/manifests/.no_puppet rename to modules/generators/image/steghide/manifests/.no_puppet diff --git a/modules/generators/image/steghide/secgen_local/local.rb b/modules/generators/image/steghide/secgen_local/local.rb new file mode 100644 index 000000000..77e810d35 --- /dev/null +++ b/modules/generators/image/steghide/secgen_local/local.rb @@ -0,0 +1,76 @@ +#!/usr/bin/ruby +require_relative '../../../../../lib/objects/local_string_encoder.rb' +require_relative '../../../../../lib/helpers/print.rb' +require 'mini_exiftool_vendored' +require 'securerandom' + +class SteghideGenerator < StringEncoder + attr_accessor :base64_image + attr_accessor :strings_to_leak + attr_accessor :exif_field + attr_accessor :password + + def initialize + super + self.module_name = 'Steghide Image Generator' + self.base64_image = '' + self.password = '' + self.strings_to_leak = [] + self.exif_field = '' + end + + def encode_all + # Decode the base64 image data into raw contents + raw_image_contents = Base64.strict_decode64(self.base64_image) + + # Store the raw_image_contents as a temporary image file called 'tmp.jpg' + tmp_file_path_image = "/tmp/#{SecureRandom.hex(6)}.jpg" + tmp_file_path_leak = "/tmp/#{SecureRandom.hex(6)}.txt" + File.open(tmp_file_path_image, 'wb') { |f| f.write(raw_image_contents) } + File.open(tmp_file_path_leak, 'w') { |f| f.write(self.strings_to_leak.join) } + + returnstr = `steghide embed -cf #{tmp_file_path_image} -ef #{tmp_file_path_leak} -p #{self.password}` + + Print.local_verbose returnstr + + unless $?.exitstatus == 0 + Print.err "Steghide failed to run. Please make sure it's installed (apt-get install steghide)" + exit(1) + end + self.outputs << Base64.strict_encode64(File.binread(tmp_file_path_image)) + + File.delete(tmp_file_path_image) + File.delete(tmp_file_path_leak) + + end + + def get_options_array + super + [['--base64_image', GetoptLong::REQUIRED_ARGUMENT], + ['--strings_to_leak', GetoptLong::REQUIRED_ARGUMENT], + ['--password', GetoptLong::REQUIRED_ARGUMENT], + ['--exif_field', GetoptLong::REQUIRED_ARGUMENT]] + end + + def process_options(opt, arg) + super + case opt + when '--base64_image' + self.base64_image << arg; + when '--strings_to_leak' + self.strings_to_leak << arg; + when '--exif_field' + self.exif_field << arg; + when '--password' + self.password << arg; + end + end + + def encoding_print_string + 'base64_image: ' + print_string_padding + + 'strings_to_leak: ' + self.strings_to_leak.to_s + print_string_padding + + 'password: ' + self.password.to_s + print_string_padding + + 'exif_field: ' + self.exif_field.to_s + end +end + +SteghideGenerator.new.run diff --git a/modules/generators/challenges/hidden_zip_in_image_file/secgen_metadata.xml b/modules/generators/image/steghide/secgen_metadata.xml similarity index 50% rename from modules/generators/challenges/hidden_zip_in_image_file/secgen_metadata.xml rename to modules/generators/image/steghide/secgen_metadata.xml index 89b5234e0..84187921a 100644 --- a/modules/generators/challenges/hidden_zip_in_image_file/secgen_metadata.xml +++ b/modules/generators/image/steghide/secgen_metadata.xml @@ -3,45 +3,47 @@ - Hidden Zip in Image File + Image Steghide (using package) + Z. Cliffe Schreuders Thomas Shaw MIT - Makes use of a random image, encodes a string_to_leak (flag) then inserts the data to decode into the end - of the image file in ascii. - + Modifies an image's data to leak a string (password protected with a weak password). - hidden_zip_in_image_file image_generator image_challenge_generator local_calculation linux windows - Inspect the file's raw hex. Example tools: hexedit/hexeditor. Some data has been appended to the image with a - file signature of: \x50\x4b\x03\x04 ("PK..") + The image has a hidden message - Extract the ZIP file's raw hex into a new file. Starting from the signature to the end of file. Unzip the - file. - base64_image - zip_file + strings_to_leak - + - - + + + + + + generated_image - - STEGANOGRAPHY + + artifact analysis + Steganography + SEARCH FOR EVIDENCE + data acquisition + encryption concerns + STEGANOGRAPHY - diff --git a/modules/generators/challenges/hidden_zip_in_image_file/hidden_zip_in_image_file.pp b/modules/generators/image/steghide/steghide.pp similarity index 100% rename from modules/generators/challenges/hidden_zip_in_image_file/hidden_zip_in_image_file.pp rename to modules/generators/image/steghide/steghide.pp diff --git a/modules/generators/random/random_exif_string_field/secgen_local/local.rb b/modules/generators/random/random_exif_string_field/secgen_local/local.rb index 397d95010..b23ec4f11 100644 --- a/modules/generators/random/random_exif_string_field/secgen_local/local.rb +++ b/modules/generators/random/random_exif_string_field/secgen_local/local.rb @@ -9,10 +9,10 @@ class RandomExifStringField < StringGenerator def generate - fields = %w(title comment make) + fields = %w(title comment make UserComment) self.outputs << fields.sample.chomp end end -RandomExifStringField.new.run \ No newline at end of file +RandomExifStringField.new.run diff --git a/modules/generators/sqlite/firefox_places_history_bookmarks/firefox_places_history_bookmarks.pp b/modules/generators/sqlite/firefox_places_history_bookmarks/firefox_places_history_bookmarks.pp new file mode 100644 index 000000000..e69de29bb diff --git a/modules/generators/sqlite/firefox_places_history_bookmarks/manifests/.no_puppet b/modules/generators/sqlite/firefox_places_history_bookmarks/manifests/.no_puppet new file mode 100644 index 000000000..e69de29bb diff --git a/modules/generators/sqlite/firefox_places_history_bookmarks/secgen_local/local.rb b/modules/generators/sqlite/firefox_places_history_bookmarks/secgen_local/local.rb new file mode 100644 index 000000000..b6dff7d2f --- /dev/null +++ b/modules/generators/sqlite/firefox_places_history_bookmarks/secgen_local/local.rb @@ -0,0 +1,164 @@ +#!/usr/bin/ruby +require_relative '../../../../../lib/objects/local_string_generator.rb' +require 'sqlite3' +require 'securerandom' +require 'uri' +require 'base64' +require 'fileutils' + +class PlacesSqliteGenerator < StringGenerator + attr_accessor :strings_to_leak + + def initialize + super + self.module_name = 'Firefox History and Bookmarks Generator' + self.strings_to_leak = [] + end + + def get_options_array + super + [['--strings_to_leak', GetoptLong::REQUIRED_ARGUMENT]] + end + + def process_options(opt, arg) + super + case opt + when '--strings_to_leak' + self.strings_to_leak << arg; + end + end + + # -- Calculate url_hash -- + def rotate_left_5(value) + ((value << 5) | (value >> 27)) & 0xFFFFFFFF + end + + def add_to_hash(hash_value, value) + (0x9E3779B9 * (rotate_left_5(hash_value) ^ value)) & 0xFFFFFFFF + end + + def hash_simple(url) + hash_value = 0 + url.each_byte { |char| hash_value = add_to_hash(hash_value, char) } + hash_value + end + + def url_hash(url) + prefix, _ = url.split(':', 2) + ((hash_simple(prefix) & 0x0000FFFF) << 32) + hash_simple(url) + end + # ---- + + def insert_origin(db, url, frecency) + uri = URI.parse(url) + prefix = "#{uri.scheme}://" + host = uri.host + origin_id = db.execute("SELECT id FROM moz_origins WHERE prefix = ? AND host = ?", [prefix, host]).first + if origin_id + origin_id = origin_id.first + db.execute("UPDATE moz_origins SET frecency = ? WHERE id = ?", [frecency, origin_id]) + else + db.execute("INSERT INTO moz_origins (prefix, host, frecency) VALUES (?, ?, ?)", [prefix, host, frecency]) + origin_id = db.last_insert_row_id + end + origin_id + end + + def add_place (url, title, db, bookmark, date_added) + uri = URI.parse(url) + rev_host = uri.host.reverse + guid = SecureRandom.hex(6).to_s + is_typed = 1 + frecency = 100 + foreign_count = 1 + origin_id = insert_origin(db, url, frecency) + + # Insert the new URL into the moz_places table + url_hash = url_hash(url) # Calculate the URL hash + + db.execute("INSERT OR REPLACE INTO moz_places (url, title, guid, url_hash, typed, frecency, last_visit_date, rev_host, origin_id, foreign_count) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + [url, title, guid, url_hash, is_typed, frecency, date_added, rev_host, origin_id, foreign_count]) + db.execute("UPDATE moz_places SET visit_count = COALESCE((SELECT visit_count FROM moz_places WHERE url = ?), 0) + 1 WHERE url = ?", [url, url]) + place_id = db.last_insert_row_id + + # Insert a new bookmark into the moz_bookmarks table + bookmark_title = title + parent_id = 2 # ID of the folder where the bookmark should be added + last_modified = date_added + bookmark_guid = SecureRandom.hex(6).to_s + + db.execute("INSERT INTO moz_bookmarks (type, fk, parent, position, title, dateAdded, lastModified, guid) + VALUES (1, ?, ?, (SELECT COALESCE(MAX(position), 0) + 1 FROM moz_bookmarks WHERE parent = ?), ?, ?, ?, ?)", + [place_id, parent_id, parent_id, bookmark_title, date_added, date_added, bookmark_guid]) + + db.execute("INSERT INTO moz_historyvisits (place_id, visit_date, visit_type, session, from_visit) VALUES (?, ?, 1, 0, 1)", [place_id, date_added]) + + # Insert a new entry into the moz_inputhistory table + db.execute("INSERT INTO moz_inputhistory (place_id, input, use_count) VALUES (?, ?, 1)", [place_id, url]) + end + + def generate + # make a fresh tmp copy of the sqlite database + rand_file_name = "/tmp/places#{SecureRandom.hex(6)}.sqlite" + FileUtils.cp("#{SQLITE_DIR}/places.sqlite.blank", rand_file_name) + + # Open the places.sqlite file + db = SQLite3::Database.new(rand_file_name) + + random_interest = Dir.glob(File.join("#{INTERESTS_DIR}/benign/", '*')).select { |f| File.directory? f }.sample + + # malicious_interest = Dir.glob(File.join("#{INTERESTS_DIR}/malicious/", '*')).select { |f| File.directory? f }.sample + malicious_interest = "#{INTERESTS_DIR}/malicious/world_domination" + + website_lines = File.readlines("#{random_interest}/websites").map(&:strip) + search_lines = File.readlines("#{random_interest}/search_phrases").map(&:strip) + + website_mal_lines = File.readlines("#{malicious_interest}/websites").map(&:strip) + search_mal_lines = File.readlines("#{malicious_interest}/search_phrases").map(&:strip) + + start_date = Date.new(2022, 9, 24) + end_date = Date.new(2023, 2, 2) + malicious_date = rand(start_date..end_date) + + (start_date..end_date).each do |date| + rand(1..10).times do # a random number of urls per day + if date == malicious_date # one day where it's all malicious + if rand < 0.25 # 25% of the time it's a google search + random_line = search_mal_lines.sample + url = "https://www.google.com/search?q=#{random_line}" + title = "#{random_line} - Google search - #{Base64.encode64(random_line)}" + else + random_line = website_mal_lines.sample + title_raw, url = random_line.split(" - ") + title = "#{title_raw} - #{Base64.encode64(strings_to_leak.to_s)}" + end + else + if rand < 0.25 # 25% of the time it's a google search + random_line = search_lines.sample + url = "https://www.google.com/search?q=#{random_line}" + title = "#{random_line} - Google search - #{Base64.encode64(random_line)}" + else + random_line = website_lines.sample + title_raw, url = random_line.split(" - ") + title = "#{title_raw} - #{Base64.encode64(title_raw)}" + end + end + + # add a bookmark 10% of the time + bookmark = rand < 0.1 + # Calculate a random offset between 0 and time_offset seconds + time_offset = 60 * 60 * 24 # 1 day in microseconds + date_added = (date.to_time.to_i + rand(time_offset)) * 1000000 # Convert to microseconds since epoch + add_place(url, title, db, bookmark, date_added) + end + + end + db.close + # Re-encode in base64 and return + self.outputs << Base64.strict_encode64(File.read(rand_file_name)) + File.delete(rand_file_name) + end + +end + +PlacesSqliteGenerator.new.run diff --git a/modules/generators/sqlite/firefox_places_history_bookmarks/secgen_metadata.xml b/modules/generators/sqlite/firefox_places_history_bookmarks/secgen_metadata.xml new file mode 100644 index 000000000..3a234a7fa --- /dev/null +++ b/modules/generators/sqlite/firefox_places_history_bookmarks/secgen_metadata.xml @@ -0,0 +1,44 @@ + + + + Firefox places.sqlite: history and bookmarks + Z. Cliffe Schreuders + MIT + Generates a places.sqlite file, with months of randomly generated history and bookmarks, + based on a benign interest (such as science), and a small amount of malicious interests + (such as world domination or hacking). strings_to_leak is stored with the malicious. + + + firefox_history + sqlite_data + local_calculation + linux + windows + + Look through the web history (sqlite database) for evidence of something malicious + The data is stored encoded alongside the malicious items. + + strings_to_leak + + + + + + generated_sqlite + + + application artifacts + data acquisition + + + APPLICATION ARTIFACTS + web browsers + url history + SEARCH FOR EVIDENCE + URL HISTORY + Database analysis + + + diff --git a/modules/utilities/unix/audit_tools/stego_tools/manifests/install.pp b/modules/utilities/unix/audit_tools/stego_tools/manifests/install.pp new file mode 100644 index 000000000..64acbb26a --- /dev/null +++ b/modules/utilities/unix/audit_tools/stego_tools/manifests/install.pp @@ -0,0 +1,3 @@ +class stego_tools::install{ + ensure_packages(["exif", "exiftool", "steghide"]) +} diff --git a/modules/utilities/unix/audit_tools/stego_tools/secgen_metadata.xml b/modules/utilities/unix/audit_tools/stego_tools/secgen_metadata.xml new file mode 100644 index 000000000..27a2af1df --- /dev/null +++ b/modules/utilities/unix/audit_tools/stego_tools/secgen_metadata.xml @@ -0,0 +1,14 @@ + + + + Stego tools + Z. Cliffe Schreuders + Apache v2 + Installs a collection of stego tools for forensics and image processing + + audit_tools + linux + + diff --git a/modules/utilities/unix/audit_tools/stego_tools/stego_tools.pp b/modules/utilities/unix/audit_tools/stego_tools/stego_tools.pp new file mode 100644 index 000000000..9b0ebae3b --- /dev/null +++ b/modules/utilities/unix/audit_tools/stego_tools/stego_tools.pp @@ -0,0 +1 @@ +include stego_tools::install diff --git a/modules/utilities/unix/system/leak_to_file/manifests/init.pp b/modules/utilities/unix/system/leak_to_file/manifests/init.pp index fd031dfdd..10f4d2115 100644 --- a/modules/utilities/unix/system/leak_to_file/manifests/init.pp +++ b/modules/utilities/unix/system/leak_to_file/manifests/init.pp @@ -20,4 +20,4 @@ class leak_to_file::init { owner => $username, group => $username, } -} \ No newline at end of file +} diff --git a/modules/vulnerabilities/unix/system/forensic_trash_deleted_files/forensic_trash_deleted_files.pp b/modules/vulnerabilities/unix/system/forensic_trash_deleted_files/forensic_trash_deleted_files.pp new file mode 100644 index 000000000..33bfb8aa9 --- /dev/null +++ b/modules/vulnerabilities/unix/system/forensic_trash_deleted_files/forensic_trash_deleted_files.pp @@ -0,0 +1 @@ +require forensic_trash_deleted_files::init diff --git a/modules/vulnerabilities/unix/system/forensic_trash_deleted_files/manifests/init.pp b/modules/vulnerabilities/unix/system/forensic_trash_deleted_files/manifests/init.pp new file mode 100644 index 000000000..a925b3059 --- /dev/null +++ b/modules/vulnerabilities/unix/system/forensic_trash_deleted_files/manifests/init.pp @@ -0,0 +1,60 @@ +class forensic_trash_deleted_files::init { + $secgen_parameters = secgen_functions::get_parameters($::base64_inputs_file) + + $leaked_filenames = $secgen_parameters['leaked_filenames'] + $strings_to_leak = $secgen_parameters['strings_to_leak'] + + # filenames for the base64 encoded content (filenames themselves shouldn't be encoded) + $leaked_base64_filenames = $secgen_parameters['leaked_base64_filenames'] + $base64_files = $secgen_parameters['binary_base64_to_leak'] + $deletion_date = strftime('%Y-%m-%dT%H:%M:%S') + + $account = parsejson($secgen_parameters['account'][0]) + + if $account and $account != '' { + $username = $account['username'] + $storage_directory = "/home/$username/.local/share/Trash/" + } else { + fail('The "accounts" parameter is required for forensic_trash_deleted_files.') + } + + # create the directory tree + exec { "$storage_directory/files/ mkdir": + path => ['/bin', '/usr/bin', '/usr/local/bin', '/sbin', '/usr/sbin'], + command => "mkdir -p $storage_directory/files/; mkdir -p $storage_directory/info/; chown $username /home/$username/.local/share/ -R", + provider => shell, + } + $leaked_filenames.each |$index, $leaked_filename| { + $string_to_leak = $strings_to_leak[$index] + + file { "$storage_directory/files/$leaked_filename": + ensure => present, + owner => $username, + mode => '700', + content => $string_to_leak + } -> + file { "$storage_directory/info/$leaked_filename.trashinfo": + ensure => present, + owner => $username, + mode => '700', + content => "[Trash Info]\nPath=/tmp/$leaked_filename\nDeletionDate=$deletion_date" + } + } + + $leaked_base64_filenames.each |$index, $leaked_base64_filename| { + $base64_file = $base64_files[$index] + + file { "$storage_directory/files/$leaked_base64_filename": + ensure => present, + owner => $username, + mode => '700', + content => base64('decode', $base64_file) + } -> + file { "$storage_directory/info/$leaked_base64_filename.trashinfo": + ensure => present, + owner => $username, + mode => '700', + content => "[Trash Info]\nPath=/tmp/$leaked_base64_filename\nDeletionDate=$deletion_date" + } + } +} diff --git a/modules/vulnerabilities/unix/system/forensic_trash_deleted_files/secgen_metadata.xml b/modules/vulnerabilities/unix/system/forensic_trash_deleted_files/secgen_metadata.xml new file mode 100644 index 000000000..2765b4b19 --- /dev/null +++ b/modules/vulnerabilities/unix/system/forensic_trash_deleted_files/secgen_metadata.xml @@ -0,0 +1,62 @@ + + + + Forensic Artifact: KDE/Linux Trash Deleted Files + Z. Cliffe Schreuders + MIT + Files that are deleted on a Linux desktop (KDE). + + + forensic_artifact + info_leak + local + linux + + + binary_base64_to_leak + leaked_filenames + strings_to_leak + accounts + leaked_base64_filenames + + + + + + + + + + + + + + + + + + + + + + + + Look for deleted files + Deleted files are stored in ~/.local/share/Trash + + + utilities/unix/system/.*/accounts + + + + artifact analysis + Deleted files + SEARCH FOR EVIDENCE + data recovery and file content carving + storage forensics + data abstraction layers + data acquisition + + diff --git a/scenarios/examples/vulnerability_examples/deleted_files_vulnerability.xml b/scenarios/examples/vulnerability_examples/deleted_files_vulnerability.xml new file mode 100644 index 000000000..e9489ff3c --- /dev/null +++ b/scenarios/examples/vulnerability_examples/deleted_files_vulnerability.xml @@ -0,0 +1,50 @@ + + + + + + + file_server + + + + 172.16.0.2 + + + + + + + + mythical_creatures + + + + + tiaspbiqe2r + + + true + + + + + + + + accounts + + + + + + accounts + + + + + + + diff --git a/scenarios/labs/forensics/trashed_evidence.xml b/scenarios/labs/forensics/trashed_evidence.xml new file mode 100644 index 000000000..cffbd1804 --- /dev/null +++ b/scenarios/labs/forensics/trashed_evidence.xml @@ -0,0 +1,200 @@ + + + + + Digital Forensics: Trashed Evidence + Z. Cliffe Schreuders + + # Introduction + Welcome to the world of digital forensics! + + In this CTF problem-based learning task, you will be given a virtual machine (VM) representing a seized PC from an operative who works for an evil organization bent on global domination. Your task is to analyze the contents of the VM to gather evidence and identify any evidence of malicious activities on the machine. + + In this task, you will be using digital forensics techniques to extract information from the VM, including files, and internet history, and and will involve retrieving deleted files and identifying and extracting data hidden using steganography. + + These tasks will require a combination of technical skills, creativity, and critical thinking. With your help we can discover more about their evil plans! + + The password to login is: tiaspbiqe2r + + ctf-lab + medium + + + artifact analysis + Steganography + Encoding and alternative data formats + Deleted files + SEARCH FOR EVIDENCE + METADATA + data recovery and file content carving + storage forensics + data abstraction layers + application artifacts + data acquisition + encryption concerns + Hidden files + + + APPLICATION ARTIFACTS + web browsers + url history + SEARCH FOR EVIDENCE + URL HISTORY + Command history + Database analysis + + + + METADATA + STEGANOGRAPHY + + + + + seized_desktop + + + + 172.16.0.2 + + + + + tiaspbiqe2r + + + + + + + + mythical_creatures + + + + + password + + + true + + + .they_will_never_find_us + + + Trash the evidence, hide in plain sight, and they will never uncover our plans. + + + + + + + + + + + accounts + + + + + + accounts + + + + .bash_history + + + + + + password + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Secret Kill Switch + + + + + + password + + + + + + + + + + + + + +