Compare commits
	
		
			159 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					f78dab50cb | ||
| 
						 | 
					edb324c3d9 | ||
| 
						 | 
					83bcca6e66 | ||
| 
						 | 
					a124518d78 | ||
| 
						 | 
					94bf630e29 | ||
| 
						 | 
					31bb33fd90 | ||
| 
						 | 
					4b680b9960 | ||
| 
						 | 
					8a8ab8cb18 | ||
| 
						 | 
					8146f5fd1b | ||
| 
						 | 
					425c585e47 | ||
| 
						 | 
					4f1578b2d6 | ||
| 
						 | 
					7969b343b0 | ||
| 
						 | 
					58cf1f4c8e | ||
| 
						 | 
					a5b87af862 | ||
| 
						 | 
					a0e592b934 | ||
| 
						 | 
					7eccc538bb | ||
| 
						 | 
					59daa8570a | ||
| 
						 | 
					3f52d318bc | ||
| 
						 | 
					11a7a0c934 | ||
| 
						 | 
					89f49b0e29 | ||
| 
						 | 
					72457cbf8e | ||
| 
						 | 
					c11ba27509 | ||
| 
						 | 
					8a611f9ba6 | ||
| 
						 | 
					4a73875e4d | ||
| 
						 | 
					d9d5e612ff | ||
| 
						 | 
					4d8599e4fc | ||
| 
						 | 
					59c7061d29 | ||
| 
						 | 
					996557c667 | ||
| 
						 | 
					519fb19a77 | ||
| 
						 | 
					36456cb151 | ||
| 
						 | 
					4ae87cc36c | ||
| 
						 | 
					b37df89fb1 | ||
| 
						 | 
					d18e7a751d | ||
| 
						 | 
					8d5ea98e50 | ||
| 
						 | 
					835dc08049 | ||
| 
						 | 
					62c9409fe9 | ||
| 
						 | 
					2374f578ed | ||
| 
						 | 
					34e2f033d8 | ||
| 
						 | 
					420825cacc | ||
| 
						 | 
					466ec93d8e | ||
| 
						 | 
					3f5bb6ab29 | ||
| 
						 | 
					ebe5f858c8 | ||
| 
						 | 
					9dd025437b | ||
| 
						 | 
					c0ebac305a | ||
| 
						 | 
					1f23ab7ba4 | ||
| 
						 | 
					ea3b63998d | ||
| 
						 | 
					3093426458 | ||
| 
						 | 
					37716feac7 | ||
| 
						 | 
					56b12c38d2 | ||
| 
						 | 
					749ead5d4a | ||
| 
						 | 
					3be50ab8da | ||
| 
						 | 
					649f4a6991 | ||
| 
						 | 
					0ff7641471 | ||
| 
						 | 
					1679bfae20 | ||
| 
						 | 
					45aa364436 | ||
| 
						 | 
					778516c4d9 | ||
| 
						 | 
					464d523c42 | ||
| 
						 | 
					0f6a1987d4 | ||
| 
						 | 
					20c6247ce5 | ||
| 
						 | 
					a10dd67e0f | ||
| 
						 | 
					5729ad6026 | ||
| 
						 | 
					9aa0d87a21 | ||
| 
						 | 
					fe3f1b9924 | ||
| 
						 | 
					00e52a88fa | ||
| 
						 | 
					5811dffe7a | ||
| 
						 | 
					7278982af4 | ||
| 
						 | 
					c17b4154ec | ||
| 
						 | 
					d6e74cce08 | ||
| 
						 | 
					3f80749241 | ||
| 
						 | 
					7f72b6ac69 | ||
| 
						 | 
					03e7b90b9f | ||
| 
						 | 
					7936b3533b | ||
| 
						 | 
					bd7e61d7cc | ||
| 
						 | 
					69214e0c22 | ||
| 
						 | 
					45bff26558 | ||
| 
						 | 
					b2e429ccc6 | ||
| 
						 | 
					76363c227b | ||
| 
						 | 
					d5a3e5c2c5 | ||
| 
						 | 
					2b02807ef0 | ||
| 
						 | 
					be659ae094 | ||
| 
						 | 
					b2c105adbc | ||
| 
						 | 
					c61f462948 | ||
| 
						 | 
					3ffed18e02 | ||
| 
						 | 
					f54e7257d1 | ||
| 
						 | 
					cc13b6a27c | ||
| 
						 | 
					8877db1979 | ||
| 
						 | 
					af58122c91 | ||
| 
						 | 
					b7ca5e5590 | ||
| 
						 | 
					69b6d875e6 | ||
| 
						 | 
					1fbd516b83 | ||
| 
						 | 
					dec5d3b165 | ||
| 
						 | 
					d5e2040cef | ||
| 
						 | 
					4326befdec | ||
| 
						 | 
					3d4a5d9917 | ||
| 
						 | 
					d770034788 | ||
| 
						 | 
					a977533c78 | ||
| 
						 | 
					c5e13dd5e4 | ||
| 
						 | 
					a8040fe4d2 | ||
| 
						 | 
					9e066008c3 | ||
| 
						 | 
					22c6601526 | ||
| 
						 | 
					425464fd76 | ||
| 
						 | 
					ccb0751ffd | ||
| 
						 | 
					f832de81b7 | ||
| 
						 | 
					8a37de0686 | ||
| 
						 | 
					836e4704f8 | ||
| 
						 | 
					3e5390309c | ||
| 
						 | 
					f8c0b38716 | ||
| 
						 | 
					65e6070e5f | ||
| 
						 | 
					7b78ebbc42 | ||
| 
						 | 
					03c3189c02 | ||
| 
						 | 
					4a34dfe0e9 | ||
| 
						 | 
					4cf9a723fe | ||
| 
						 | 
					bd1b135db3 | ||
| 
						 | 
					8c3b305149 | ||
| 
						 | 
					a3719038b8 | ||
| 
						 | 
					c68a261c0b | ||
| 
						 | 
					75fea79ac1 | ||
| 
						 | 
					eb9f9680ec | ||
| 
						 | 
					3634afdb81 | ||
| 
						 | 
					77b5df896a | ||
| 
						 | 
					b81f64058c | ||
| 
						 | 
					a8a90d7c63 | ||
| 
						 | 
					17bb575002 | ||
| 
						 | 
					abcea1a14d | ||
| 
						 | 
					10942f7c08 | ||
| 
						 | 
					87ee829e80 | ||
| 
						 | 
					fcc2c1e4c7 | ||
| 
						 | 
					269095d034 | ||
| 
						 | 
					40492ee00a | ||
| 
						 | 
					64cdd5aedc | ||
| 
						 | 
					3bb650cb77 | ||
| 
						 | 
					774544c975 | ||
| 
						 | 
					299805a726 | ||
| 
						 | 
					276363e793 | ||
| 
						 | 
					e750bd53fc | ||
| 
						 | 
					98fee7b5d2 | ||
| 
						 | 
					53aaea9fe2 | ||
| 
						 | 
					824fbb6368 | ||
| 
						 | 
					80566b91ab | ||
| 
						 | 
					533d05a1b5 | ||
| 
						 | 
					6a1fc4fade | ||
| 
						 | 
					9008d0ddf0 | ||
| 
						 | 
					583f4577bc | ||
| 
						 | 
					e5716d5092 | ||
| 
						 | 
					7192ae1287 | ||
| 
						 | 
					99c65eff48 | ||
| 
						 | 
					91df593566 | ||
| 
						 | 
					07aeaeb989 | ||
| 
						 | 
					cfeecdacd0 | ||
| 
						 | 
					564dfa8b62 | ||
| 
						 | 
					75dd6f2010 | ||
| 
						 | 
					e26fd0b759 | ||
| 
						 | 
					d630680a51 | ||
| 
						 | 
					1723c3f6a0 | ||
| 
						 | 
					53dd90302e | ||
| 
						 | 
					5c6e06b05e | ||
| 
						 | 
					cf6fb0c8a5 | ||
| 
						 | 
					e0e71b2eae | ||
| 
						 | 
					53f4a29fb1 | 
							
								
								
									
										3
									
								
								.github/FUNDING.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,3 @@
 | 
			
		||||
# These are supported funding model platforms
 | 
			
		||||
 | 
			
		||||
github: kotakanbe
 | 
			
		||||
@@ -1,3 +1,8 @@
 | 
			
		||||
---
 | 
			
		||||
name: Bug Report
 | 
			
		||||
labels: bug
 | 
			
		||||
about: If something isn't working as expected.
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
# What did you do? (required. The issue will be **closed** when not provided.)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,9 @@
 | 
			
		||||
---
 | 
			
		||||
name: Feature Request
 | 
			
		||||
labels: enhancement
 | 
			
		||||
about: I have a suggestion (and might want to implement myself)!
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
<!--
 | 
			
		||||
If this is a FEATURE REQUEST, request format does not matter!
 | 
			
		||||
-->
 | 
			
		||||
							
								
								
									
										10
									
								
								.github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,10 @@
 | 
			
		||||
---
 | 
			
		||||
name: Support Question
 | 
			
		||||
labels: question
 | 
			
		||||
about: If you have a question about Vuls.
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
<!--
 | 
			
		||||
If you have a trouble, feel free to ask.
 | 
			
		||||
Make sure you're not asking duplicate question by searching on the issues lists.
 | 
			
		||||
-->
 | 
			
		||||
							
								
								
									
										7
									
								
								.github/ISSUE_TEMPLATE/VULSREPO.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,7 @@
 | 
			
		||||
---
 | 
			
		||||
name: Vuls Repo
 | 
			
		||||
labels: vulsrepo
 | 
			
		||||
about: If something isn't working as expected.
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										28
									
								
								.github/workflows/golangci.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,28 @@
 | 
			
		||||
name: golangci-lint
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    tags:
 | 
			
		||||
      - v*
 | 
			
		||||
    branches:
 | 
			
		||||
      - master
 | 
			
		||||
  pull_request:
 | 
			
		||||
jobs:
 | 
			
		||||
  golangci:
 | 
			
		||||
    name: lint
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v2
 | 
			
		||||
      - name: golangci-lint
 | 
			
		||||
        uses: golangci/golangci-lint-action@v1
 | 
			
		||||
        with:
 | 
			
		||||
          # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
 | 
			
		||||
          version: v1.26
 | 
			
		||||
          
 | 
			
		||||
          # Optional: working directory, useful for monorepos
 | 
			
		||||
          # working-directory: somedir
 | 
			
		||||
 | 
			
		||||
          # Optional: golangci-lint command line arguments.
 | 
			
		||||
          # args: --issues-exit-code=0
 | 
			
		||||
 | 
			
		||||
          # Optional: show only new issues if it's a pull request. The default value is `false`.
 | 
			
		||||
          # only-new-issues: true
 | 
			
		||||
							
								
								
									
										31
									
								
								.github/workflows/goreleaser.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,31 @@
 | 
			
		||||
name: goreleaser
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    tags:
 | 
			
		||||
      - '*'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  goreleaser:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      -
 | 
			
		||||
        name: Checkout
 | 
			
		||||
        uses: actions/checkout@v2
 | 
			
		||||
      -
 | 
			
		||||
        name: Unshallow
 | 
			
		||||
        run: git fetch --prune --unshallow
 | 
			
		||||
      -
 | 
			
		||||
        name: Set up Go
 | 
			
		||||
        uses: actions/setup-go@v2
 | 
			
		||||
        with:
 | 
			
		||||
          go-version: 1.14
 | 
			
		||||
      -
 | 
			
		||||
        name: Run GoReleaser
 | 
			
		||||
        uses: goreleaser/goreleaser-action@v2
 | 
			
		||||
        with:
 | 
			
		||||
          version: latest
 | 
			
		||||
          args: release --rm-dist
 | 
			
		||||
        env:
 | 
			
		||||
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,21 @@
 | 
			
		||||
name: Test
 | 
			
		||||
 | 
			
		||||
on: [pull_request]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    name: Build
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
 | 
			
		||||
    - name: Set up Go 1.x
 | 
			
		||||
      uses: actions/setup-go@v2
 | 
			
		||||
      with:
 | 
			
		||||
        go-version: 1.14.x
 | 
			
		||||
      id: go
 | 
			
		||||
 | 
			
		||||
    - name: Check out code into the Go module directory
 | 
			
		||||
      uses: actions/checkout@v2
 | 
			
		||||
 | 
			
		||||
    - name: Test
 | 
			
		||||
      run: make test
 | 
			
		||||
							
								
								
									
										22
									
								
								.github/workflows/tidy.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,22 @@
 | 
			
		||||
name: go-mod-tidy-pr
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: "0 0 * * 1" # Weekly build
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  go-mod-tidy-pr:
 | 
			
		||||
    name: go-mod-tidy-pr
 | 
			
		||||
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v2
 | 
			
		||||
 | 
			
		||||
      - name: Run go-mod-tidy-pr
 | 
			
		||||
        uses: sue445/go-mod-tidy-pr@master
 | 
			
		||||
        with:
 | 
			
		||||
          github_token: ${{ secrets.GITHUB_TOKEN }}
 | 
			
		||||
          git_user_name: kotakanbe
 | 
			
		||||
          git_user_email: kotakanbe@gmail.com
 | 
			
		||||
          go_version: 1.14.x
 | 
			
		||||
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -13,3 +13,6 @@ log/
 | 
			
		||||
results/
 | 
			
		||||
*config.toml
 | 
			
		||||
!setup/docker/*
 | 
			
		||||
.DS_Store
 | 
			
		||||
dist/
 | 
			
		||||
.idea
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								.golangci.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,17 @@
 | 
			
		||||
name: golang-ci
 | 
			
		||||
 | 
			
		||||
linters-settings:
 | 
			
		||||
  errcheck:
 | 
			
		||||
    #exclude: /path/to/file.txt
 | 
			
		||||
 | 
			
		||||
linters:
 | 
			
		||||
  disable-all: true
 | 
			
		||||
  enable:
 | 
			
		||||
    - goimports
 | 
			
		||||
    - golint
 | 
			
		||||
    - govet
 | 
			
		||||
    - misspell
 | 
			
		||||
    - errcheck
 | 
			
		||||
    - staticcheck
 | 
			
		||||
    - prealloc
 | 
			
		||||
    - ineffassign
 | 
			
		||||
@@ -1,20 +1,66 @@
 | 
			
		||||
project_name: vuls
 | 
			
		||||
env:
 | 
			
		||||
  - GO111MODULE=on
 | 
			
		||||
release:
 | 
			
		||||
  github:
 | 
			
		||||
    owner: future-architect
 | 
			
		||||
    name: vuls
 | 
			
		||||
builds:
 | 
			
		||||
- goos:
 | 
			
		||||
- id: vuls
 | 
			
		||||
  goos:
 | 
			
		||||
  - linux
 | 
			
		||||
  goarch:
 | 
			
		||||
  - amd64
 | 
			
		||||
  main: .
 | 
			
		||||
  ldflags: -s -w -X main.version={{.Version}} -X main.revision={{.Commit}}
 | 
			
		||||
  flags:
 | 
			
		||||
      - -a
 | 
			
		||||
  ldflags: -s -w -X main.version={{.Version}} -X main.revision={{.Commit}} 
 | 
			
		||||
  binary: vuls
 | 
			
		||||
archive:
 | 
			
		||||
 | 
			
		||||
- id: trivy-to-vuls
 | 
			
		||||
  goos:
 | 
			
		||||
  - linux
 | 
			
		||||
  goarch:
 | 
			
		||||
  - amd64
 | 
			
		||||
  main: ./contrib/trivy/cmd/main.go
 | 
			
		||||
  binary: trivy-to-vuls
 | 
			
		||||
 | 
			
		||||
- id: future-vuls
 | 
			
		||||
  goos:
 | 
			
		||||
  - linux
 | 
			
		||||
  goarch:
 | 
			
		||||
  - amd64
 | 
			
		||||
  main: ./contrib/future-vuls/cmd/main.go
 | 
			
		||||
  binary: future-vuls
 | 
			
		||||
archives:
 | 
			
		||||
 | 
			
		||||
- id: vuls
 | 
			
		||||
  name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
 | 
			
		||||
  builds:
 | 
			
		||||
  - vuls
 | 
			
		||||
  format: tar.gz
 | 
			
		||||
  files:
 | 
			
		||||
  - LICENSE
 | 
			
		||||
  - NOTICE
 | 
			
		||||
  - README*
 | 
			
		||||
  - CHANGELOG.md
 | 
			
		||||
 | 
			
		||||
- id: trivy-to-vuls
 | 
			
		||||
  name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
 | 
			
		||||
  builds:
 | 
			
		||||
  - trivy-to-vuls
 | 
			
		||||
  format: tar.gz
 | 
			
		||||
  files:
 | 
			
		||||
  - LICENSE
 | 
			
		||||
  - NOTICE
 | 
			
		||||
  - README*
 | 
			
		||||
  - CHANGELOG.md
 | 
			
		||||
- id: future-vuls
 | 
			
		||||
  name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
 | 
			
		||||
  builds:
 | 
			
		||||
 | 
			
		||||
  - future-vuls
 | 
			
		||||
  format: tar.gz
 | 
			
		||||
  name_template: '{{ .Binary }}_{{.Version}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{
 | 
			
		||||
    .Arm }}{{ end }}'
 | 
			
		||||
  files:
 | 
			
		||||
  - LICENSE
 | 
			
		||||
  - NOTICE
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
language: go
 | 
			
		||||
 | 
			
		||||
go:
 | 
			
		||||
  - "1.11.x"
 | 
			
		||||
 | 
			
		||||
after_success:
 | 
			
		||||
  - test -n "$TRAVIS_TAG" && curl -sL https://git.io/goreleaser | bash
 | 
			
		||||
@@ -11,7 +11,7 @@ COPY . $GOPATH/src/$REPOSITORY
 | 
			
		||||
RUN cd $GOPATH/src/$REPOSITORY && make install
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
FROM alpine:3.7
 | 
			
		||||
FROM alpine:3.11
 | 
			
		||||
 | 
			
		||||
MAINTAINER hikachan sadayuki-matsuno
 | 
			
		||||
 | 
			
		||||
@@ -21,11 +21,12 @@ ENV WORKDIR /vuls
 | 
			
		||||
RUN apk add --no-cache \
 | 
			
		||||
        openssh-client \
 | 
			
		||||
        ca-certificates \
 | 
			
		||||
        git \
 | 
			
		||||
    && mkdir -p $WORKDIR $LOGDIR
 | 
			
		||||
 | 
			
		||||
COPY --from=builder /go/bin/vuls /usr/local/bin/
 | 
			
		||||
 | 
			
		||||
VOLUME [$WORKDIR, $LOGDIR]
 | 
			
		||||
VOLUME ["$WORKDIR", "$LOGDIR"]
 | 
			
		||||
WORKDIR $WORKDIR
 | 
			
		||||
ENV PWD $WORKDIR
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								GNUmakefile
									
									
									
									
									
								
							
							
						
						@@ -1,11 +1,9 @@
 | 
			
		||||
.PHONY: \
 | 
			
		||||
	dep \
 | 
			
		||||
	depup \
 | 
			
		||||
	build \
 | 
			
		||||
	install \
 | 
			
		||||
	all \
 | 
			
		||||
	vendor \
 | 
			
		||||
	lint \
 | 
			
		||||
 	lint \
 | 
			
		||||
	vet \
 | 
			
		||||
	fmt \
 | 
			
		||||
	fmtcheck \
 | 
			
		||||
@@ -21,31 +19,27 @@ REVISION := $(shell git rev-parse --short HEAD)
 | 
			
		||||
BUILDTIME := $(shell date "+%Y%m%d_%H%M%S")
 | 
			
		||||
LDFLAGS := -X 'github.com/future-architect/vuls/config.Version=$(VERSION)' \
 | 
			
		||||
    -X 'github.com/future-architect/vuls/config.Revision=build-$(BUILDTIME)_$(REVISION)'
 | 
			
		||||
GO := GO111MODULE=on go
 | 
			
		||||
GO_OFF := GO111MODULE=off go
 | 
			
		||||
 | 
			
		||||
all: dep build
 | 
			
		||||
 | 
			
		||||
dep:
 | 
			
		||||
	go get -u github.com/golang/dep/...
 | 
			
		||||
	dep ensure -v
 | 
			
		||||
all: build
 | 
			
		||||
 | 
			
		||||
depup:
 | 
			
		||||
	go get -u github.com/golang/dep/...
 | 
			
		||||
	dep ensure -update -v
 | 
			
		||||
build: main.go pretest fmt
 | 
			
		||||
	$(GO) build -a -ldflags "$(LDFLAGS)" -o vuls $<
 | 
			
		||||
 | 
			
		||||
build: main.go dep pretest
 | 
			
		||||
	go build -ldflags "$(LDFLAGS)" -o vuls $<
 | 
			
		||||
 | 
			
		||||
install: main.go dep pretest
 | 
			
		||||
	go install -ldflags "$(LDFLAGS)"
 | 
			
		||||
b: 	main.go pretest fmt
 | 
			
		||||
	$(GO) build -ldflags "$(LDFLAGS)" -o vuls $<
 | 
			
		||||
 | 
			
		||||
install: main.go pretest
 | 
			
		||||
	$(GO) install -ldflags "$(LDFLAGS)"
 | 
			
		||||
 | 
			
		||||
lint:
 | 
			
		||||
	@ go get -v golang.org/x/lint/golint
 | 
			
		||||
	$(GO_OFF) get -u golang.org/x/lint/golint
 | 
			
		||||
	golint $(PKGS)
 | 
			
		||||
 | 
			
		||||
vet:
 | 
			
		||||
	#  @-go get -v golang.org/x/tools/cmd/vet
 | 
			
		||||
	go vet ./... || exit;
 | 
			
		||||
	echo $(PKGS) | xargs env $(GO) vet || exit;
 | 
			
		||||
 | 
			
		||||
fmt:
 | 
			
		||||
	gofmt -s -w $(SRCS)
 | 
			
		||||
@@ -59,7 +53,7 @@ fmtcheck:
 | 
			
		||||
pretest: lint vet fmtcheck
 | 
			
		||||
 | 
			
		||||
test: 
 | 
			
		||||
	echo $(PKGS) | xargs go test -cover -v || exit;
 | 
			
		||||
	$(GO) test -cover -v ./... || exit;
 | 
			
		||||
 | 
			
		||||
unused:
 | 
			
		||||
	$(foreach pkg,$(PKGS),unused $(pkg);)
 | 
			
		||||
@@ -72,3 +66,10 @@ cov:
 | 
			
		||||
clean:
 | 
			
		||||
	echo $(PKGS) | xargs go clean || exit;
 | 
			
		||||
 | 
			
		||||
# trivy-to-vuls
 | 
			
		||||
build-trivy-to-vuls: pretest fmt
 | 
			
		||||
	$(GO) build -o trivy-to-vuls contrib/trivy/cmd/*.go
 | 
			
		||||
 | 
			
		||||
# future-vuls
 | 
			
		||||
build-future-vuls: pretest fmt
 | 
			
		||||
	$(GO) build -o future-vuls contrib/future-vuls/cmd/*.go
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										991
									
								
								Gopkg.lock
									
									
									
										generated
									
									
									
								
							
							
						
						@@ -1,991 +0,0 @@
 | 
			
		||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:b92928b73320648b38c93cacb9082c0fe3f8ac3383ad9bd537eef62c380e0e7a"
 | 
			
		||||
  name = "contrib.go.opencensus.io/exporter/ocagent"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "00af367e65149ff1f2f4b93bbfbb84fd9297170d"
 | 
			
		||||
  version = "v0.2.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:a90dbfc07d4cf47b5f113a2d52227e0b098592b22c0bd7afd731f6cb8bd9d55c"
 | 
			
		||||
  name = "github.com/Azure/azure-sdk-for-go"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "storage",
 | 
			
		||||
    "version",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "1951233eb944a49aa5f7278cba8e3e32a8c958af"
 | 
			
		||||
  version = "v24.0.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:e6c692a2dd5f978216331f2ab41b45dfdf01d5b2a74c596a9f69bcef77b7d67b"
 | 
			
		||||
  name = "github.com/Azure/go-autorest"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "autorest",
 | 
			
		||||
    "autorest/adal",
 | 
			
		||||
    "autorest/azure",
 | 
			
		||||
    "autorest/date",
 | 
			
		||||
    "logger",
 | 
			
		||||
    "tracing",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "be17756531f50014397912b7aa557ec335e39b98"
 | 
			
		||||
  version = "v11.3.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:9f3b30d9f8e0d7040f729b82dcbc8f0dead820a133b3147ce355fc451f32d761"
 | 
			
		||||
  name = "github.com/BurntSushi/toml"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "3012a1dbe2e4bd1391d42b32f0577cb7bbc7f005"
 | 
			
		||||
  version = "v0.3.1"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:bb6c15391e666c4f44bdc604772301b93102233ed687be6df6d1c2abbde4f15c"
 | 
			
		||||
  name = "github.com/RackSec/srslog"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "a4725f04ec91af1a91b380da679d6e0c2f061e59"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:320e7ead93de9fd2b0e59b50fd92a4d50c1f8ab455d96bc2eb083267453a9709"
 | 
			
		||||
  name = "github.com/asaskevich/govalidator"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "ccb8e960c48f04d6935e72476ae4a51028f9e22f"
 | 
			
		||||
  version = "v9"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:5652bf3ce03ccaeb93cd5e11fcaab25467f78275fd9c4b4d1ffe88aae6faed12"
 | 
			
		||||
  name = "github.com/aws/aws-sdk-go"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "aws",
 | 
			
		||||
    "aws/awserr",
 | 
			
		||||
    "aws/awsutil",
 | 
			
		||||
    "aws/client",
 | 
			
		||||
    "aws/client/metadata",
 | 
			
		||||
    "aws/corehandlers",
 | 
			
		||||
    "aws/credentials",
 | 
			
		||||
    "aws/credentials/ec2rolecreds",
 | 
			
		||||
    "aws/credentials/endpointcreds",
 | 
			
		||||
    "aws/credentials/processcreds",
 | 
			
		||||
    "aws/credentials/stscreds",
 | 
			
		||||
    "aws/csm",
 | 
			
		||||
    "aws/defaults",
 | 
			
		||||
    "aws/ec2metadata",
 | 
			
		||||
    "aws/endpoints",
 | 
			
		||||
    "aws/request",
 | 
			
		||||
    "aws/session",
 | 
			
		||||
    "aws/signer/v4",
 | 
			
		||||
    "internal/ini",
 | 
			
		||||
    "internal/s3err",
 | 
			
		||||
    "internal/sdkio",
 | 
			
		||||
    "internal/sdkrand",
 | 
			
		||||
    "internal/sdkuri",
 | 
			
		||||
    "internal/shareddefaults",
 | 
			
		||||
    "private/protocol",
 | 
			
		||||
    "private/protocol/eventstream",
 | 
			
		||||
    "private/protocol/eventstream/eventstreamapi",
 | 
			
		||||
    "private/protocol/query",
 | 
			
		||||
    "private/protocol/query/queryutil",
 | 
			
		||||
    "private/protocol/rest",
 | 
			
		||||
    "private/protocol/restxml",
 | 
			
		||||
    "private/protocol/xml/xmlutil",
 | 
			
		||||
    "service/s3",
 | 
			
		||||
    "service/sts",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "aabf189db35ba7eb5a35afe6d681fc0f70954fca"
 | 
			
		||||
  version = "v1.16.18"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:0f98f59e9a2f4070d66f0c9c39561f68fcd1dc837b22a852d28d0003aebd1b1e"
 | 
			
		||||
  name = "github.com/boltdb/bolt"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "2f1ce7a837dcb8da3ec595b1dac9d0632f0f99e8"
 | 
			
		||||
  version = "v1.3.1"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:166438587ed45ac211dab8a3ecebf4fa0c186d0db63430fb9127bbc2e5fcdc67"
 | 
			
		||||
  name = "github.com/cenkalti/backoff"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "1e4cf3da559842a91afcb6ea6141451e6c30c618"
 | 
			
		||||
  version = "v2.1.1"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:65b0d980b428a6ad4425f2df4cd5410edd81f044cf527bd1c345368444649e58"
 | 
			
		||||
  name = "github.com/census-instrumentation/opencensus-proto"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "gen-go/agent/common/v1",
 | 
			
		||||
    "gen-go/agent/trace/v1",
 | 
			
		||||
    "gen-go/resource/v1",
 | 
			
		||||
    "gen-go/trace/v1",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "7f2434bc10da710debe5c4315ed6d4df454b4024"
 | 
			
		||||
  version = "v0.1.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:e04c00d619875ce5fa67180891984a9b1fadcc031af36bcd7a3509cbdad1df15"
 | 
			
		||||
  name = "github.com/cheggaaa/pb"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "c112833d014c77e8bde723fd0158e3156951639f"
 | 
			
		||||
  version = "v2.0.6"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:76dc72490af7174349349838f2fe118996381b31ea83243812a97e5a0fd5ed55"
 | 
			
		||||
  name = "github.com/dgrijalva/jwt-go"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e"
 | 
			
		||||
  version = "v3.2.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:865079840386857c809b72ce300be7580cb50d3d3129ce11bf9aa6ca2bc1934a"
 | 
			
		||||
  name = "github.com/fatih/color"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4"
 | 
			
		||||
  version = "v1.7.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:abeb38ade3f32a92943e5be54f55ed6d6e3b6602761d74b4aab4c9dd45c18abd"
 | 
			
		||||
  name = "github.com/fsnotify/fsnotify"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9"
 | 
			
		||||
  version = "v1.4.7"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:ad53d1f710522a38d1f0e5e0a55a194b1c6b2cd8e84313568e43523271f0cf62"
 | 
			
		||||
  name = "github.com/go-redis/redis"
 | 
			
		||||
  packages = [
 | 
			
		||||
    ".",
 | 
			
		||||
    "internal",
 | 
			
		||||
    "internal/consistenthash",
 | 
			
		||||
    "internal/hashtag",
 | 
			
		||||
    "internal/pool",
 | 
			
		||||
    "internal/proto",
 | 
			
		||||
    "internal/util",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "22be8a3eaf992c828cecb69dc07348313bf08d2e"
 | 
			
		||||
  version = "v6.15.1"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:ec6f9bf5e274c833c911923c9193867f3f18788c461f76f05f62bb1510e0ae65"
 | 
			
		||||
  name = "github.com/go-sql-driver/mysql"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "72cd26f257d44c1114970e19afddcd812016007e"
 | 
			
		||||
  version = "v1.4.1"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:586ea76dbd0374d6fb649a91d70d652b7fe0ccffb8910a77468e7702e7901f3d"
 | 
			
		||||
  name = "github.com/go-stack/stack"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a"
 | 
			
		||||
  version = "v1.8.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:8f0705fa33e8957018611cc81c65cb373b626c092d39931bb86882489fc4c3f4"
 | 
			
		||||
  name = "github.com/golang/protobuf"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "proto",
 | 
			
		||||
    "ptypes",
 | 
			
		||||
    "ptypes/any",
 | 
			
		||||
    "ptypes/duration",
 | 
			
		||||
    "ptypes/timestamp",
 | 
			
		||||
    "ptypes/wrappers",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5"
 | 
			
		||||
  version = "v1.2.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:df265b7f54410945dad5cf5979d91461b9fa7ff9b397ab58d2d577002a8a0e24"
 | 
			
		||||
  name = "github.com/google/subcommands"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "46f0354f63152e8801bb460d26f5b6c4c878efbb"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:7b5c6e2eeaa9ae5907c391a91c132abfd5c9e8a784a341b5625e750c67e6825d"
 | 
			
		||||
  name = "github.com/gorilla/websocket"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "66b9c49e59c6c48f0ffce28c2d8b8a5678502c6d"
 | 
			
		||||
  version = "v1.4.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:4e08dc2383a46b3107f0b34ca338c4459e8fc8ee90e46a60e728aa8a2b21d558"
 | 
			
		||||
  name = "github.com/gosuri/uitable"
 | 
			
		||||
  packages = [
 | 
			
		||||
    ".",
 | 
			
		||||
    "util/strutil",
 | 
			
		||||
    "util/wordwrap",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "36ee7e946282a3fb1cfecd476ddc9b35d8847e42"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:8dbe76014be3c83806abc61befcb5e1789d2d872bc8f98a8fb955405550c63be"
 | 
			
		||||
  name = "github.com/grokify/html-strip-tags-go"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "e9e44961e26f513866063f54bf85070db95600f7"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:950caca7dfcf796419232ba996c9c3539d09f26af27ba848c4508e604c13efbb"
 | 
			
		||||
  name = "github.com/hashicorp/go-version"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "d40cf49b3a77bba84a7afdbd7f1dc295d114efb1"
 | 
			
		||||
  version = "v1.1.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:c0d19ab64b32ce9fe5cf4ddceba78d5bc9807f0016db6b1183599da3dcc24d10"
 | 
			
		||||
  name = "github.com/hashicorp/hcl"
 | 
			
		||||
  packages = [
 | 
			
		||||
    ".",
 | 
			
		||||
    "hcl/ast",
 | 
			
		||||
    "hcl/parser",
 | 
			
		||||
    "hcl/printer",
 | 
			
		||||
    "hcl/scanner",
 | 
			
		||||
    "hcl/strconv",
 | 
			
		||||
    "hcl/token",
 | 
			
		||||
    "json/parser",
 | 
			
		||||
    "json/scanner",
 | 
			
		||||
    "json/token",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "8cb6e5b959231cc1119e43259c4a608f9c51a241"
 | 
			
		||||
  version = "v1.0.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:0f8b63af5601a93b6b6a63a420c857819e98a252369262d8faf66f3566ba294e"
 | 
			
		||||
  name = "github.com/hashicorp/uuid"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "ebb0a03e909c9c642a36d2527729104324c44fdb"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:0778dc7fce1b4669a8bfa7ae506ec1f595b6ab0f8989c1c0d22a8ca1144e9972"
 | 
			
		||||
  name = "github.com/howeyc/gopass"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "bf9dde6d0d2c004a008c27aaee91170c786f6db8"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:e96640e5b9ce93e2d7ee18f48048483080fd23e72e3c38bc17e9c8b77062031a"
 | 
			
		||||
  name = "github.com/inconshreveable/log15"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "67afb5ed74ec82fd7ac8f49d27c509ac6f991970"
 | 
			
		||||
  version = "v2.14"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:ff312c4d510c67954a6fc6a11c9ff72a2b2169584776b7419c7b8c729e2b13ac"
 | 
			
		||||
  name = "github.com/jinzhu/gorm"
 | 
			
		||||
  packages = [
 | 
			
		||||
    ".",
 | 
			
		||||
    "dialects/mysql",
 | 
			
		||||
    "dialects/postgres",
 | 
			
		||||
    "dialects/sqlite",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "472c70caa40267cb89fd8facb07fe6454b578626"
 | 
			
		||||
  version = "v1.9.2"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:fd97437fbb6b7dce04132cf06775bd258cce305c44add58eb55ca86c6c325160"
 | 
			
		||||
  name = "github.com/jinzhu/inflection"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "04140366298a54a039076d798123ffa108fff46c"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:bb81097a5b62634f3e9fec1014657855610c82d19b9a40c17612e32651e35dca"
 | 
			
		||||
  name = "github.com/jmespath/go-jmespath"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "c2b33e84"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:114ecad51af93a73ae6781fd0d0bc28e52b433c852b84ab4b4c109c15e6c6b6d"
 | 
			
		||||
  name = "github.com/jroimartin/gocui"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "c055c87ae801372cd74a0839b972db4f7697ae5f"
 | 
			
		||||
  version = "v0.4.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:16dd6b893b78a50564cdde1d9f7ea67224dece11bb0886bd882f1dc3dc1d440d"
 | 
			
		||||
  name = "github.com/k0kubun/pp"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "027a6d1765d673d337e687394dbe780dd64e2a1e"
 | 
			
		||||
  version = "v2.3.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:bdf08c9b41c029c60ba5dc99443a3ce74eedad842cf2adf9c255513f432422e2"
 | 
			
		||||
  name = "github.com/knqyf263/go-cpe"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "common",
 | 
			
		||||
    "matching",
 | 
			
		||||
    "naming",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "659663f6eca2ff32258e282557e7808115ea498a"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:a9955a589c7f6f28bd5a5f69da3f1e2cc857c23c7605c5fa7b605f065ba8f3fe"
 | 
			
		||||
  name = "github.com/knqyf263/go-deb-version"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "9865fe14d09b1c729188ac810466dde90f897ee3"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:5734c5362ef66c39ddf1b4a11dfe75fa3c1adb70e78059543c83c0c6e89f2bc0"
 | 
			
		||||
  name = "github.com/knqyf263/go-rpm-version"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "74609b86c936dff800c69ec89fcf4bc52d5f13a4"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:acca5c567e76e94e81f8d65893e2a9cd12d914dd688731f461a5ebdb180d4938"
 | 
			
		||||
  name = "github.com/knqyf263/gost"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "config",
 | 
			
		||||
    "db",
 | 
			
		||||
    "models",
 | 
			
		||||
    "util",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "5afeda5e8e1f8f3561738d3d6fa6549c88feb31e"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:0a69a1c0db3591fcefb47f115b224592c8dfa4368b7ba9fae509d5e16cdc95c8"
 | 
			
		||||
  name = "github.com/konsorten/go-windows-terminal-sequences"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "5c8c8bd35d3832f5d134ae1e1e375b69a4d25242"
 | 
			
		||||
  version = "v1.0.1"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:fa59fec07121e6190139b5134524c4fc7a6abe5143a775a0e17313b6997e17a7"
 | 
			
		||||
  name = "github.com/kotakanbe/go-cve-dictionary"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "config",
 | 
			
		||||
    "db",
 | 
			
		||||
    "log",
 | 
			
		||||
    "models",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "b083bedef97055c27d1f039428ab183eca7c6450"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:54d3c90db1164399906830313a6fce7770917d7e4a12da8f2d8693d18ff5ef27"
 | 
			
		||||
  name = "github.com/kotakanbe/go-pingscanner"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "641dc2cc2d3cbf295dad356667b74c69bcbd6f70"
 | 
			
		||||
  version = "v0.1.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:8fd95e6bab4d09a0f610bd5c02ef6ec7d0d91da5a72b7cfcbfd67254bcb72b75"
 | 
			
		||||
  name = "github.com/kotakanbe/goval-dictionary"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "config",
 | 
			
		||||
    "db",
 | 
			
		||||
    "db/rdb",
 | 
			
		||||
    "models",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "5070051ecafdf15cbe2490e71ec038de7d25b71e"
 | 
			
		||||
  version = "v0.1.1"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:0daead102d7ca3af110dfb832e8c14393f197d94e5ffe3f0639f10ea2cc55530"
 | 
			
		||||
  name = "github.com/kotakanbe/logrus-prefixed-formatter"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "928f7356cb964637e2489a6ef37eee55181676c5"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:01eb0269028d3c2e21b5b6cd9b1ba81bc4170ab293fcffa84e3aa3a6138a92e8"
 | 
			
		||||
  name = "github.com/labstack/gommon"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "color",
 | 
			
		||||
    "log",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "7fd9f68ece0bcb1a905fac8f1549f0083f71c51b"
 | 
			
		||||
  version = "v0.2.8"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:b18ffc558326ebaed3b4a175617f1e12ed4e3f53d6ebfe5ba372a3de16d22278"
 | 
			
		||||
  name = "github.com/lib/pq"
 | 
			
		||||
  packages = [
 | 
			
		||||
    ".",
 | 
			
		||||
    "hstore",
 | 
			
		||||
    "oid",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "4ded0e9383f75c197b3a2aaa6d590ac52df6fd79"
 | 
			
		||||
  version = "v1.0.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:c568d7727aa262c32bdf8a3f7db83614f7af0ed661474b24588de635c20024c7"
 | 
			
		||||
  name = "github.com/magiconair/properties"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "c2353362d570a7bfa228149c62842019201cfb71"
 | 
			
		||||
  version = "v1.8.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:4e878df5f4e9fd625bf9c9aac77ef7cbfa4a74c01265505527c23470c0e40300"
 | 
			
		||||
  name = "github.com/marstr/guid"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "8bd9a64bf37eb297b492a4101fb28e80ac0b290f"
 | 
			
		||||
  version = "v1.1.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:c658e84ad3916da105a761660dcaeb01e63416c8ec7bc62256a9b411a05fcd67"
 | 
			
		||||
  name = "github.com/mattn/go-colorable"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
 | 
			
		||||
  version = "v0.0.9"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:0981502f9816113c9c8c4ac301583841855c8cf4da8c72f696b3ebedf6d0e4e5"
 | 
			
		||||
  name = "github.com/mattn/go-isatty"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c"
 | 
			
		||||
  version = "v0.0.4"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:0356f3312c9bd1cbeda81505b7fd437501d8e778ab66998ef69f00d7f9b3a0d7"
 | 
			
		||||
  name = "github.com/mattn/go-runewidth"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "3ee7d812e62a0804a7d0a324e0249ca2db3476d3"
 | 
			
		||||
  version = "v0.0.4"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:4a49346ca45376a2bba679ca0e83bec949d780d4e927931317904bad482943ec"
 | 
			
		||||
  name = "github.com/mattn/go-sqlite3"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "c7c4067b79cc51e6dfdcef5c702e74b1e0fa7c75"
 | 
			
		||||
  version = "v1.10.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:2b32af4d2a529083275afc192d1067d8126b578c7a9613b26600e4df9c735155"
 | 
			
		||||
  name = "github.com/mgutz/ansi"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "9520e82c474b0a04dd04f8a40959027271bab992"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:78bbb1ba5b7c3f2ed0ea1eab57bdd3859aec7e177811563edc41198a760b06af"
 | 
			
		||||
  name = "github.com/mitchellh/go-homedir"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "ae18d6b8b3205b561c79e8e5f69bff09736185f4"
 | 
			
		||||
  version = "v1.0.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:53bc4cd4914cd7cd52139990d5170d6dc99067ae31c56530621b18b35fc30318"
 | 
			
		||||
  name = "github.com/mitchellh/mapstructure"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "3536a929edddb9a5b34bd6861dc4a9647cb459fe"
 | 
			
		||||
  version = "v1.1.2"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:7aefb397a53fc437c90f0fdb3e1419c751c5a3a165ced52325d5d797edf1aca6"
 | 
			
		||||
  name = "github.com/moul/http2curl"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "9ac6cf4d929b2fa8fd2d2e6dec5bb0feb4f4911d"
 | 
			
		||||
  version = "v1.0.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:a440c18972e9499a1e8de68915e5a9119008d86efc2a9c6c6edddc323ce6f3ed"
 | 
			
		||||
  name = "github.com/mozqnet/go-exploitdb"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "db",
 | 
			
		||||
    "models",
 | 
			
		||||
    "util",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "652ae1f6aa234a4e22c8a6c9566ef4018a1d28c8"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:95d38d218bf2290987c6b0e885a9f0f2d3d3239235acaddca01c3fe36e5e5566"
 | 
			
		||||
  name = "github.com/nlopes/slack"
 | 
			
		||||
  packages = [
 | 
			
		||||
    ".",
 | 
			
		||||
    "slackutilsx",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "b9033a72a20bf84563485e86a2adbea4bf265804"
 | 
			
		||||
  version = "v0.4.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:f3fc7efada7606d5abc88372e1f838ed897fa522077957070fbc2207a50d6faa"
 | 
			
		||||
  name = "github.com/nsf/termbox-go"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "0938b5187e61bb8c4dcac2b0a9cf4047d83784fc"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:abcdbf03ca6ca13d3697e2186edc1f33863bbdac2b3a44dfa39015e8903f7409"
 | 
			
		||||
  name = "github.com/olekukonko/tablewriter"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "e6d60cf7ba1f42d86d54cdf5508611c4aafb3970"
 | 
			
		||||
  version = "v0.0.1"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:d776f3e95774a8719f2e57fabbbb33103035fe072dcf6f1864f33abd17b753e5"
 | 
			
		||||
  name = "github.com/parnurzeal/gorequest"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "a578a48e8d6ca8b01a3b18314c43c6716bb5f5a3"
 | 
			
		||||
  version = "v0.2.15"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:95741de3af260a92cc5c7f3f3061e85273f5a81b5db20d4bd68da74bd521675e"
 | 
			
		||||
  name = "github.com/pelletier/go-toml"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "c01d1270ff3e442a8a57cddc1c92dc1138598194"
 | 
			
		||||
  version = "v1.2.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:cf31692c14422fa27c83a05292eb5cbe0fb2775972e8f1f8446a71549bd8980b"
 | 
			
		||||
  name = "github.com/pkg/errors"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4"
 | 
			
		||||
  version = "v0.8.1"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:1a23fdd843129ef761ffe7651bc5fe7c5b09fbe933e92783ab06cc11c37b7b37"
 | 
			
		||||
  name = "github.com/rifflock/lfshook"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "b9218ef580f59a2e72dad1aa33d660150445d05a"
 | 
			
		||||
  version = "v2.4"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:274f67cb6fed9588ea2521ecdac05a6d62a8c51c074c1fccc6a49a40ba80e925"
 | 
			
		||||
  name = "github.com/satori/go.uuid"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3"
 | 
			
		||||
  version = "v1.2.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:9c3c856c4bd09733de5727aeb85fc484b8b87a6eb9e6a632c47e3f17142757ee"
 | 
			
		||||
  name = "github.com/sirupsen/logrus"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "78fb3852d92683dc28da6cc3d5f965100677c27d"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:d707dbc1330c0ed177d4642d6ae102d5e2c847ebd0eb84562d0dc4f024531cfc"
 | 
			
		||||
  name = "github.com/spf13/afero"
 | 
			
		||||
  packages = [
 | 
			
		||||
    ".",
 | 
			
		||||
    "mem",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "a5d6946387efe7d64d09dcba68cdd523dc1273a3"
 | 
			
		||||
  version = "v1.2.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:08d65904057412fc0270fc4812a1c90c594186819243160dc779a402d4b6d0bc"
 | 
			
		||||
  name = "github.com/spf13/cast"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "8c9545af88b134710ab1cd196795e7f2388358d7"
 | 
			
		||||
  version = "v1.3.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:68ea4e23713989dc20b1bded5d9da2c5f9be14ff9885beef481848edd18c26cb"
 | 
			
		||||
  name = "github.com/spf13/jwalterweatherman"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "4a4406e478ca629068e7768fc33f3f044173c0a6"
 | 
			
		||||
  version = "v1.0.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:c1b1102241e7f645bc8e0c22ae352e8f0dc6484b6cb4d132fa9f24174e0119e2"
 | 
			
		||||
  name = "github.com/spf13/pflag"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "298182f68c66c05229eb03ac171abe6e309ee79a"
 | 
			
		||||
  version = "v1.0.3"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:de37e343c64582d7026bf8ab6ac5b22a72eac54f3a57020db31524affed9f423"
 | 
			
		||||
  name = "github.com/spf13/viper"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "6d33b5a963d922d182c91e8a1c88d81fd150cfd4"
 | 
			
		||||
  version = "v1.3.1"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:c468422f334a6b46a19448ad59aaffdfc0a36b08fdcc1c749a0b29b6453d7e59"
 | 
			
		||||
  name = "github.com/valyala/bytebufferpool"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7"
 | 
			
		||||
  version = "v1.0.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:268b8bce0064e8c057d7b913605459f9a26dcab864c0886a56d196540fbf003f"
 | 
			
		||||
  name = "github.com/valyala/fasttemplate"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "dcecefd839c4193db0d35b88ec65b4c12d360ab0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:0792df7c7ff49b81c7a8c5a2a47aee897c5bab31fb348c8e2f80a560d675f941"
 | 
			
		||||
  name = "github.com/ymomoi/goval-parser"
 | 
			
		||||
  packages = ["oval"]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "0a0be1dd9d0855b50be0be5a10ad3085382b6d59"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:2ae8314c44cd413cfdb5b1df082b350116dd8d2fff973e62c01b285b7affd89e"
 | 
			
		||||
  name = "go.opencensus.io"
 | 
			
		||||
  packages = [
 | 
			
		||||
    ".",
 | 
			
		||||
    "exemplar",
 | 
			
		||||
    "internal",
 | 
			
		||||
    "internal/tagencoding",
 | 
			
		||||
    "plugin/ochttp",
 | 
			
		||||
    "plugin/ochttp/propagation/b3",
 | 
			
		||||
    "plugin/ochttp/propagation/tracecontext",
 | 
			
		||||
    "stats",
 | 
			
		||||
    "stats/internal",
 | 
			
		||||
    "stats/view",
 | 
			
		||||
    "tag",
 | 
			
		||||
    "trace",
 | 
			
		||||
    "trace/internal",
 | 
			
		||||
    "trace/propagation",
 | 
			
		||||
    "trace/tracestate",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "b7bf3cdb64150a8c8c53b769fdeb2ba581bd4d4b"
 | 
			
		||||
  version = "v0.18.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:30e9f5bea4df0d1a573ed89a85cc680ab05dfc078f6a21e627db236f29650a11"
 | 
			
		||||
  name = "golang.org/x/crypto"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "curve25519",
 | 
			
		||||
    "ed25519",
 | 
			
		||||
    "ed25519/internal/edwards25519",
 | 
			
		||||
    "internal/chacha20",
 | 
			
		||||
    "internal/subtle",
 | 
			
		||||
    "poly1305",
 | 
			
		||||
    "ssh",
 | 
			
		||||
    "ssh/agent",
 | 
			
		||||
    "ssh/terminal",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "ff983b9c42bc9fbf91556e191cc8efb585c16908"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:25c965216c188afcd5f430f65acc28d4f193c5a88e7c6c54ae876b1898f86368"
 | 
			
		||||
  name = "golang.org/x/net"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "context",
 | 
			
		||||
    "context/ctxhttp",
 | 
			
		||||
    "http/httpguts",
 | 
			
		||||
    "http2",
 | 
			
		||||
    "http2/hpack",
 | 
			
		||||
    "idna",
 | 
			
		||||
    "internal/timeseries",
 | 
			
		||||
    "publicsuffix",
 | 
			
		||||
    "trace",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "915654e7eabcea33ae277abbecf52f0d8b7a9fdc"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:e007b54f54cbd4214aa6d97a67d57bc2539991adb4e22ea92c482bbece8de469"
 | 
			
		||||
  name = "golang.org/x/oauth2"
 | 
			
		||||
  packages = [
 | 
			
		||||
    ".",
 | 
			
		||||
    "internal",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "99b60b757ec124ebb7d6b7e97f153b19c10ce163"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:75515eedc0dc2cb0b40372008b616fa2841d831c63eedd403285ff286c593295"
 | 
			
		||||
  name = "golang.org/x/sync"
 | 
			
		||||
  packages = ["semaphore"]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "37e7f081c4d4c64e13b10787722085407fe5d15f"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:5ee4df7ab18e945607ac822de8d10b180baea263b5e8676a1041727543b9c1e4"
 | 
			
		||||
  name = "golang.org/x/sys"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "unix",
 | 
			
		||||
    "windows",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "48ac38b7c8cbedd50b1613c0fccacfc7d88dfcdf"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18"
 | 
			
		||||
  name = "golang.org/x/text"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "collate",
 | 
			
		||||
    "collate/build",
 | 
			
		||||
    "internal/colltab",
 | 
			
		||||
    "internal/gen",
 | 
			
		||||
    "internal/tag",
 | 
			
		||||
    "internal/triegen",
 | 
			
		||||
    "internal/ucd",
 | 
			
		||||
    "language",
 | 
			
		||||
    "secure/bidirule",
 | 
			
		||||
    "transform",
 | 
			
		||||
    "unicode/bidi",
 | 
			
		||||
    "unicode/cldr",
 | 
			
		||||
    "unicode/norm",
 | 
			
		||||
    "unicode/rangetable",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
 | 
			
		||||
  version = "v0.3.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:5f003878aabe31d7f6b842d4de32b41c46c214bb629bb485387dbcce1edf5643"
 | 
			
		||||
  name = "google.golang.org/api"
 | 
			
		||||
  packages = ["support/bundler"]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "19e022d8cf43ce81f046bae8cc18c5397cc7732f"
 | 
			
		||||
  version = "v0.1.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:9e29a0ec029d012437d88da3ccccf18adcdce069cab08d462056c2c6bb006505"
 | 
			
		||||
  name = "google.golang.org/appengine"
 | 
			
		||||
  packages = [
 | 
			
		||||
    "cloudsql",
 | 
			
		||||
    "internal",
 | 
			
		||||
    "internal/base",
 | 
			
		||||
    "internal/datastore",
 | 
			
		||||
    "internal/log",
 | 
			
		||||
    "internal/remote_api",
 | 
			
		||||
    "internal/urlfetch",
 | 
			
		||||
    "urlfetch",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "e9657d882bb81064595ca3b56cbe2546bbabf7b1"
 | 
			
		||||
  version = "v1.4.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  branch = "master"
 | 
			
		||||
  digest = "1:077c1c599507b3b3e9156d17d36e1e61928ee9b53a5b420f10f28ebd4a0b275c"
 | 
			
		||||
  name = "google.golang.org/genproto"
 | 
			
		||||
  packages = ["googleapis/rpc/status"]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "db91494dd46c1fdcbbde05e5ff5eb56df8f7d79a"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:9edd250a3c46675d0679d87540b30c9ed253b19bd1fd1af08f4f5fb3c79fc487"
 | 
			
		||||
  name = "google.golang.org/grpc"
 | 
			
		||||
  packages = [
 | 
			
		||||
    ".",
 | 
			
		||||
    "balancer",
 | 
			
		||||
    "balancer/base",
 | 
			
		||||
    "balancer/roundrobin",
 | 
			
		||||
    "binarylog/grpc_binarylog_v1",
 | 
			
		||||
    "codes",
 | 
			
		||||
    "connectivity",
 | 
			
		||||
    "credentials",
 | 
			
		||||
    "credentials/internal",
 | 
			
		||||
    "encoding",
 | 
			
		||||
    "encoding/proto",
 | 
			
		||||
    "grpclog",
 | 
			
		||||
    "internal",
 | 
			
		||||
    "internal/backoff",
 | 
			
		||||
    "internal/binarylog",
 | 
			
		||||
    "internal/channelz",
 | 
			
		||||
    "internal/envconfig",
 | 
			
		||||
    "internal/grpcrand",
 | 
			
		||||
    "internal/grpcsync",
 | 
			
		||||
    "internal/syscall",
 | 
			
		||||
    "internal/transport",
 | 
			
		||||
    "keepalive",
 | 
			
		||||
    "metadata",
 | 
			
		||||
    "naming",
 | 
			
		||||
    "peer",
 | 
			
		||||
    "resolver",
 | 
			
		||||
    "resolver/dns",
 | 
			
		||||
    "resolver/passthrough",
 | 
			
		||||
    "stats",
 | 
			
		||||
    "status",
 | 
			
		||||
    "tap",
 | 
			
		||||
  ]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "df014850f6dee74ba2fc94874043a9f3f75fbfd8"
 | 
			
		||||
  version = "v1.17.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:e626376fab8608a972d47e91b3c1bbbddaecaf1d42b82be6dcc52d10a7557893"
 | 
			
		||||
  name = "gopkg.in/VividCortex/ewma.v1"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "b24eb346a94c3ba12c1da1e564dbac1b498a77ce"
 | 
			
		||||
  version = "v1.1.1"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:94cad6e2359d57da6652e689189c5b6ef19f99db6304d2c41de54f6632e15143"
 | 
			
		||||
  name = "gopkg.in/cheggaaa/pb.v1"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "1cc5bbe20449079337944d56292c7383510c534c"
 | 
			
		||||
  version = "v1.0.27"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:256938e7d43c73bd5e7bb97dd281d1ebe294b2928403ee1fbec96249915d1150"
 | 
			
		||||
  name = "gopkg.in/cheggaaa/pb.v2"
 | 
			
		||||
  packages = ["termutil"]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "c112833d014c77e8bde723fd0158e3156951639f"
 | 
			
		||||
  version = "v2.0.6"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:865079840386857c809b72ce300be7580cb50d3d3129ce11bf9aa6ca2bc1934a"
 | 
			
		||||
  name = "gopkg.in/fatih/color.v1"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4"
 | 
			
		||||
  version = "v1.7.0"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:c658e84ad3916da105a761660dcaeb01e63416c8ec7bc62256a9b411a05fcd67"
 | 
			
		||||
  name = "gopkg.in/mattn/go-colorable.v0"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072"
 | 
			
		||||
  version = "v0.0.9"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:0981502f9816113c9c8c4ac301583841855c8cf4da8c72f696b3ebedf6d0e4e5"
 | 
			
		||||
  name = "gopkg.in/mattn/go-isatty.v0"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c"
 | 
			
		||||
  version = "v0.0.4"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:0356f3312c9bd1cbeda81505b7fd437501d8e778ab66998ef69f00d7f9b3a0d7"
 | 
			
		||||
  name = "gopkg.in/mattn/go-runewidth.v0"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "3ee7d812e62a0804a7d0a324e0249ca2db3476d3"
 | 
			
		||||
  version = "v0.0.4"
 | 
			
		||||
 | 
			
		||||
[[projects]]
 | 
			
		||||
  digest = "1:4d2e5a73dc1500038e504a8d78b986630e3626dc027bc030ba5c75da257cdb96"
 | 
			
		||||
  name = "gopkg.in/yaml.v2"
 | 
			
		||||
  packages = ["."]
 | 
			
		||||
  pruneopts = "UT"
 | 
			
		||||
  revision = "51d6538a90f86fe93ac480b35f37b2be17fef232"
 | 
			
		||||
  version = "v2.2.2"
 | 
			
		||||
 | 
			
		||||
[solve-meta]
 | 
			
		||||
  analyzer-name = "dep"
 | 
			
		||||
  analyzer-version = 1
 | 
			
		||||
  input-imports = [
 | 
			
		||||
    "github.com/Azure/azure-sdk-for-go/storage",
 | 
			
		||||
    "github.com/BurntSushi/toml",
 | 
			
		||||
    "github.com/RackSec/srslog",
 | 
			
		||||
    "github.com/asaskevich/govalidator",
 | 
			
		||||
    "github.com/aws/aws-sdk-go/aws",
 | 
			
		||||
    "github.com/aws/aws-sdk-go/aws/credentials",
 | 
			
		||||
    "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
 | 
			
		||||
    "github.com/aws/aws-sdk-go/aws/ec2metadata",
 | 
			
		||||
    "github.com/aws/aws-sdk-go/aws/session",
 | 
			
		||||
    "github.com/aws/aws-sdk-go/service/s3",
 | 
			
		||||
    "github.com/aws/aws-sdk-go/service/sts",
 | 
			
		||||
    "github.com/boltdb/bolt",
 | 
			
		||||
    "github.com/cenkalti/backoff",
 | 
			
		||||
    "github.com/google/subcommands",
 | 
			
		||||
    "github.com/gosuri/uitable",
 | 
			
		||||
    "github.com/hashicorp/uuid",
 | 
			
		||||
    "github.com/howeyc/gopass",
 | 
			
		||||
    "github.com/jroimartin/gocui",
 | 
			
		||||
    "github.com/k0kubun/pp",
 | 
			
		||||
    "github.com/knqyf263/go-cpe/naming",
 | 
			
		||||
    "github.com/knqyf263/go-deb-version",
 | 
			
		||||
    "github.com/knqyf263/go-rpm-version",
 | 
			
		||||
    "github.com/knqyf263/gost/db",
 | 
			
		||||
    "github.com/knqyf263/gost/models",
 | 
			
		||||
    "github.com/kotakanbe/go-cve-dictionary/db",
 | 
			
		||||
    "github.com/kotakanbe/go-cve-dictionary/log",
 | 
			
		||||
    "github.com/kotakanbe/go-cve-dictionary/models",
 | 
			
		||||
    "github.com/kotakanbe/go-pingscanner",
 | 
			
		||||
    "github.com/kotakanbe/goval-dictionary/db",
 | 
			
		||||
    "github.com/kotakanbe/goval-dictionary/models",
 | 
			
		||||
    "github.com/kotakanbe/logrus-prefixed-formatter",
 | 
			
		||||
    "github.com/mitchellh/go-homedir",
 | 
			
		||||
    "github.com/mozqnet/go-exploitdb/db",
 | 
			
		||||
    "github.com/mozqnet/go-exploitdb/models",
 | 
			
		||||
    "github.com/nlopes/slack",
 | 
			
		||||
    "github.com/olekukonko/tablewriter",
 | 
			
		||||
    "github.com/parnurzeal/gorequest",
 | 
			
		||||
    "github.com/pkg/errors",
 | 
			
		||||
    "github.com/rifflock/lfshook",
 | 
			
		||||
    "github.com/sirupsen/logrus",
 | 
			
		||||
    "golang.org/x/crypto/ssh",
 | 
			
		||||
    "golang.org/x/crypto/ssh/agent",
 | 
			
		||||
    "golang.org/x/oauth2",
 | 
			
		||||
  ]
 | 
			
		||||
  solver-name = "gps-cdcl"
 | 
			
		||||
  solver-version = 1
 | 
			
		||||
							
								
								
									
										41
									
								
								Gopkg.toml
									
									
									
									
									
								
							
							
						
						@@ -1,41 +0,0 @@
 | 
			
		||||
# Gopkg.toml example
 | 
			
		||||
#
 | 
			
		||||
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
 | 
			
		||||
# for detailed Gopkg.toml documentation.
 | 
			
		||||
#
 | 
			
		||||
# required = ["github.com/user/thing/cmd/thing"]
 | 
			
		||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
 | 
			
		||||
#
 | 
			
		||||
# [[constraint]]
 | 
			
		||||
#   name = "github.com/user/project"
 | 
			
		||||
#   version = "1.0.0"
 | 
			
		||||
#
 | 
			
		||||
# [[constraint]]
 | 
			
		||||
#   name = "github.com/user/project2"
 | 
			
		||||
#   branch = "dev"
 | 
			
		||||
#   source = "github.com/myfork/project2"
 | 
			
		||||
#
 | 
			
		||||
# [[override]]
 | 
			
		||||
#   name = "github.com/x/y"
 | 
			
		||||
#   version = "2.4.0"
 | 
			
		||||
#
 | 
			
		||||
# [prune]
 | 
			
		||||
#   non-go = false
 | 
			
		||||
#   go-tests = true
 | 
			
		||||
#   unused-packages = true
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/knqyf263/gost"
 | 
			
		||||
  branch = "master"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/kotakanbe/go-cve-dictionary"
 | 
			
		||||
  branch = "master"
 | 
			
		||||
 | 
			
		||||
[[constraint]]
 | 
			
		||||
  name = "github.com/mozqnet/go-exploitdb"
 | 
			
		||||
  branch = "master"
 | 
			
		||||
 | 
			
		||||
[prune]
 | 
			
		||||
  go-tests = true
 | 
			
		||||
  unused-packages = true
 | 
			
		||||
							
								
								
									
										153
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						@@ -1,23 +1,21 @@
 | 
			
		||||
                    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
                       Version 3, 29 June 2007
 | 
			
		||||
                    GNU AFFERO GENERAL PUBLIC LICENSE
 | 
			
		||||
                       Version 3, 19 November 2007
 | 
			
		||||
 | 
			
		||||
 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 | 
			
		||||
 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 | 
			
		||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
			
		||||
 of this license document, but changing it is not allowed.
 | 
			
		||||
 | 
			
		||||
                            Preamble
 | 
			
		||||
 | 
			
		||||
  The GNU General Public License is a free, copyleft license for
 | 
			
		||||
software and other kinds of works.
 | 
			
		||||
  The GNU Affero General Public License is a free, copyleft license for
 | 
			
		||||
software and other kinds of works, specifically designed to ensure
 | 
			
		||||
cooperation with the community in the case of network server software.
 | 
			
		||||
 | 
			
		||||
  The licenses for most software and other practical works are designed
 | 
			
		||||
to take away your freedom to share and change the works.  By contrast,
 | 
			
		||||
the GNU General Public License is intended to guarantee your freedom to
 | 
			
		||||
our General Public Licenses are intended to guarantee your freedom to
 | 
			
		||||
share and change all versions of a program--to make sure it remains free
 | 
			
		||||
software for all its users.  We, the Free Software Foundation, use the
 | 
			
		||||
GNU General Public License for most of our software; it applies also to
 | 
			
		||||
any other work released this way by its authors.  You can apply it to
 | 
			
		||||
your programs, too.
 | 
			
		||||
software for all its users.
 | 
			
		||||
 | 
			
		||||
  When we speak of free software, we are referring to freedom, not
 | 
			
		||||
price.  Our General Public Licenses are designed to make sure that you
 | 
			
		||||
@@ -26,44 +24,34 @@ them if you wish), that you receive source code or can get it if you
 | 
			
		||||
want it, that you can change the software or use pieces of it in new
 | 
			
		||||
free programs, and that you know you can do these things.
 | 
			
		||||
 | 
			
		||||
  To protect your rights, we need to prevent others from denying you
 | 
			
		||||
these rights or asking you to surrender the rights.  Therefore, you have
 | 
			
		||||
certain responsibilities if you distribute copies of the software, or if
 | 
			
		||||
you modify it: responsibilities to respect the freedom of others.
 | 
			
		||||
  Developers that use our General Public Licenses protect your rights
 | 
			
		||||
with two steps: (1) assert copyright on the software, and (2) offer
 | 
			
		||||
you this License which gives you legal permission to copy, distribute
 | 
			
		||||
and/or modify the software.
 | 
			
		||||
 | 
			
		||||
  For example, if you distribute copies of such a program, whether
 | 
			
		||||
gratis or for a fee, you must pass on to the recipients the same
 | 
			
		||||
freedoms that you received.  You must make sure that they, too, receive
 | 
			
		||||
or can get the source code.  And you must show them these terms so they
 | 
			
		||||
know their rights.
 | 
			
		||||
  A secondary benefit of defending all users' freedom is that
 | 
			
		||||
improvements made in alternate versions of the program, if they
 | 
			
		||||
receive widespread use, become available for other developers to
 | 
			
		||||
incorporate.  Many developers of free software are heartened and
 | 
			
		||||
encouraged by the resulting cooperation.  However, in the case of
 | 
			
		||||
software used on network servers, this result may fail to come about.
 | 
			
		||||
The GNU General Public License permits making a modified version and
 | 
			
		||||
letting the public access it on a server without ever releasing its
 | 
			
		||||
source code to the public.
 | 
			
		||||
 | 
			
		||||
  Developers that use the GNU GPL protect your rights with two steps:
 | 
			
		||||
(1) assert copyright on the software, and (2) offer you this License
 | 
			
		||||
giving you legal permission to copy, distribute and/or modify it.
 | 
			
		||||
  The GNU Affero General Public License is designed specifically to
 | 
			
		||||
ensure that, in such cases, the modified source code becomes available
 | 
			
		||||
to the community.  It requires the operator of a network server to
 | 
			
		||||
provide the source code of the modified version running there to the
 | 
			
		||||
users of that server.  Therefore, public use of a modified version, on
 | 
			
		||||
a publicly accessible server, gives the public access to the source
 | 
			
		||||
code of the modified version.
 | 
			
		||||
 | 
			
		||||
  For the developers' and authors' protection, the GPL clearly explains
 | 
			
		||||
that there is no warranty for this free software.  For both users' and
 | 
			
		||||
authors' sake, the GPL requires that modified versions be marked as
 | 
			
		||||
changed, so that their problems will not be attributed erroneously to
 | 
			
		||||
authors of previous versions.
 | 
			
		||||
 | 
			
		||||
  Some devices are designed to deny users access to install or run
 | 
			
		||||
modified versions of the software inside them, although the manufacturer
 | 
			
		||||
can do so.  This is fundamentally incompatible with the aim of
 | 
			
		||||
protecting users' freedom to change the software.  The systematic
 | 
			
		||||
pattern of such abuse occurs in the area of products for individuals to
 | 
			
		||||
use, which is precisely where it is most unacceptable.  Therefore, we
 | 
			
		||||
have designed this version of the GPL to prohibit the practice for those
 | 
			
		||||
products.  If such problems arise substantially in other domains, we
 | 
			
		||||
stand ready to extend this provision to those domains in future versions
 | 
			
		||||
of the GPL, as needed to protect the freedom of users.
 | 
			
		||||
 | 
			
		||||
  Finally, every program is threatened constantly by software patents.
 | 
			
		||||
States should not allow patents to restrict development and use of
 | 
			
		||||
software on general-purpose computers, but in those that do, we wish to
 | 
			
		||||
avoid the special danger that patents applied to a free program could
 | 
			
		||||
make it effectively proprietary.  To prevent this, the GPL assures that
 | 
			
		||||
patents cannot be used to render the program non-free.
 | 
			
		||||
  An older license, called the Affero General Public License and
 | 
			
		||||
published by Affero, was designed to accomplish similar goals.  This is
 | 
			
		||||
a different license, not a version of the Affero GPL, but Affero has
 | 
			
		||||
released a new version of the Affero GPL which permits relicensing under
 | 
			
		||||
this license.
 | 
			
		||||
 | 
			
		||||
  The precise terms and conditions for copying, distribution and
 | 
			
		||||
modification follow.
 | 
			
		||||
@@ -72,7 +60,7 @@ modification follow.
 | 
			
		||||
 | 
			
		||||
  0. Definitions.
 | 
			
		||||
 | 
			
		||||
  "This License" refers to version 3 of the GNU General Public License.
 | 
			
		||||
  "This License" refers to version 3 of the GNU Affero General Public License.
 | 
			
		||||
 | 
			
		||||
  "Copyright" also means copyright-like laws that apply to other kinds of
 | 
			
		||||
works, such as semiconductor masks.
 | 
			
		||||
@@ -549,35 +537,45 @@ to collect a royalty for further conveying from those to whom you convey
 | 
			
		||||
the Program, the only way you could satisfy both those terms and this
 | 
			
		||||
License would be to refrain entirely from conveying the Program.
 | 
			
		||||
 | 
			
		||||
  13. Use with the GNU Affero General Public License.
 | 
			
		||||
  13. Remote Network Interaction; Use with the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
  Notwithstanding any other provision of this License, if you modify the
 | 
			
		||||
Program, your modified version must prominently offer all users
 | 
			
		||||
interacting with it remotely through a computer network (if your version
 | 
			
		||||
supports such interaction) an opportunity to receive the Corresponding
 | 
			
		||||
Source of your version by providing access to the Corresponding Source
 | 
			
		||||
from a network server at no charge, through some standard or customary
 | 
			
		||||
means of facilitating copying of software.  This Corresponding Source
 | 
			
		||||
shall include the Corresponding Source for any work covered by version 3
 | 
			
		||||
of the GNU General Public License that is incorporated pursuant to the
 | 
			
		||||
following paragraph.
 | 
			
		||||
 | 
			
		||||
  Notwithstanding any other provision of this License, you have
 | 
			
		||||
permission to link or combine any covered work with a work licensed
 | 
			
		||||
under version 3 of the GNU Affero General Public License into a single
 | 
			
		||||
under version 3 of the GNU General Public License into a single
 | 
			
		||||
combined work, and to convey the resulting work.  The terms of this
 | 
			
		||||
License will continue to apply to the part which is the covered work,
 | 
			
		||||
but the special requirements of the GNU Affero General Public License,
 | 
			
		||||
section 13, concerning interaction through a network will apply to the
 | 
			
		||||
combination as such.
 | 
			
		||||
but the work with which it is combined will remain governed by version
 | 
			
		||||
3 of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
  14. Revised Versions of this License.
 | 
			
		||||
 | 
			
		||||
  The Free Software Foundation may publish revised and/or new versions of
 | 
			
		||||
the GNU General Public License from time to time.  Such new versions will
 | 
			
		||||
be similar in spirit to the present version, but may differ in detail to
 | 
			
		||||
the GNU Affero General Public License from time to time.  Such new versions
 | 
			
		||||
will be similar in spirit to the present version, but may differ in detail to
 | 
			
		||||
address new problems or concerns.
 | 
			
		||||
 | 
			
		||||
  Each version is given a distinguishing version number.  If the
 | 
			
		||||
Program specifies that a certain numbered version of the GNU General
 | 
			
		||||
Program specifies that a certain numbered version of the GNU Affero General
 | 
			
		||||
Public License "or any later version" applies to it, you have the
 | 
			
		||||
option of following the terms and conditions either of that numbered
 | 
			
		||||
version or of any later version published by the Free Software
 | 
			
		||||
Foundation.  If the Program does not specify a version number of the
 | 
			
		||||
GNU General Public License, you may choose any version ever published
 | 
			
		||||
GNU Affero General Public License, you may choose any version ever published
 | 
			
		||||
by the Free Software Foundation.
 | 
			
		||||
 | 
			
		||||
  If the Program specifies that a proxy can decide which future
 | 
			
		||||
versions of the GNU General Public License can be used, that proxy's
 | 
			
		||||
versions of the GNU Affero General Public License can be used, that proxy's
 | 
			
		||||
public statement of acceptance of a version permanently authorizes you
 | 
			
		||||
to choose that version for the Program.
 | 
			
		||||
 | 
			
		||||
@@ -631,44 +629,33 @@ to attach them to the start of each source file to most effectively
 | 
			
		||||
state the exclusion of warranty; and each file should have at least
 | 
			
		||||
the "copyright" line and a pointer to where the full notice is found.
 | 
			
		||||
 | 
			
		||||
    Vuls - Vulnerability Scanner
 | 
			
		||||
    Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
    <one line to give the program's name and a brief idea of what it does.>
 | 
			
		||||
    Copyright (C) <year>  <name of author>
 | 
			
		||||
 | 
			
		||||
    This program is free software: you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
    it under the terms of the GNU Affero General Public License as published
 | 
			
		||||
    by the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This program is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
    GNU Affero General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
    You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
Also add information on how to contact you by electronic and paper mail.
 | 
			
		||||
 | 
			
		||||
  If the program does terminal interaction, make it output a short
 | 
			
		||||
notice like this when it starts in an interactive mode:
 | 
			
		||||
 | 
			
		||||
    Vuls  Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 | 
			
		||||
    This is free software, and you are welcome to redistribute it
 | 
			
		||||
    under certain conditions; type `show c' for details.
 | 
			
		||||
 | 
			
		||||
The hypothetical commands `show w' and `show c' should show the appropriate
 | 
			
		||||
parts of the General Public License.  Of course, your program's commands
 | 
			
		||||
might be different; for a GUI interface, you would use an "about box".
 | 
			
		||||
  If your software can interact with users remotely through a computer
 | 
			
		||||
network, you should also make sure that it provides a way for users to
 | 
			
		||||
get its source.  For example, if your program is a web application, its
 | 
			
		||||
interface could display a "Source" link that leads users to an archive
 | 
			
		||||
of the code.  There are many ways you could offer source, and different
 | 
			
		||||
solutions will be better for different programs; see section 13 for the
 | 
			
		||||
specific requirements.
 | 
			
		||||
 | 
			
		||||
  You should also get your employer (if you work as a programmer) or school,
 | 
			
		||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
 | 
			
		||||
For more information on this, and how to apply and follow the GNU GPL, see
 | 
			
		||||
<http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
  The GNU General Public License does not permit incorporating your program
 | 
			
		||||
into proprietary programs.  If your program is a subroutine library, you
 | 
			
		||||
may consider it more useful to permit linking proprietary applications with
 | 
			
		||||
the library.  If this is what you want to do, use the GNU Lesser General
 | 
			
		||||
Public License instead of this License.  But first, please read
 | 
			
		||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
 | 
			
		||||
For more information on this, and how to apply and follow the GNU AGPL, see
 | 
			
		||||
<https://www.gnu.org/licenses/>.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										143
									
								
								README.md
									
									
									
									
									
								
							
							
						
						@@ -9,7 +9,7 @@
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
Vulnerability scanner for Linux/FreeBSD, agentless, written in golang.
 | 
			
		||||
Vulnerability scanner for Linux/FreeBSD, agent-less, written in Go.
 | 
			
		||||
We have a slack team. [Join slack team](http://goo.gl/forms/xm5KFo35tu)
 | 
			
		||||
Twitter: [@vuls_en](https://twitter.com/vuls_en)
 | 
			
		||||
 | 
			
		||||
@@ -23,14 +23,14 @@ Twitter: [@vuls_en](https://twitter.com/vuls_en)
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
# Abstract
 | 
			
		||||
## Abstract
 | 
			
		||||
 | 
			
		||||
For a system administrator, having to perform security vulnerability analysis and software update on a daily basis can be a burden.
 | 
			
		||||
To avoid downtime in production environment, it is common for system administrator to choose not to use the automatic update option provided by package manager and to perform update manually.
 | 
			
		||||
To avoid downtime in a production environment, it is common for a system administrator to choose not to use the automatic update option provided by the package manager and to perform update manually.
 | 
			
		||||
This leads to the following problems.
 | 
			
		||||
 | 
			
		||||
- System administrator will have to constantly watch out for any new vulnerabilities in NVD(National Vulnerability Database) or similar databases.
 | 
			
		||||
- It might be impossible for the system administrator to monitor all the software if there are a large number of software installed in server.
 | 
			
		||||
- The system administrator will have to constantly watch out for any new vulnerabilities in NVD (National Vulnerability Database) or similar databases.
 | 
			
		||||
- It might be impossible for the system administrator to monitor all the software if there are a large number of software packages installed in the server.
 | 
			
		||||
- It is expensive to perform analysis to determine the servers affected by new vulnerabilities. The possibility of overlooking a server or two during analysis is there.
 | 
			
		||||
 | 
			
		||||
Vuls is a tool created to solve the problems listed above. It has the following characteristics.
 | 
			
		||||
@@ -38,134 +38,153 @@ Vuls is a tool created to solve the problems listed above. It has the following
 | 
			
		||||
- Informs users of the vulnerabilities that are related to the system.
 | 
			
		||||
- Informs users of the servers that are affected.
 | 
			
		||||
- Vulnerability detection is done automatically to prevent any oversight.
 | 
			
		||||
- Report is generated on regular basis using CRON or other methods. to manage vulnerability.
 | 
			
		||||
- A report is generated on a regular basis using CRON or other methods. to manage vulnerability.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
# Main Features
 | 
			
		||||
## Main Features
 | 
			
		||||
 | 
			
		||||
## Scan for any vulnerabilities in Linux/FreeBSD Server
 | 
			
		||||
### Scan for any vulnerabilities in Linux/FreeBSD Server
 | 
			
		||||
 | 
			
		||||
[Supports major Linux/FreeBSD](https://vuls.io/docs/en/supported-os.html)
 | 
			
		||||
 | 
			
		||||
- Alpine, Ubuntu, Debian, CentOS, Amazon Linux, RHEL, Oracle Linux, SUSE Enterprise Linux and Raspbian, FreeBSD
 | 
			
		||||
- Cloud, on-premise, Docker
 | 
			
		||||
- Alpine, Amazon Linux, CentOS, Debian, Oracle Linux, Raspbian, RHEL, SUSE Enterprise Linux, and Ubuntu
 | 
			
		||||
- FreeBSD
 | 
			
		||||
- Cloud, on-premise, Running Docker Container
 | 
			
		||||
 | 
			
		||||
## High quality scan
 | 
			
		||||
### High-quality scan
 | 
			
		||||
 | 
			
		||||
Vuls uses Multiple vulnerability databases
 | 
			
		||||
- Vulnerability Database
 | 
			
		||||
  - [NVD](https://nvd.nist.gov/)
 | 
			
		||||
  - [JVN(Japanese)](http://jvndb.jvn.jp/apis/myjvn/)
 | 
			
		||||
 | 
			
		||||
- [NVD](https://nvd.nist.gov/)
 | 
			
		||||
- [JVN(Japanese)](http://jvndb.jvn.jp/apis/myjvn/)
 | 
			
		||||
- OVAL
 | 
			
		||||
  - [RedHat](https://www.redhat.com/security/data/oval/)
 | 
			
		||||
  - [Red Hat](https://www.redhat.com/security/data/oval/)
 | 
			
		||||
  - [Debian](https://www.debian.org/security/oval/)
 | 
			
		||||
  - [Ubuntu](https://people.canonical.com/~ubuntu-security/oval/)
 | 
			
		||||
  - [SUSE](http://ftp.suse.com/pub/projects/security/oval/)
 | 
			
		||||
  - [Oracle Linux](https://linux.oracle.com/security/oval/)
 | 
			
		||||
 | 
			
		||||
- [Alpine-secdb](https://git.alpinelinux.org/cgit/alpine-secdb/)
 | 
			
		||||
- [Red Hat Security Advisories](https://access.redhat.com/security/security-updates/)
 | 
			
		||||
- [Debian Security Bug Tracker](https://security-tracker.debian.org/tracker/)
 | 
			
		||||
- Commands(yum, zypper, pkg-audit)
 | 
			
		||||
  - RHSA/ALAS/ELSA/FreeBSD-SA
 | 
			
		||||
- [Exploit Database](https://www.exploit-db.com/)
 | 
			
		||||
- [US-CERT](https://www.us-cert.gov/ncas/alerts)
 | 
			
		||||
- [JPCERT](http://www.jpcert.or.jp/at/2019.html)
 | 
			
		||||
- Changelog
 | 
			
		||||
- Security Advisory
 | 
			
		||||
  - [Alpine-secdb](https://git.alpinelinux.org/cgit/alpine-secdb/)
 | 
			
		||||
  - [Red Hat Security Advisories](https://access.redhat.com/security/security-updates/)
 | 
			
		||||
  - [Debian Security Bug Tracker](https://security-tracker.debian.org/tracker/)
 | 
			
		||||
 | 
			
		||||
## Fast scan and Deep scan
 | 
			
		||||
- Commands(yum, zypper, pkg-audit)
 | 
			
		||||
  - RHSA / ALAS / ELSA / FreeBSD-SA
 | 
			
		||||
  - Changelog
 | 
			
		||||
 | 
			
		||||
- PoC, Exploit
 | 
			
		||||
  - [Exploit Database](https://www.exploit-db.com/)
 | 
			
		||||
  - [Metasploit-Framework modules](https://www.rapid7.com/db/?q=&type=metasploit)
 | 
			
		||||
 | 
			
		||||
- CERT
 | 
			
		||||
  - [US-CERT](https://www.us-cert.gov/ncas/alerts)
 | 
			
		||||
  - [JPCERT](http://www.jpcert.or.jp/at/2019.html)
 | 
			
		||||
 | 
			
		||||
- Libraries
 | 
			
		||||
  - [Node.js Security Working Group](https://github.com/nodejs/security-wg)
 | 
			
		||||
  - [Ruby Advisory Database](https://github.com/rubysec/ruby-advisory-db)
 | 
			
		||||
  - [Safety DB(Python)](https://github.com/pyupio/safety-db)
 | 
			
		||||
  - [PHP Security Advisories Database](https://github.com/FriendsOfPHP/security-advisories)
 | 
			
		||||
  - [RustSec Advisory Database](https://github.com/RustSec/advisory-db)
 | 
			
		||||
 | 
			
		||||
- WordPress
 | 
			
		||||
  - [WPVulnDB](https://wpvulndb.com/api)
 | 
			
		||||
 | 
			
		||||
### Scan mode
 | 
			
		||||
 | 
			
		||||
[Fast Scan](https://vuls.io/docs/en/architecture-fast-scan.html)
 | 
			
		||||
 | 
			
		||||
- Scan without root privilege, no dependencies
 | 
			
		||||
- Almost no load on the scan target server
 | 
			
		||||
- Offline mode scan with no internet access. (Red Hat, CentOS, OracleLinux, Ubuntu, Debian)
 | 
			
		||||
- Offline mode scan with no internet access. (CentOS, Debian, Oracle Linux, Red Hat, and Ubuntu)
 | 
			
		||||
 | 
			
		||||
[Fast Root Scan](https://vuls.io/docs/en/architecture-fast-root-scan.html)
 | 
			
		||||
 | 
			
		||||
- Scan with root privilege
 | 
			
		||||
- Almost no load on the scan target server
 | 
			
		||||
- Detect processes affected by update using yum-ps (RedHat, CentOS, Oracle Linux and Amazon Linux)
 | 
			
		||||
- Detect processes affected by update using yum-ps (Amazon Linux, CentOS, Oracle Linux, and RedHat)
 | 
			
		||||
- Detect processes which updated before but not restarting yet using checkrestart of debian-goodies (Debian and Ubuntu)
 | 
			
		||||
- Offline mode scan with no internet access. (RedHat, CentOS, OracleLinux, Ubuntu, Debian)
 | 
			
		||||
- Offline mode scan with no internet access. (CentOS, Debian, Oracle Linux, Red Hat, and Ubuntu)
 | 
			
		||||
 | 
			
		||||
[Deep Scan](https://vuls.io/docs/en/architecture-deep-scan.html)
 | 
			
		||||
### [Remote, Local scan mode, Server mode](https://vuls.io/docs/en/architecture-remote-local.html)
 | 
			
		||||
 | 
			
		||||
- Scan with root privilege
 | 
			
		||||
- Parses the Changelog
 | 
			
		||||
    Changelog has a history of version changes. When a security issue is fixed, the relevant CVE ID is listed.
 | 
			
		||||
    By parsing the changelog and analysing the updates between the installed version of software on the server and the newest version of that software
 | 
			
		||||
    it's possible to create a list of all vulnerabilities that need to be fixed.
 | 
			
		||||
- Sometimes load on the scan target server
 | 
			
		||||
[Remote scan mode](https://vuls.io/docs/en/architecture-remote-scan.html)
 | 
			
		||||
 | 
			
		||||
## [Remote scan and Local scan](https://vuls.io/docs/en/architecture-remote-local.html)
 | 
			
		||||
- User is required to only set up one machine that is connected to other target servers via SSH
 | 
			
		||||
 | 
			
		||||
[Remote Scan](https://vuls.io/docs/en/architecture-remote-scan.html)
 | 
			
		||||
 | 
			
		||||
- User is required to only setup one machine that is connected to other target servers via SSH
 | 
			
		||||
 | 
			
		||||
[Local Scan](https://vuls.io/docs/en/architecture-local-scan.html)
 | 
			
		||||
[Local scan mode](https://vuls.io/docs/en/architecture-local-scan.html)
 | 
			
		||||
 | 
			
		||||
- If you don't want the central Vuls server to connect to each server by SSH, you can use Vuls in the Local Scan mode.
 | 
			
		||||
 | 
			
		||||
## **Dynamic** Analysis
 | 
			
		||||
[Server mode](https://vuls.io/docs/en/usage-server.html)
 | 
			
		||||
 | 
			
		||||
- First, start Vuls in server mode and listen as an HTTP server.
 | 
			
		||||
- Next, issue a command on the scan target server to collect software information. Then send the result to Vuls Server via HTTP. You receive the scan results as JSON format.
 | 
			
		||||
- No SSH needed, No Scanner needed. Only issuing Linux commands directory on the scan target server.
 | 
			
		||||
 | 
			
		||||
### **Dynamic** Analysis
 | 
			
		||||
 | 
			
		||||
- It is possible to acquire the state of the server by connecting via SSH and executing the command.
 | 
			
		||||
- Vuls warns when the scan target server was updated the kernel etc. but not restarting it.
 | 
			
		||||
 | 
			
		||||
## Scan vulnerabilites of non-OS packages
 | 
			
		||||
### Scan vulnerabilities of non-OS-packages
 | 
			
		||||
 | 
			
		||||
- [Common Platform Enumeration (CPE) based Scan](https://vuls.io/docs/en/usage-scan-non-os-packages.html#how-to-search-cpe-name-by-software-name)
 | 
			
		||||
  - NW equipment, middleware, programming language libraries and framework for vulnerability
 | 
			
		||||
- Integrate with [GitHub Security Alerts](https://vuls.io/docs/en/usage-scan-non-os-packages.html#usage-integrate-with-github-security-alerts)
 | 
			
		||||
- Integrate with [OWASP Dependency Check](https://vuls.io/docs/en/usage-scan-non-os-packages.html#usage-integrate-with-owasp-dependency-check-to-automatic-update-when-the-libraries-are-updated-experimental)
 | 
			
		||||
- Libraries of programming language
 | 
			
		||||
- Self-compiled software
 | 
			
		||||
- Network Devices
 | 
			
		||||
 | 
			
		||||
Vuls has some options to detect the vulnerabilities
 | 
			
		||||
 | 
			
		||||
- [Lockfile based Scan](https://vuls.io/docs/en/usage-scan-non-os-packages.html#library-vulns-scan)
 | 
			
		||||
- [GitHub Integration](https://vuls.io/docs/en/usage-scan-non-os-packages.html#usage-integrate-with-github-security-alerts)
 | 
			
		||||
- [Common Platform Enumeration (CPE) based Scan](https://vuls.io/docs/en/usage-scan-non-os-packages.html#cpe-scan)
 | 
			
		||||
- [OWASP Dependency Check Integration](https://vuls.io/docs/en/usage-scan-non-os-packages.html#usage-integrate-with-owasp-dependency-check-to-automatic-update-when-the-libraries-are-updated-experimental)
 | 
			
		||||
 | 
			
		||||
## Scan WordPress core, themes, plugins
 | 
			
		||||
 | 
			
		||||
- [Scan WordPress](https://vuls.io/docs/en/usage-scan-wordpress.html)
 | 
			
		||||
 | 
			
		||||
## MISC
 | 
			
		||||
 | 
			
		||||
- Nondestructive testing
 | 
			
		||||
- Pre-authorization is *NOT* necessary before scanning on AWS
 | 
			
		||||
  - Vuls works well with Continuous Integration since tests can be run every day. This allows you to find vulnerabilities very quickly.
 | 
			
		||||
- Auto generation of configuration file template
 | 
			
		||||
  - Auto detection of servers set using CIDR, generate configuration file template
 | 
			
		||||
- Auto-generation of configuration file template
 | 
			
		||||
  - Auto-detection of servers set using CIDR, generate configuration file template
 | 
			
		||||
- Email and Slack notification is possible (supports Japanese language)
 | 
			
		||||
- Scan result is viewable on accessory software, TUI Viewer on terminal or Web UI ([VulsRepo](https://github.com/usiusi360/vulsrepo)).
 | 
			
		||||
- Scan result is viewable on accessory software, TUI Viewer in a terminal or Web UI ([VulsRepo](https://github.com/ishiDACo/vulsrepo)).
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
# What Vuls Doesn't Do
 | 
			
		||||
## What Vuls Doesn't Do
 | 
			
		||||
 | 
			
		||||
- Vuls doesn't update the vulnerable packages.
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
# Document
 | 
			
		||||
## Document
 | 
			
		||||
 | 
			
		||||
For more information such as Installation, Tutorial, Usage, visit [vuls.io](https://vuls.io/)
 | 
			
		||||
For more information such as Installation, Tutorial, Usage, visit [vuls.io](https://vuls.io/)  
 | 
			
		||||
[日本語翻訳ドキュメント](https://vuls.io/ja/)
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
# Authors
 | 
			
		||||
## Authors
 | 
			
		||||
 | 
			
		||||
kotakanbe ([@kotakanbe](https://twitter.com/kotakanbe)) created vuls and [these fine people](https://github.com/future-architect/vuls/graphs/contributors) have contributed.
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
# Change Log
 | 
			
		||||
 | 
			
		||||
Please see [CHANGELOG](https://github.com/future-architect/vuls/blob/master/CHANGELOG.md).
 | 
			
		||||
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
# Stargazers over time
 | 
			
		||||
## Stargazers over time
 | 
			
		||||
 | 
			
		||||
[](https://starcharts.herokuapp.com/future-architect/vuls)
 | 
			
		||||
 | 
			
		||||
-----;
 | 
			
		||||
 | 
			
		||||
# License
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
Please see [LICENSE](https://github.com/future-architect/vuls/blob/master/LICENSE).
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2897
									
								
								alert/alert_jp.go
									
									
									
									
									
								
							
							
						
						@@ -1,920 +0,0 @@
 | 
			
		||||
package alert
 | 
			
		||||
 | 
			
		||||
// AlertDictEn has USCERT alerts
 | 
			
		||||
var AlertDictEn = map[string]Alert{
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA08-352A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA08-352A",
 | 
			
		||||
		Title: `Microsoft Internet Explorer Data Binding Vulnerability`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA08-350A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA08-350A",
 | 
			
		||||
		Title: `Apple Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA08-344A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA08-344A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA08-340A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA08-340A",
 | 
			
		||||
		Title: `Sun Java Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA08-319A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA08-319A",
 | 
			
		||||
		Title: `Mozilla Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-132A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-132A",
 | 
			
		||||
		Title: `Microsoft PowerPoint Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-041A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-041A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-343A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-343A",
 | 
			
		||||
		Title: `Adobe Flash Vulnerabilities Affect Flash Player and Adobe AIR`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-218A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-218A",
 | 
			
		||||
		Title: `Apple Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-195A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-195A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-342A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-342A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-286B": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-286B",
 | 
			
		||||
		Title: `Adobe Reader and Acrobat Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-160B": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-160B",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-069A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-069A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-223A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-223A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-013A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-013A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple SMB Protocol Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-294A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-294A",
 | 
			
		||||
		Title: `Oracle Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-020A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-020A",
 | 
			
		||||
		Title: `Microsoft Windows Does Not Disable AutoRun Properly`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-133A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-133A",
 | 
			
		||||
		Title: `Apple Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-022A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-022A",
 | 
			
		||||
		Title: `Apple QuickTime Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-051A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-051A",
 | 
			
		||||
		Title: `Adobe Acrobat and Reader Vulnerability`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-015A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-015A",
 | 
			
		||||
		Title: `Oracle Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-251A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-251A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-209A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-209A",
 | 
			
		||||
		Title: `Microsoft Windows, Internet Explorer, and Active Template Library (ATL) Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-204A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-204A",
 | 
			
		||||
		Title: `Adobe Flash Vulnerability Affects Flash Player and Other Adobe Products`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-161A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-161A",
 | 
			
		||||
		Title: `Adobe Acrobat and Reader Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-133B": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-133B",
 | 
			
		||||
		Title: `Adobe Reader and Acrobat JavaScript Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-088A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-088A",
 | 
			
		||||
		Title: `Conficker Worm Targets Microsoft Windows Systems`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-314A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-314A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-105A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-105A",
 | 
			
		||||
		Title: `Oracle Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-104A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-104A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-286A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-286A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA09-187A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA09-187A",
 | 
			
		||||
		Title: `Microsoft Video ActiveX Control Vulnerability`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-238A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-238A",
 | 
			
		||||
		Title: `Microsoft Windows Insecurely Loads Dynamic Libraries`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-159B": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-159B",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-103B": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-103B",
 | 
			
		||||
		Title: `Oracle Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-021A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-021A",
 | 
			
		||||
		Title: `Microsoft Internet Explorer Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-012A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-012A",
 | 
			
		||||
		Title: `Oracle Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-313A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-313A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-285A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-285A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-263A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-263A",
 | 
			
		||||
		Title: `Adobe Flash Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-103C": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-103C",
 | 
			
		||||
		Title: `Adobe Reader and Acrobat Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-040A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-040A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-194B": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-194B",
 | 
			
		||||
		Title: `Oracle Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-194A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-194A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-131A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-131A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-068A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-068A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-348A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-348A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-257A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-257A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-231A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-231A",
 | 
			
		||||
		Title: `Adobe Reader and Acrobat Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-222A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-222A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-162A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-162A",
 | 
			
		||||
		Title: `Adobe Flash and AIR Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-159A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-159A",
 | 
			
		||||
		Title: `Adobe Flash, Reader, and Acrobat Vulnerability`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-089A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-089A",
 | 
			
		||||
		Title: `Microsoft Internet Explorer Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-013A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-013A",
 | 
			
		||||
		Title: `Adobe Reader and Acrobat Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-287A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-287A",
 | 
			
		||||
		Title: `Oracle Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-279A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-279A",
 | 
			
		||||
		Title: `Adobe Reader and Acrobat Affected by Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-223A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-223A",
 | 
			
		||||
		Title: `Adobe Flash and AIR Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA10-012B": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA10-012B",
 | 
			
		||||
		Title: `Microsoft Windows EOT Font and Adobe Flash Player 6 Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-165A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-165A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-067A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-067A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-039A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-039A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-222A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-222A",
 | 
			
		||||
		Title: `Adobe Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-193A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-193A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-201A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-201A",
 | 
			
		||||
		Title: `Oracle Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-166A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-166A",
 | 
			
		||||
		Title: `Adobe Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-130A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-130A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-312A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-312A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-286A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-286A",
 | 
			
		||||
		Title: `Apple Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-350A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-350A",
 | 
			
		||||
		Title: `Adobe Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-221A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-221A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-256A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-256A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-200A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-200A",
 | 
			
		||||
		Title: `Security Recommendations to Prevent Cyber Intrusions`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-102A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-102A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-011A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-011A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-347A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-347A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA11-284A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA11-284A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-262A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-262A",
 | 
			
		||||
		Title: `Microsoft Security Advisory for Internet Explorer Exploit`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-240A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-240A",
 | 
			
		||||
		Title: `Oracle Java 7 Security Manager Bypass Vulnerability`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-227A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-227A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-129A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-129A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-101B": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-101B",
 | 
			
		||||
		Title: `Adobe Reader and Acrobat Security Updates and Architectural Improvements`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-010A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-010A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-006A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-006A",
 | 
			
		||||
		Title: `Wi-Fi Protected Setup (WPS) Vulnerable to Brute-Force Attack`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-265A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-265A",
 | 
			
		||||
		Title: `Microsoft Releases Patch for Internet Explorer Exploit`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-255A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-255A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-251A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-251A",
 | 
			
		||||
		Title: `Microsoft Update For Minimum Certificate Key Length`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-174A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-174A",
 | 
			
		||||
		Title: `Microsoft XML Core Services Attack Activity`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-164A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-164A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-101A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-101A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-318A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-318A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-283A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-283A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-346A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-346A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-192A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-192A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-073A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-073A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-045A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-045A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA12-024A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA12-024A",
 | 
			
		||||
		Title: `"Anonymous" DDoS Activity`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-134A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-134A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-043B": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-043B",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-008A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-008A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-051A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-051A",
 | 
			
		||||
		Title: `Oracle Java Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-043A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-043A",
 | 
			
		||||
		Title: `Adobe Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-225A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-225A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-207A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-207A",
 | 
			
		||||
		Title: `Risks of Using the Intelligent Platform Management Interface (IPMI)`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-141A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-141A",
 | 
			
		||||
		Title: `Washington, DC Radio Station Web Site Compromises`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-175A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-175A",
 | 
			
		||||
		Title: `Risks of Default Passwords on the Internet`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-169A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-169A",
 | 
			
		||||
		Title: `Oracle Releases Updates for Javadoc and Other Java SE Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-168A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-168A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-100A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-100A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-088A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-088A",
 | 
			
		||||
		Title: `DNS Amplification Attacks`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-317A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-317A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-309A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-309A",
 | 
			
		||||
		Title: `CryptoLocker Ransomware Infections`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-288A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-288A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-064A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-064A",
 | 
			
		||||
		Title: `Oracle Java Contains Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-032A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-032A",
 | 
			
		||||
		Title: `Oracle Java Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-024A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-024A",
 | 
			
		||||
		Title: `Content Management Systems Security and Associated Risks`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-107A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-107A",
 | 
			
		||||
		Title: `Oracle Has Released Multiple Updates for Java SE`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-071A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-071A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-015A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-015A",
 | 
			
		||||
		Title: `Microsoft Releases Update for Internet Explorer Vulnerability CVE-2012-4792`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-010A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-010A",
 | 
			
		||||
		Title: `Oracle Java 7 Security Manager Bypass Vulnerability`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-253A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-253A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-193A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-193A",
 | 
			
		||||
		Title: `Exploit Tool Targets Vulnerabilities in McAfee ePolicy Orchestrator (ePO)`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA13-190A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA13-190A",
 | 
			
		||||
		Title: `Microsoft Updates for Multiple Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-323A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-323A",
 | 
			
		||||
		Title: `Microsoft Windows Kerberos KDC Remote Privilege Escalation Vulnerability `,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-300A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-300A",
 | 
			
		||||
		Title: `Phishing Campaign Linked with “Dyre” Banking Malware`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-295A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-295A",
 | 
			
		||||
		Title: `Crypto Ransomware`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-318B": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-318B",
 | 
			
		||||
		Title: `Microsoft Windows OLE Automation Array Remote Code Execution Vulnerability `,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-317A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-317A",
 | 
			
		||||
		Title: `Apple iOS 'Masque Attack' Technique`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-290A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-290A",
 | 
			
		||||
		Title: `SSL 3.0 Protocol Vulnerability and POODLE Attack`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-017A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-017A",
 | 
			
		||||
		Title: `UDP-Based Amplification Attacks`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-002A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-002A",
 | 
			
		||||
		Title: `Malware Targeting Point of Sale Systems`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-318A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-318A",
 | 
			
		||||
		Title: `Microsoft Secure Channel (Schannel) Vulnerability (CVE-2014-6321) `,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-310A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-310A",
 | 
			
		||||
		Title: `Microsoft Ending Support for Windows Server 2003 Operating System`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-268A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-268A",
 | 
			
		||||
		Title: `GNU Bourne-Again Shell (Bash) ‘Shellshock’ Vulnerability (CVE-2014-6271, CVE-2014-7169, CVE-2014-7186, CVE-2014-7187, CVE-2014-6277 and CVE 2014-6278) `,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-098A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-098A",
 | 
			
		||||
		Title: `OpenSSL 'Heartbleed' vulnerability (CVE-2014-0160)`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-353A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-353A",
 | 
			
		||||
		Title: `Targeted Destructive Malware`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-329A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-329A",
 | 
			
		||||
		Title: `Regin Malware`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-212A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-212A",
 | 
			
		||||
		Title: `Backoff Point-of-Sale Malware`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-150A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-150A",
 | 
			
		||||
		Title: `GameOver Zeus P2P Malware`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA14-013A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA14-013A",
 | 
			
		||||
		Title: `NTP Amplification Attacks Using CVE-2013-5211`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA15-195A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA15-195A",
 | 
			
		||||
		Title: `Adobe Flash and Microsoft Windows Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA15-337A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA15-337A",
 | 
			
		||||
		Title: `Dorkbot`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA15-240A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA15-240A",
 | 
			
		||||
		Title: `Controlling Outbound DNS Access`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA15-213A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA15-213A",
 | 
			
		||||
		Title: `Recent Email Phishing Campaigns – Mitigation and Response Recommendations`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA15-120A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA15-120A",
 | 
			
		||||
		Title: `Securing End-to-End Communications`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA15-119A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA15-119A",
 | 
			
		||||
		Title: `Top 30 Targeted High Risk Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA15-105A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA15-105A",
 | 
			
		||||
		Title: `Simda Botnet`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA15-103A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA15-103A",
 | 
			
		||||
		Title: `DNS Zone Transfer AXFR Requests May Leak Domain Information`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA15-098A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA15-098A",
 | 
			
		||||
		Title: `AAEH`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA15-314A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA15-314A",
 | 
			
		||||
		Title: `Compromised Web Servers and Web Shells - Threat Awareness and Guidance `,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA15-286A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA15-286A",
 | 
			
		||||
		Title: `Dridex P2P Malware`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA15-051A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA15-051A",
 | 
			
		||||
		Title: `Lenovo Superfish Adware Vulnerable to HTTPS Spoofing`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA16-187A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA16-187A",
 | 
			
		||||
		Title: `Symantec and Norton Security Products Contain Critical Vulnerabilities`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA16-144A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA16-144A",
 | 
			
		||||
		Title: `WPAD Name Collision Vulnerability`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA16-132A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA16-132A",
 | 
			
		||||
		Title: `Exploitation of SAP Business Applications`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA16-105A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA16-105A",
 | 
			
		||||
		Title: `Apple Ends Support for QuickTime for Windows; New Vulnerabilities Announced`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA16-091A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA16-091A",
 | 
			
		||||
		Title: `Ransomware and Recent Variants`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA16-336A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA16-336A",
 | 
			
		||||
		Title: `Avalanche (crimeware-as-a-service infrastructure)`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA16-288A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA16-288A",
 | 
			
		||||
		Title: `Heightened DDoS Threat Posed by Mirai and Other Botnets`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA16-250A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA16-250A",
 | 
			
		||||
		Title: `The Increasing Threat to Network Infrastructure Devices and Recommended Mitigations`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA17-117A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA17-117A",
 | 
			
		||||
		Title: `Intrusions Affecting Multiple Victims Across Multiple Sectors`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA17-318B": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA17-318B",
 | 
			
		||||
		Title: `HIDDEN COBRA – North Korean Trojan: Volgmer`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA17-318A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA17-318A",
 | 
			
		||||
		Title: `HIDDEN COBRA – North Korean Remote Administration Tool: FALLCHILL`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA17-181A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA17-181A",
 | 
			
		||||
		Title: `Petya Ransomware `,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA17-132A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA17-132A",
 | 
			
		||||
		Title: `Indicators Associated With WannaCry Ransomware`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA17-075A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA17-075A",
 | 
			
		||||
		Title: `HTTPS Interception Weakens TLS Security`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA17-293A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA17-293A",
 | 
			
		||||
		Title: `Advanced Persistent Threat Activity Targeting Energy and Other Critical Infrastructure Sectors`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA17-164A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA17-164A",
 | 
			
		||||
		Title: `HIDDEN COBRA – North Korea’s DDoS Botnet Infrastructure`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA17-163A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA17-163A",
 | 
			
		||||
		Title: `CrashOverride Malware`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA17-156A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA17-156A",
 | 
			
		||||
		Title: `Reducing the Risk of SNMP Abuse`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA18-141A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA18-141A",
 | 
			
		||||
		Title: `Side-Channel Vulnerability Variants 3a and 4`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA18-086A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA18-086A",
 | 
			
		||||
		Title: `Brute Force Attacks Conducted by Cyber Actors `,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA18-004A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA18-004A",
 | 
			
		||||
		Title: `Meltdown and Spectre Side-Channel Vulnerability Guidance`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA18-331A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA18-331A",
 | 
			
		||||
		Title: `3ve – Major Online Ad Fraud Operation`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/AA18-284A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/AA18-284A",
 | 
			
		||||
		Title: `Publicly Available Tools Seen in Cyber Incidents Worldwide`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA18-276B": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA18-276B",
 | 
			
		||||
		Title: `Advanced Persistent Threat Activity Exploiting Managed Service Providers`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA18-275A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA18-275A",
 | 
			
		||||
		Title: `HIDDEN COBRA – FASTCash Campaign`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA18-201A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA18-201A",
 | 
			
		||||
		Title: `Emotet Malware`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA18-276A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA18-276A",
 | 
			
		||||
		Title: `Using Rigorous Credential Control to Mitigate Trusted Network Exploitation`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA18-149A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA18-149A",
 | 
			
		||||
		Title: `HIDDEN COBRA – Joanap Backdoor Trojan and Brambul Server Message Block Worm`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA18-145A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA18-145A",
 | 
			
		||||
		Title: `Cyber Actors Target Home and Office Routers and Networked Devices Worldwide`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA18-106A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA18-106A",
 | 
			
		||||
		Title: `Russian State-Sponsored Cyber Actors Targeting Network Infrastructure Devices`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
	"https://www.us-cert.gov/ncas/alerts/TA18-074A": {
 | 
			
		||||
		URL:   "https://www.us-cert.gov/ncas/alerts/TA18-074A",
 | 
			
		||||
		Title: `Russian Government Cyber Activity Targeting Energy and Other Critical Infrastructure Sectors`,
 | 
			
		||||
		Team:  "us",
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										534
									
								
								alert/cve_jp.go
									
									
									
									
									
								
							
							
						
						@@ -1,534 +0,0 @@
 | 
			
		||||
package alert
 | 
			
		||||
 | 
			
		||||
// CveDictJa has CVE-ID key which included JPCERT alerts
 | 
			
		||||
var CveDictJa = map[string][]string{
 | 
			
		||||
	"CVE-2006-0003":    {"https://www.jpcert.or.jp/at/2007/at070016.html"},
 | 
			
		||||
	"CVE-2006-0005":    {"https://www.jpcert.or.jp/at/2007/at070016.html"},
 | 
			
		||||
	"CVE-2006-1173":    {"https://www.jpcert.or.jp/at/2006/at060008.html"},
 | 
			
		||||
	"CVE-2006-3014":    {"https://www.jpcert.or.jp/at/2006/at060009.html"},
 | 
			
		||||
	"CVE-2006-3059":    {"https://www.jpcert.or.jp/at/2006/at060009.html"},
 | 
			
		||||
	"CVE-2006-3086":    {"https://www.jpcert.or.jp/at/2006/at060009.html"},
 | 
			
		||||
	"CVE-2006-3643":    {"https://www.jpcert.or.jp/at/2007/at070016.html"},
 | 
			
		||||
	"CVE-2006-3730":    {"https://www.jpcert.or.jp/at/2007/at070016.html"},
 | 
			
		||||
	"CVE-2006-3877":    {"https://www.jpcert.or.jp/at/2007/at070005.html"},
 | 
			
		||||
	"CVE-2006-5198":    {"https://www.jpcert.or.jp/at/2007/at070016.html"},
 | 
			
		||||
	"CVE-2006-5745":    {"https://www.jpcert.or.jp/at/2007/at070016.html"},
 | 
			
		||||
	"CVE-2007-0015":    {"https://www.jpcert.or.jp/at/2007/at070016.html"},
 | 
			
		||||
	"CVE-2007-0038":    {"https://www.jpcert.or.jp/at/2007/at070016.html"},
 | 
			
		||||
	"CVE-2008-4609":    {"https://www.jpcert.or.jp/at/2009/at090019.html"},
 | 
			
		||||
	"CVE-2010-0886":    {"https://www.jpcert.or.jp/at/2010/at100010.html"},
 | 
			
		||||
	"CVE-2010-0887":    {"https://www.jpcert.or.jp/at/2010/at100010.html"},
 | 
			
		||||
	"CVE-2011-1910":    {"https://www.jpcert.or.jp/at/2011/at110014.html"},
 | 
			
		||||
	"CVE-2011-2444":    {"https://www.jpcert.or.jp/at/2011/at110026.html"},
 | 
			
		||||
	"CVE-2011-2462":    {"https://www.jpcert.or.jp/at/2011/at110034.html"},
 | 
			
		||||
	"CVE-2011-2465":    {"https://www.jpcert.or.jp/at/2011/at110019.html"},
 | 
			
		||||
	"CVE-2011-3192":    {"https://www.jpcert.or.jp/at/2011/at110023.html"},
 | 
			
		||||
	"CVE-2011-3348":    {"https://www.jpcert.or.jp/at/2011/at110023.html"},
 | 
			
		||||
	"CVE-2011-3544":    {"https://www.jpcert.or.jp/at/2011/at110032.html"},
 | 
			
		||||
	"CVE-2011-4313":    {"https://www.jpcert.or.jp/at/2011/at110031.html"},
 | 
			
		||||
	"CVE-2012-0002":    {"https://www.jpcert.or.jp/at/2012/at120009.html"},
 | 
			
		||||
	"CVE-2012-0507":    {"https://www.jpcert.or.jp/at/2012/at120010.html"},
 | 
			
		||||
	"CVE-2012-0767":    {"https://www.jpcert.or.jp/at/2012/at120006.html"},
 | 
			
		||||
	"CVE-2012-0779":    {"https://www.jpcert.or.jp/at/2012/at120014.html"},
 | 
			
		||||
	"CVE-2012-0830":    {"https://www.jpcert.or.jp/at/2012/at120004.html"},
 | 
			
		||||
	"CVE-2012-2311":    {"https://www.jpcert.or.jp/at/2012/at120016.html"},
 | 
			
		||||
	"CVE-2012-4244":    {"https://www.jpcert.or.jp/at/2012/at120029.html"},
 | 
			
		||||
	"CVE-2012-4681":    {"https://www.jpcert.or.jp/at/2012/at120028.html"},
 | 
			
		||||
	"CVE-2012-4969":    {"https://www.jpcert.or.jp/at/2012/at120030.html"},
 | 
			
		||||
	"CVE-2012-5166":    {"https://www.jpcert.or.jp/at/2012/at120033.html"},
 | 
			
		||||
	"CVE-2013-0422":    {"https://www.jpcert.or.jp/at/2013/at130004.html"},
 | 
			
		||||
	"CVE-2013-1493":    {"https://www.jpcert.or.jp/at/2013/at130014.html"},
 | 
			
		||||
	"CVE-2013-2266":    {"https://www.jpcert.or.jp/at/2013/at130017.html"},
 | 
			
		||||
	"CVE-2013-2494":    {"https://www.jpcert.or.jp/at/2013/at130017.html"},
 | 
			
		||||
	"CVE-2013-3893":    {"https://www.jpcert.or.jp/at/2013/at130040.html", "https://www.jpcert.or.jp/at/2013/at130041.html"},
 | 
			
		||||
	"CVE-2013-3906":    {"https://www.jpcert.or.jp/at/2013/at130044.html"},
 | 
			
		||||
	"CVE-2013-3918":    {"https://www.jpcert.or.jp/at/2013/at130045.html"},
 | 
			
		||||
	"CVE-2013-3919":    {"https://www.jpcert.or.jp/at/2013/at130026.html"},
 | 
			
		||||
	"CVE-2013-4854":    {"https://www.jpcert.or.jp/at/2013/at130034.html"},
 | 
			
		||||
	"CVE-2014-0050":    {"https://www.jpcert.or.jp/at/2014/at140007.html"},
 | 
			
		||||
	"CVE-2014-0160":    {"https://www.jpcert.or.jp/at/2014/at140013.html"},
 | 
			
		||||
	"CVE-2014-0322":    {"https://www.jpcert.or.jp/at/2014/at140009.html"},
 | 
			
		||||
	"CVE-2014-1776":    {"https://www.jpcert.or.jp/at/2014/at140018.html", "https://www.jpcert.or.jp/at/2014/at140020.html"},
 | 
			
		||||
	"CVE-2014-3383":    {"https://www.jpcert.or.jp/at/2015/at150021.html"},
 | 
			
		||||
	"CVE-2014-3859":    {"https://www.jpcert.or.jp/at/2014/at140027.html"},
 | 
			
		||||
	"CVE-2014-4114":    {"https://www.jpcert.or.jp/at/2014/at140039.html"},
 | 
			
		||||
	"CVE-2014-6271":    {"https://www.jpcert.or.jp/at/2014/at140037.html", "https://www.jpcert.or.jp/at/2014/at140038.html"},
 | 
			
		||||
	"CVE-2014-6277":    {"https://www.jpcert.or.jp/at/2014/at140037.html"},
 | 
			
		||||
	"CVE-2014-6278":    {"https://www.jpcert.or.jp/at/2014/at140037.html"},
 | 
			
		||||
	"CVE-2014-6324":    {"https://www.jpcert.or.jp/at/2014/at140048.html"},
 | 
			
		||||
	"CVE-2014-6332":    {"https://www.jpcert.or.jp/at/2015/at150015.html"},
 | 
			
		||||
	"CVE-2014-6352":    {"https://www.jpcert.or.jp/at/2014/at140043.html"},
 | 
			
		||||
	"CVE-2014-7169":    {"https://www.jpcert.or.jp/at/2014/at140037.html"},
 | 
			
		||||
	"CVE-2014-7186":    {"https://www.jpcert.or.jp/at/2014/at140037.html"},
 | 
			
		||||
	"CVE-2014-7187":    {"https://www.jpcert.or.jp/at/2014/at140037.html"},
 | 
			
		||||
	"CVE-2014-8361":    {"https://www.jpcert.or.jp/at/2017/at170049.html"},
 | 
			
		||||
	"CVE-2014-8500":    {"https://www.jpcert.or.jp/at/2014/at140050.html"},
 | 
			
		||||
	"CVE-2014-9163":    {"https://www.jpcert.or.jp/at/2014/at140052.html"},
 | 
			
		||||
	"CVE-2015-0313":    {"https://www.jpcert.or.jp/at/2015/at150015.html"},
 | 
			
		||||
	"CVE-2015-1769":    {"https://www.jpcert.or.jp/at/2015/at150028.html"},
 | 
			
		||||
	"CVE-2015-5119":    {"https://www.jpcert.or.jp/at/2015/at150019.html"},
 | 
			
		||||
	"CVE-2015-5122":    {"https://www.jpcert.or.jp/at/2015/at150020.html"},
 | 
			
		||||
	"CVE-2015-5123":    {"https://www.jpcert.or.jp/at/2015/at150020.html"},
 | 
			
		||||
	"CVE-2015-5477":    {"https://www.jpcert.or.jp/at/2015/at150027.html"},
 | 
			
		||||
	"CVE-2015-5986":    {"https://www.jpcert.or.jp/at/2015/at150031.html"},
 | 
			
		||||
	"CVE-2015-6835":    {"https://www.jpcert.or.jp/at/2016/at160036.html"},
 | 
			
		||||
	"CVE-2015-7547":    {"https://www.jpcert.or.jp/at/2016/at160009.html"},
 | 
			
		||||
	"CVE-2015-7645":    {"https://www.jpcert.or.jp/at/2015/at150036.html", "https://www.jpcert.or.jp/at/2015/at150037.html"},
 | 
			
		||||
	"CVE-2015-8000":    {"https://www.jpcert.or.jp/at/2015/at150043.html"},
 | 
			
		||||
	"CVE-2015-8461":    {"https://www.jpcert.or.jp/at/2015/at150043.html"},
 | 
			
		||||
	"CVE-2015-8562":    {"https://www.jpcert.or.jp/at/2016/at160036.html"},
 | 
			
		||||
	"CVE-2015-8651":    {"https://www.jpcert.or.jp/at/2016/at160001.html"},
 | 
			
		||||
	"CVE-2015-8704":    {"https://www.jpcert.or.jp/at/2016/at160006.html"},
 | 
			
		||||
	"CVE-2015-8705":    {"https://www.jpcert.or.jp/at/2016/at160006.html"},
 | 
			
		||||
	"CVE-2016-0189":    {"https://www.jpcert.or.jp/at/2016/at160022.html"},
 | 
			
		||||
	"CVE-2016-0636":    {"https://www.jpcert.or.jp/at/2016/at160015.html"},
 | 
			
		||||
	"CVE-2016-0800":    {"https://www.jpcert.or.jp/at/2016/at160010.html"},
 | 
			
		||||
	"CVE-2016-1000109": {"https://www.jpcert.or.jp/at/2016/at160031.html"},
 | 
			
		||||
	"CVE-2016-1000110": {"https://www.jpcert.or.jp/at/2016/at160031.html"},
 | 
			
		||||
	"CVE-2016-1010":    {"https://www.jpcert.or.jp/at/2016/at160014.html"},
 | 
			
		||||
	"CVE-2016-1019":    {"https://www.jpcert.or.jp/at/2016/at160016.html"},
 | 
			
		||||
	"CVE-2016-1204":    {"https://www.jpcert.or.jp/at/2016/at160019.html"},
 | 
			
		||||
	"CVE-2016-1286":    {"https://www.jpcert.or.jp/at/2016/at160013.html", "https://www.jpcert.or.jp/at/2016/at160037.html"},
 | 
			
		||||
	"CVE-2016-2776":    {"https://www.jpcert.or.jp/at/2016/at160037.html"},
 | 
			
		||||
	"CVE-2016-3081":    {"https://www.jpcert.or.jp/at/2016/at160020.html"},
 | 
			
		||||
	"CVE-2016-3227":    {"https://www.jpcert.or.jp/at/2016/at160025.html"},
 | 
			
		||||
	"CVE-2016-3714":    {"https://www.jpcert.or.jp/at/2016/at160021.html"},
 | 
			
		||||
	"CVE-2016-3715":    {"https://www.jpcert.or.jp/at/2016/at160021.html"},
 | 
			
		||||
	"CVE-2016-3716":    {"https://www.jpcert.or.jp/at/2016/at160021.html"},
 | 
			
		||||
	"CVE-2016-3717":    {"https://www.jpcert.or.jp/at/2016/at160021.html"},
 | 
			
		||||
	"CVE-2016-3718":    {"https://www.jpcert.or.jp/at/2016/at160021.html"},
 | 
			
		||||
	"CVE-2016-4117":    {"https://www.jpcert.or.jp/at/2016/at160024.html"},
 | 
			
		||||
	"CVE-2016-4171":    {"https://www.jpcert.or.jp/at/2016/at160026.html"},
 | 
			
		||||
	"CVE-2016-4438":    {"https://www.jpcert.or.jp/at/2016/at160027.html"},
 | 
			
		||||
	"CVE-2016-5385":    {"https://www.jpcert.or.jp/at/2016/at160031.html"},
 | 
			
		||||
	"CVE-2016-5386":    {"https://www.jpcert.or.jp/at/2016/at160031.html"},
 | 
			
		||||
	"CVE-2016-5387":    {"https://www.jpcert.or.jp/at/2016/at160031.html"},
 | 
			
		||||
	"CVE-2016-5388":    {"https://www.jpcert.or.jp/at/2016/at160031.html"},
 | 
			
		||||
	"CVE-2016-6307":    {"https://www.jpcert.or.jp/at/2016/at160038.html"},
 | 
			
		||||
	"CVE-2016-6309":    {"https://www.jpcert.or.jp/at/2016/at160038.html"},
 | 
			
		||||
	"CVE-2016-7189":    {"https://www.jpcert.or.jp/at/2016/at160039.html"},
 | 
			
		||||
	"CVE-2016-7836":    {"https://www.jpcert.or.jp/at/2016/at160051.html", "https://www.jpcert.or.jp/at/2017/at170023.html"},
 | 
			
		||||
	"CVE-2016-7855":    {"https://www.jpcert.or.jp/at/2016/at160039.html", "https://www.jpcert.or.jp/at/2016/at160043.html"},
 | 
			
		||||
	"CVE-2016-7892":    {"https://www.jpcert.or.jp/at/2016/at160048.html", "https://www.jpcert.or.jp/at/2016/at160049.html"},
 | 
			
		||||
	"CVE-2016-8864":    {"https://www.jpcert.or.jp/at/2016/at160044.html"},
 | 
			
		||||
	"CVE-2016-9131":    {"https://www.jpcert.or.jp/at/2017/at170004.html"},
 | 
			
		||||
	"CVE-2016-9147":    {"https://www.jpcert.or.jp/at/2017/at170004.html"},
 | 
			
		||||
	"CVE-2016-9444":    {"https://www.jpcert.or.jp/at/2017/at170004.html"},
 | 
			
		||||
	"CVE-2016-9778":    {"https://www.jpcert.or.jp/at/2017/at170004.html"},
 | 
			
		||||
	"CVE-2017-0093":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0106":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0145":    {"https://www.jpcert.or.jp/at/2017/at170020.html"},
 | 
			
		||||
	"CVE-2017-0158":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0160":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0161":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-0162":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0163":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0180":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0181":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0199":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0200":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0201":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0202":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0205":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0210":    {"https://www.jpcert.or.jp/at/2017/at170015.html"},
 | 
			
		||||
	"CVE-2017-0221":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0222":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0224":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0227":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0228":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0229":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0235":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0236":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0240":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0250":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-0261":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0263":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0266":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0272":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0277":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0278":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0279":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0283":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-0290":    {"https://www.jpcert.or.jp/at/2017/at170019.html"},
 | 
			
		||||
	"CVE-2017-0291":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-0292":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-0293":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-0294":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-0781":    {"https://www.jpcert.or.jp/at/2017/at170037.html"},
 | 
			
		||||
	"CVE-2017-0782":    {"https://www.jpcert.or.jp/at/2017/at170037.html"},
 | 
			
		||||
	"CVE-2017-0783":    {"https://www.jpcert.or.jp/at/2017/at170037.html"},
 | 
			
		||||
	"CVE-2017-0785":    {"https://www.jpcert.or.jp/at/2017/at170037.html"},
 | 
			
		||||
	"CVE-2017-1000250": {"https://www.jpcert.or.jp/at/2017/at170037.html"},
 | 
			
		||||
	"CVE-2017-1000251": {"https://www.jpcert.or.jp/at/2017/at170037.html"},
 | 
			
		||||
	"CVE-2017-10271":   {"https://www.jpcert.or.jp/at/2018/at180004.html"},
 | 
			
		||||
	"CVE-2017-10845":   {"https://www.jpcert.or.jp/at/2017/at170034.html"},
 | 
			
		||||
	"CVE-2017-10846":   {"https://www.jpcert.or.jp/at/2017/at170034.html"},
 | 
			
		||||
	"CVE-2017-11223":   {"https://www.jpcert.or.jp/at/2017/at170031.html"},
 | 
			
		||||
	"CVE-2017-11292":   {"https://www.jpcert.or.jp/at/2017/at170040.html"},
 | 
			
		||||
	"CVE-2017-11762":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11763":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11764":   {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-11766":   {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-11771":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11779":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11792":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11793":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11796":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11798":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11799":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11800":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11802":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11804":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11805":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11806":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11807":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11808":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11809":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11810":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11811":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11812":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11813":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11819":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11821":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11822":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11826":   {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-11836":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11837":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11838":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11839":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11840":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11841":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11843":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11845":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11846":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11855":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11856":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11858":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11861":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11862":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11866":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11869":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11870":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11871":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11873":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11882":   {"https://www.jpcert.or.jp/at/2017/at170044.html"},
 | 
			
		||||
	"CVE-2017-11886":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11888":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11889":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11890":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11893":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11894":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11895":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11901":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11903":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11905":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11907":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11908":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11909":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11910":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11911":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11912":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11914":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11918":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11930":   {"https://www.jpcert.or.jp/at/2017/at170048.html"},
 | 
			
		||||
	"CVE-2017-11937":   {"https://www.jpcert.or.jp/at/2017/at170046.html"},
 | 
			
		||||
	"CVE-2017-12615":   {"https://www.jpcert.or.jp/at/2017/at170038.html"},
 | 
			
		||||
	"CVE-2017-12616":   {"https://www.jpcert.or.jp/at/2017/at170038.html"},
 | 
			
		||||
	"CVE-2017-12617":   {"https://www.jpcert.or.jp/at/2017/at170038.html"},
 | 
			
		||||
	"CVE-2017-13872":   {"https://www.jpcert.or.jp/at/2017/at170045.html"},
 | 
			
		||||
	"CVE-2017-14315":   {"https://www.jpcert.or.jp/at/2017/at170037.html"},
 | 
			
		||||
	"CVE-2017-3135":    {"https://www.jpcert.or.jp/at/2017/at170007.html"},
 | 
			
		||||
	"CVE-2017-3136":    {"https://www.jpcert.or.jp/at/2017/at170016.html"},
 | 
			
		||||
	"CVE-2017-3137":    {"https://www.jpcert.or.jp/at/2017/at170016.html"},
 | 
			
		||||
	"CVE-2017-3138":    {"https://www.jpcert.or.jp/at/2017/at170016.html"},
 | 
			
		||||
	"CVE-2017-3142":    {"https://www.jpcert.or.jp/at/2017/at170024.html"},
 | 
			
		||||
	"CVE-2017-3143":    {"https://www.jpcert.or.jp/at/2017/at170024.html"},
 | 
			
		||||
	"CVE-2017-3145":    {"https://www.jpcert.or.jp/at/2018/at180005.html"},
 | 
			
		||||
	"CVE-2017-5638":    {"https://www.jpcert.or.jp/at/2017/at170009.html"},
 | 
			
		||||
	"CVE-2017-6753":    {"https://www.jpcert.or.jp/at/2017/at170028.html"},
 | 
			
		||||
	"CVE-2017-8463":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8464":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8496":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8497":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8499":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8517":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8520":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8522":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8524":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8527":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8528":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8543":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8548":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8549":    {"https://www.jpcert.or.jp/at/2017/at170022.html"},
 | 
			
		||||
	"CVE-2017-8584":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8589":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8591":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8594":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8595":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8596":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8598":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8601":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8603":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8604":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8605":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8606":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8607":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8608":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8609":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8610":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8617":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8618":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8619":    {"https://www.jpcert.or.jp/at/2017/at170027.html"},
 | 
			
		||||
	"CVE-2017-8620":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8622":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8628":    {"https://www.jpcert.or.jp/at/2017/at170037.html"},
 | 
			
		||||
	"CVE-2017-8634":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8635":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8636":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8638":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8639":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8640":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8641":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8645":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8646":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8647":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8649":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8653":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8655":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8656":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8657":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8660":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8661":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8669":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8670":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8671":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8672":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8674":    {"https://www.jpcert.or.jp/at/2017/at170032.html"},
 | 
			
		||||
	"CVE-2017-8676":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8682":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8686":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8696":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8727":    {"https://www.jpcert.or.jp/at/2017/at170039.html"},
 | 
			
		||||
	"CVE-2017-8728":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8729":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8731":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8734":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8737":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8738":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8740":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8741":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8747":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8748":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8749":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8750":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8751":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8752":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8753":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8755":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8756":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8757":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-8759":    {"https://www.jpcert.or.jp/at/2017/at170036.html"},
 | 
			
		||||
	"CVE-2017-9791":    {"https://www.jpcert.or.jp/at/2017/at170025.html"},
 | 
			
		||||
	"CVE-2017-9805":    {"https://www.jpcert.or.jp/at/2017/at170033.html"},
 | 
			
		||||
	"CVE-2018-0171":    {"https://www.jpcert.or.jp/at/2018/at180013.html"},
 | 
			
		||||
	"CVE-2018-0758":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0762":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0763":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0767":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0769":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0770":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0772":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0773":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0774":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0775":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0776":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0777":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0778":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0780":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0781":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0797":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0800":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0802":    {"https://www.jpcert.or.jp/at/2018/at180002.html"},
 | 
			
		||||
	"CVE-2018-0825":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0834":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0835":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0837":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0838":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0840":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0852":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0856":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0857":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0859":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0860":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0861":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-0870":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-0872":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0874":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0876":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0889":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0893":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0930":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0931":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0932":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0933":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0934":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0936":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0937":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0939":    {"https://www.jpcert.or.jp/at/2018/at180011.html"},
 | 
			
		||||
	"CVE-2018-0943":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-0945":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-0946":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-0950":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-0951":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-0953":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-0954":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-0955":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-0959":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-0961":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-0965":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-0979":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-0980":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-0981":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-0988":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-0990":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-0991":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-0993":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-0994":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-0995":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-0996":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-1000":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-1004":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-1010":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-1012":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-1013":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-1015":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-1016":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-1018":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-1019":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-1020":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-1022":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-1023":    {"https://www.jpcert.or.jp/at/2018/at180016.html"},
 | 
			
		||||
	"CVE-2018-11776":   {"https://www.jpcert.or.jp/at/2018/at180036.html"},
 | 
			
		||||
	"CVE-2018-1270":    {"https://www.jpcert.or.jp/at/2018/at180014.html"},
 | 
			
		||||
	"CVE-2018-1271":    {"https://www.jpcert.or.jp/at/2018/at180014.html"},
 | 
			
		||||
	"CVE-2018-1272":    {"https://www.jpcert.or.jp/at/2018/at180014.html"},
 | 
			
		||||
	"CVE-2018-1273":    {"https://www.jpcert.or.jp/at/2018/at180017.html"},
 | 
			
		||||
	"CVE-2018-1274":    {"https://www.jpcert.or.jp/at/2018/at180017.html"},
 | 
			
		||||
	"CVE-2018-1275":    {"https://www.jpcert.or.jp/at/2018/at180014.html"},
 | 
			
		||||
	"CVE-2018-12794":   {"https://www.jpcert.or.jp/at/2018/at180039.html"},
 | 
			
		||||
	"CVE-2018-1336":    {"https://www.jpcert.or.jp/at/2018/at180030.html"},
 | 
			
		||||
	"CVE-2018-15442":   {"https://www.jpcert.or.jp/at/2018/at180043.html"},
 | 
			
		||||
	"CVE-2018-15979":   {"https://www.jpcert.or.jp/at/2018/at180045.html"},
 | 
			
		||||
	"CVE-2018-2628":    {"https://www.jpcert.or.jp/at/2018/at180029.html"},
 | 
			
		||||
	"CVE-2018-2893":    {"https://www.jpcert.or.jp/at/2018/at180029.html"},
 | 
			
		||||
	"CVE-2018-2894":    {"https://www.jpcert.or.jp/at/2018/at180029.html"},
 | 
			
		||||
	"CVE-2018-2933":    {"https://www.jpcert.or.jp/at/2018/at180029.html"},
 | 
			
		||||
	"CVE-2018-2983":    {"https://www.jpcert.or.jp/at/2018/at180029.html"},
 | 
			
		||||
	"CVE-2018-2998":    {"https://www.jpcert.or.jp/at/2018/at180029.html"},
 | 
			
		||||
	"CVE-2018-4877":    {"https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-4878":    {"https://www.jpcert.or.jp/at/2018/at180006.html", "https://www.jpcert.or.jp/at/2018/at180008.html"},
 | 
			
		||||
	"CVE-2018-4945":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-5000":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-5001":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-5002":    {"https://www.jpcert.or.jp/at/2018/at180024.html", "https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-5740":    {"https://www.jpcert.or.jp/at/2018/at180031.html"},
 | 
			
		||||
	"CVE-2018-7600":    {"https://www.jpcert.or.jp/at/2018/at180012.html"},
 | 
			
		||||
	"CVE-2018-7602":    {"https://www.jpcert.or.jp/at/2018/at180019.html"},
 | 
			
		||||
	"CVE-2018-8034":    {"https://www.jpcert.or.jp/at/2018/at180030.html"},
 | 
			
		||||
	"CVE-2018-8037":    {"https://www.jpcert.or.jp/at/2018/at180030.html"},
 | 
			
		||||
	"CVE-2018-8110":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-8111":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-8114":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-8120":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-8122":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-8128":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-8130":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-8133":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-8137":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-8139":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-8154":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-8174":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-8178":    {"https://www.jpcert.or.jp/at/2018/at180021.html"},
 | 
			
		||||
	"CVE-2018-8213":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-8225":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-8229":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-8231":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-8236":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-8242":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8249":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-8251":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-8262":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8266":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8267":    {"https://www.jpcert.or.jp/at/2018/at180025.html"},
 | 
			
		||||
	"CVE-2018-8273":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8274":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8275":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8279":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8280":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8286":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8288":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8290":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8291":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8294":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8296":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8301":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8302":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8324":    {"https://www.jpcert.or.jp/at/2018/at180028.html"},
 | 
			
		||||
	"CVE-2018-8332":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8344":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8345":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8350":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8355":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8367":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8371":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8372":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8373":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8377":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8380":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8381":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8385":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8387":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8390":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8397":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8403":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8414":    {"https://www.jpcert.or.jp/at/2018/at180034.html"},
 | 
			
		||||
	"CVE-2018-8420":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8421":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8439":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8440":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8447":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8453":    {"https://www.jpcert.or.jp/at/2018/at180041.html"},
 | 
			
		||||
	"CVE-2018-8456":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8457":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8459":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8460":    {"https://www.jpcert.or.jp/at/2018/at180041.html"},
 | 
			
		||||
	"CVE-2018-8461":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8464":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8465":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8466":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8467":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8473":    {"https://www.jpcert.or.jp/at/2018/at180041.html"},
 | 
			
		||||
	"CVE-2018-8475":    {"https://www.jpcert.or.jp/at/2018/at180038.html"},
 | 
			
		||||
	"CVE-2018-8476":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
	"CVE-2018-8489":    {"https://www.jpcert.or.jp/at/2018/at180041.html"},
 | 
			
		||||
	"CVE-2018-8490":    {"https://www.jpcert.or.jp/at/2018/at180041.html"},
 | 
			
		||||
	"CVE-2018-8491":    {"https://www.jpcert.or.jp/at/2018/at180041.html"},
 | 
			
		||||
	"CVE-2018-8494":    {"https://www.jpcert.or.jp/at/2018/at180041.html"},
 | 
			
		||||
	"CVE-2018-8505":    {"https://www.jpcert.or.jp/at/2018/at180041.html"},
 | 
			
		||||
	"CVE-2018-8509":    {"https://www.jpcert.or.jp/at/2018/at180041.html"},
 | 
			
		||||
	"CVE-2018-8510":    {"https://www.jpcert.or.jp/at/2018/at180041.html"},
 | 
			
		||||
	"CVE-2018-8511":    {"https://www.jpcert.or.jp/at/2018/at180041.html"},
 | 
			
		||||
	"CVE-2018-8513":    {"https://www.jpcert.or.jp/at/2018/at180041.html"},
 | 
			
		||||
	"CVE-2018-8541":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
	"CVE-2018-8542":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
	"CVE-2018-8543":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
	"CVE-2018-8544":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
	"CVE-2018-8551":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
	"CVE-2018-8553":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
	"CVE-2018-8555":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
	"CVE-2018-8556":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
	"CVE-2018-8557":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
	"CVE-2018-8588":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
	"CVE-2018-8589":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
	"CVE-2018-8609":    {"https://www.jpcert.or.jp/at/2018/at180046.html"},
 | 
			
		||||
}
 | 
			
		||||
@@ -1,96 +0,0 @@
 | 
			
		||||
package alert
 | 
			
		||||
 | 
			
		||||
// CveDictEn has CVE-ID key which included USCERT alerts
 | 
			
		||||
var CveDictEn = map[string][]string{
 | 
			
		||||
	"CVE-1999-0532": {"https://www.us-cert.gov/ncas/alerts/TA15-103A"},
 | 
			
		||||
	"CVE-2006-3227": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2008-0015": {"https://www.us-cert.gov/ncas/alerts/TA09-195A", "https://www.us-cert.gov/ncas/alerts/TA09-209A"},
 | 
			
		||||
	"CVE-2008-2244": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2009-0658": {"https://www.us-cert.gov/ncas/alerts/TA09-051A"},
 | 
			
		||||
	"CVE-2009-0927": {"https://www.us-cert.gov/ncas/alerts/TA13-141A"},
 | 
			
		||||
	"CVE-2009-1492": {"https://www.us-cert.gov/ncas/alerts/TA09-133B"},
 | 
			
		||||
	"CVE-2009-1493": {"https://www.us-cert.gov/ncas/alerts/TA09-133B"},
 | 
			
		||||
	"CVE-2009-1537": {"https://www.us-cert.gov/ncas/alerts/TA09-195A"},
 | 
			
		||||
	"CVE-2009-3103": {"https://www.us-cert.gov/ncas/alerts/TA17-181A"},
 | 
			
		||||
	"CVE-2009-3129": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2009-3674": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2009-3953": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2010-0018": {"https://www.us-cert.gov/ncas/alerts/TA10-012B"},
 | 
			
		||||
	"CVE-2010-0188": {"https://www.us-cert.gov/ncas/alerts/TA13-141A", "https://www.us-cert.gov/ncas/alerts/TA14-300A", "https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2010-0806": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2010-1297": {"https://www.us-cert.gov/ncas/alerts/TA10-162A", "https://www.us-cert.gov/ncas/alerts/TA10-159A"},
 | 
			
		||||
	"CVE-2010-2883": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2010-3333": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2011-0101": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2011-0611": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2011-2462": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2012-0158": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2012-1723": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2012-1856": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2012-1889": {"https://www.us-cert.gov/ncas/alerts/TA12-174A"},
 | 
			
		||||
	"CVE-2012-3174": {"https://www.us-cert.gov/ncas/alerts/TA13-010A"},
 | 
			
		||||
	"CVE-2012-4681": {"https://www.us-cert.gov/ncas/alerts/TA12-240A"},
 | 
			
		||||
	"CVE-2012-4792": {"https://www.us-cert.gov/ncas/alerts/TA13-015A", "https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2013-0074": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2013-0140": {"https://www.us-cert.gov/ncas/alerts/TA13-193A"},
 | 
			
		||||
	"CVE-2013-0141": {"https://www.us-cert.gov/ncas/alerts/TA13-193A"},
 | 
			
		||||
	"CVE-2013-0422": {"https://www.us-cert.gov/ncas/alerts/TA13-141A", "https://www.us-cert.gov/ncas/alerts/TA13-010A"},
 | 
			
		||||
	"CVE-2013-0625": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2013-0632": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2013-0809": {"https://www.us-cert.gov/ncas/alerts/TA13-064A"},
 | 
			
		||||
	"CVE-2013-1347": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2013-1493": {"https://www.us-cert.gov/ncas/alerts/TA13-064A"},
 | 
			
		||||
	"CVE-2013-1571": {"https://www.us-cert.gov/ncas/alerts/TA13-169A"},
 | 
			
		||||
	"CVE-2013-2465": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2013-2729": {"https://www.us-cert.gov/ncas/alerts/TA14-300A", "https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2013-3336": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2013-5211": {"https://www.us-cert.gov/ncas/alerts/TA14-017A", "https://www.us-cert.gov/ncas/alerts/TA14-013A"},
 | 
			
		||||
	"CVE-2013-5326": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2014-0160": {"https://www.us-cert.gov/ncas/alerts/TA14-098A", "https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2014-0322": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2014-0564": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2014-1761": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2014-1776": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2014-3393": {"https://www.us-cert.gov/ncas/alerts/TA16-250A"},
 | 
			
		||||
	"CVE-2014-3566": {"https://www.us-cert.gov/ncas/alerts/TA14-290A", "https://www.us-cert.gov/ncas/alerts/TA15-120A"},
 | 
			
		||||
	"CVE-2014-4114": {"https://www.us-cert.gov/ncas/alerts/TA15-119A"},
 | 
			
		||||
	"CVE-2014-6271": {"https://www.us-cert.gov/ncas/alerts/TA14-268A"},
 | 
			
		||||
	"CVE-2014-6277": {"https://www.us-cert.gov/ncas/alerts/TA14-268A"},
 | 
			
		||||
	"CVE-2014-6278": {"https://www.us-cert.gov/ncas/alerts/TA14-268A"},
 | 
			
		||||
	"CVE-2014-6321": {"https://www.us-cert.gov/ncas/alerts/TA14-318A"},
 | 
			
		||||
	"CVE-2014-6332": {"https://www.us-cert.gov/ncas/alerts/TA14-318B"},
 | 
			
		||||
	"CVE-2014-7169": {"https://www.us-cert.gov/ncas/alerts/TA14-268A"},
 | 
			
		||||
	"CVE-2014-7186": {"https://www.us-cert.gov/ncas/alerts/TA14-268A"},
 | 
			
		||||
	"CVE-2014-7187": {"https://www.us-cert.gov/ncas/alerts/TA14-268A"},
 | 
			
		||||
	"CVE-2014-8730": {"https://www.us-cert.gov/ncas/alerts/TA14-290A"},
 | 
			
		||||
	"CVE-2015-2387": {"https://www.us-cert.gov/ncas/alerts/TA15-195A"},
 | 
			
		||||
	"CVE-2015-5119": {"https://www.us-cert.gov/ncas/alerts/TA15-195A", "https://www.us-cert.gov/ncas/alerts/TA15-213A"},
 | 
			
		||||
	"CVE-2015-5122": {"https://www.us-cert.gov/ncas/alerts/TA15-195A"},
 | 
			
		||||
	"CVE-2015-5123": {"https://www.us-cert.gov/ncas/alerts/TA15-195A"},
 | 
			
		||||
	"CVE-2015-6585": {"https://www.us-cert.gov/ncas/alerts/TA17-164A"},
 | 
			
		||||
	"CVE-2015-8651": {"https://www.us-cert.gov/ncas/alerts/TA17-164A"},
 | 
			
		||||
	"CVE-2016-0034": {"https://www.us-cert.gov/ncas/alerts/TA17-164A"},
 | 
			
		||||
	"CVE-2016-1019": {"https://www.us-cert.gov/ncas/alerts/TA17-164A"},
 | 
			
		||||
	"CVE-2016-2207": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
 | 
			
		||||
	"CVE-2016-2208": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
 | 
			
		||||
	"CVE-2016-2209": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
 | 
			
		||||
	"CVE-2016-2210": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
 | 
			
		||||
	"CVE-2016-2211": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
 | 
			
		||||
	"CVE-2016-3644": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
 | 
			
		||||
	"CVE-2016-3645": {"https://www.us-cert.gov/ncas/alerts/TA16-187A"},
 | 
			
		||||
	"CVE-2016-4117": {"https://www.us-cert.gov/ncas/alerts/TA17-164A"},
 | 
			
		||||
	"CVE-2016-6366": {"https://www.us-cert.gov/ncas/alerts/TA16-250A"},
 | 
			
		||||
	"CVE-2016-6367": {"https://www.us-cert.gov/ncas/alerts/TA16-250A"},
 | 
			
		||||
	"CVE-2016-6415": {"https://www.us-cert.gov/ncas/alerts/TA16-250A"},
 | 
			
		||||
	"CVE-2016-6909": {"https://www.us-cert.gov/ncas/alerts/TA16-250A"},
 | 
			
		||||
	"CVE-2016-7089": {"https://www.us-cert.gov/ncas/alerts/TA16-250A"},
 | 
			
		||||
	"CVE-2017-0144": {"https://www.us-cert.gov/ncas/alerts/TA17-181A"},
 | 
			
		||||
	"CVE-2017-0145": {"https://www.us-cert.gov/ncas/alerts/TA17-181A"},
 | 
			
		||||
	"CVE-2017-3066": {"https://www.us-cert.gov/ncas/alerts/AA18-284A"},
 | 
			
		||||
	"CVE-2017-5715": {"https://www.us-cert.gov/ncas/alerts/TA18-141A", "https://www.us-cert.gov/ncas/alerts/TA18-004A"},
 | 
			
		||||
	"CVE-2017-5753": {"https://www.us-cert.gov/ncas/alerts/TA18-141A", "https://www.us-cert.gov/ncas/alerts/TA18-004A"},
 | 
			
		||||
	"CVE-2017-5754": {"https://www.us-cert.gov/ncas/alerts/TA18-141A", "https://www.us-cert.gov/ncas/alerts/TA18-004A"},
 | 
			
		||||
	"CVE-2018-1038": {"https://www.us-cert.gov/ncas/alerts/TA18-004A"},
 | 
			
		||||
	"CVE-2018-3639": {"https://www.us-cert.gov/ncas/alerts/TA18-141A"},
 | 
			
		||||
	"CVE-2018-3640": {"https://www.us-cert.gov/ncas/alerts/TA18-141A"},
 | 
			
		||||
}
 | 
			
		||||
@@ -1,21 +0,0 @@
 | 
			
		||||
package alert
 | 
			
		||||
 | 
			
		||||
// GenerateAlertDict returns XCERT alert slice by cveID
 | 
			
		||||
func GenerateAlertDict(cveID string, lang string) (alerts []Alert) {
 | 
			
		||||
	if lang == "ja" {
 | 
			
		||||
		if keys, ok := CveDictJa[cveID]; ok {
 | 
			
		||||
			for _, key := range keys {
 | 
			
		||||
				alerts = append(alerts, AlertDictJa[key])
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return alerts
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// default language is English
 | 
			
		||||
	if keys, ok := CveDictEn[cveID]; ok {
 | 
			
		||||
		for _, key := range keys {
 | 
			
		||||
			alerts = append(alerts, AlertDictEn[key])
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return alerts
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								cache/bolt.go
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -1,30 +1,13 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/boltdb/bolt"
 | 
			
		||||
	"github.com/future-architect/vuls/util"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Bolt holds a pointer of bolt.DB
 | 
			
		||||
@@ -69,7 +52,7 @@ func (b *Bolt) createBucketIfNotExists(name string) error {
 | 
			
		||||
	return b.db.Update(func(tx *bolt.Tx) error {
 | 
			
		||||
		_, err := tx.CreateBucketIfNotExists([]byte(name))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return fmt.Errorf("Failed to create bucket: %s", err)
 | 
			
		||||
			return xerrors.Errorf("Failed to create bucket: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	})
 | 
			
		||||
@@ -98,7 +81,7 @@ func (b Bolt) RefreshMeta(meta Meta) error {
 | 
			
		||||
	meta.CreatedAt = time.Now()
 | 
			
		||||
	jsonBytes, err := json.Marshal(meta)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("Failed to marshal to JSON: %s", err)
 | 
			
		||||
		return xerrors.Errorf("Failed to marshal to JSON: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	return b.db.Update(func(tx *bolt.Tx) error {
 | 
			
		||||
		bkt := tx.Bucket([]byte(metabucket))
 | 
			
		||||
@@ -114,7 +97,7 @@ func (b Bolt) RefreshMeta(meta Meta) error {
 | 
			
		||||
func (b Bolt) EnsureBuckets(meta Meta) error {
 | 
			
		||||
	jsonBytes, err := json.Marshal(meta)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("Failed to marshal to JSON: %s", err)
 | 
			
		||||
		return xerrors.Errorf("Failed to marshal to JSON: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	return b.db.Update(func(tx *bolt.Tx) error {
 | 
			
		||||
		b.Log.Debugf("Put to meta: %s", meta.Name)
 | 
			
		||||
@@ -158,12 +141,12 @@ func (b Bolt) PrettyPrint(meta Meta) error {
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetChangelog get the changelgo of specified packName from the Bucket
 | 
			
		||||
// GetChangelog get the changelog of specified packName from the Bucket
 | 
			
		||||
func (b Bolt) GetChangelog(servername, packName string) (changelog string, err error) {
 | 
			
		||||
	err = b.db.View(func(tx *bolt.Tx) error {
 | 
			
		||||
		bkt := tx.Bucket([]byte(servername))
 | 
			
		||||
		if bkt == nil {
 | 
			
		||||
			return fmt.Errorf("Failed to get Bucket: %s", servername)
 | 
			
		||||
			return xerrors.Errorf("Failed to get Bucket: %s", servername)
 | 
			
		||||
		}
 | 
			
		||||
		v := bkt.Get([]byte(packName))
 | 
			
		||||
		if v == nil {
 | 
			
		||||
@@ -181,7 +164,7 @@ func (b Bolt) PutChangelog(servername, packName, changelog string) error {
 | 
			
		||||
	return b.db.Update(func(tx *bolt.Tx) error {
 | 
			
		||||
		bkt := tx.Bucket([]byte(servername))
 | 
			
		||||
		if bkt == nil {
 | 
			
		||||
			return fmt.Errorf("Failed to get Bucket: %s", servername)
 | 
			
		||||
			return xerrors.Errorf("Failed to get Bucket: %s", servername)
 | 
			
		||||
		}
 | 
			
		||||
		return bkt.Put([]byte(packName), []byte(changelog))
 | 
			
		||||
	})
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								cache/bolt_test.go
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -63,7 +46,7 @@ func TestSetupBolt(t *testing.T) {
 | 
			
		||||
		t.Errorf("Failed to open bolt: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	db.View(func(tx *bolt.Tx) error {
 | 
			
		||||
	_ = db.View(func(tx *bolt.Tx) error {
 | 
			
		||||
		bkt := tx.Bucket([]byte(metabucket))
 | 
			
		||||
		if bkt == nil {
 | 
			
		||||
			t.Errorf("Meta bucket nof found")
 | 
			
		||||
@@ -104,7 +87,7 @@ func TestEnsureBuckets(t *testing.T) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Errorf("Failed to open bolt: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	db.View(func(tx *bolt.Tx) error {
 | 
			
		||||
	_ = db.View(func(tx *bolt.Tx) error {
 | 
			
		||||
		bkt := tx.Bucket([]byte(servername))
 | 
			
		||||
		if bkt == nil {
 | 
			
		||||
			t.Errorf("Meta bucket nof found")
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								cache/db.go
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 
 | 
			
		||||
@@ -1,27 +1,12 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package commands
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"flag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/google/subcommands"
 | 
			
		||||
 | 
			
		||||
@@ -51,7 +36,7 @@ func (*ConfigtestCmd) Usage() string {
 | 
			
		||||
			[-log-dir=/path/to/log]
 | 
			
		||||
			[-ask-key-password]
 | 
			
		||||
			[-timeout=300]
 | 
			
		||||
			[-ssh-external]
 | 
			
		||||
			[-ssh-config]
 | 
			
		||||
			[-containers-only]
 | 
			
		||||
			[-http-proxy=http://192.168.0.1:8080]
 | 
			
		||||
			[-debug]
 | 
			
		||||
@@ -84,7 +69,7 @@ func (p *ConfigtestCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
		"Use Native Go implementation of SSH. Default: Use the external command")
 | 
			
		||||
 | 
			
		||||
	f.BoolVar(&c.Conf.SSHConfig, "ssh-config", false,
 | 
			
		||||
		"Use SSH options specified in ssh_config preferentially")
 | 
			
		||||
		"[Deprecated] Use SSH options specified in ssh_config preferentially")
 | 
			
		||||
 | 
			
		||||
	f.BoolVar(&c.Conf.ContainersOnly, "containers-only", false,
 | 
			
		||||
		"Test containers only. Default: Test both of hosts and containers")
 | 
			
		||||
@@ -94,11 +79,10 @@ func (p *ConfigtestCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
 | 
			
		||||
// Execute execute
 | 
			
		||||
func (p *ConfigtestCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
 | 
			
		||||
	// Setup Logger
 | 
			
		||||
	util.Log = util.NewCustomLogger(c.ServerInfo{})
 | 
			
		||||
 | 
			
		||||
	if err := mkdirDotVuls(); err != nil {
 | 
			
		||||
		util.Log.Errorf("Failed to create .vuls: %s", err)
 | 
			
		||||
		util.Log.Errorf("Failed to create .vuls. err: %+v", err)
 | 
			
		||||
		return subcommands.ExitUsageError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -114,9 +98,22 @@ func (p *ConfigtestCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interfa
 | 
			
		||||
 | 
			
		||||
	err = c.Load(p.configPath, keyPass)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		util.Log.Errorf("Error loading %s, %s", p.configPath, err)
 | 
			
		||||
		util.Log.Errorf("If you update Vuls and get this error, there may be incompatible changes in config.toml")
 | 
			
		||||
		util.Log.Errorf("Please check README: https://github.com/future-architect/vuls#configuration")
 | 
			
		||||
		msg := []string{
 | 
			
		||||
			fmt.Sprintf("Error loading %s", p.configPath),
 | 
			
		||||
			"If you update Vuls and get this error, there may be incompatible changes in config.toml",
 | 
			
		||||
			"Please check config.toml template : https://vuls.io/docs/en/usage-settings.html",
 | 
			
		||||
		}
 | 
			
		||||
		util.Log.Errorf("%s\n%+v", strings.Join(msg, "\n"), err)
 | 
			
		||||
		return subcommands.ExitUsageError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.Conf.SSHConfig {
 | 
			
		||||
		msg := []string{
 | 
			
		||||
			"-ssh-config is deprecated",
 | 
			
		||||
			"If you update Vuls and get this error, there may be incompatible changes in config.toml",
 | 
			
		||||
			"Please check config.toml template : https://vuls.io/docs/en/usage-settings.html",
 | 
			
		||||
		}
 | 
			
		||||
		util.Log.Errorf("%s", strings.Join(msg, "\n"))
 | 
			
		||||
		return subcommands.ExitUsageError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -151,13 +148,13 @@ func (p *ConfigtestCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interfa
 | 
			
		||||
 | 
			
		||||
	util.Log.Info("Detecting Server/Container OS... ")
 | 
			
		||||
	if err := scan.InitServers(p.timeoutSec); err != nil {
 | 
			
		||||
		util.Log.Errorf("Failed to init servers: %s", err)
 | 
			
		||||
		util.Log.Errorf("Failed to init servers. err: %+v", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	util.Log.Info("Checking Scan Modes...")
 | 
			
		||||
	if err := scan.CheckScanModes(); err != nil {
 | 
			
		||||
		util.Log.Errorf("Fix config.toml: %s", err)
 | 
			
		||||
		util.Log.Errorf("Fix config.toml. err: %+v", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package commands
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -112,6 +95,11 @@ type        = "sqlite3"
 | 
			
		||||
sqlite3Path = "/path/to/go-exploitdb.sqlite3"
 | 
			
		||||
#url        = ""
 | 
			
		||||
 | 
			
		||||
[metasploit]
 | 
			
		||||
type        = "sqlite3"
 | 
			
		||||
sqlite3Path = "/path/to/go-msfdb.sqlite3"
 | 
			
		||||
#url        = ""
 | 
			
		||||
 | 
			
		||||
# https://vuls.io/docs/en/usage-settings.html#slack-section
 | 
			
		||||
#[slack]
 | 
			
		||||
#hookURL      = "https://hooks.slack.com/services/abc123/defghijklmnopqrstuvwxyz"
 | 
			
		||||
@@ -204,6 +192,7 @@ sqlite3Path = "/path/to/go-exploitdb.sqlite3"
 | 
			
		||||
host                = "{{$ip}}"
 | 
			
		||||
#port               = "22"
 | 
			
		||||
#user               = "root"
 | 
			
		||||
#sshConfigPath		= "/home/username/.ssh/config"
 | 
			
		||||
#keyPath            = "/home/username/.ssh/id_rsa"
 | 
			
		||||
#scanMode           = ["fast", "fast-root", "deep", "offline"]
 | 
			
		||||
#type               = "pseudo"
 | 
			
		||||
@@ -223,6 +212,13 @@ host                = "{{$ip}}"
 | 
			
		||||
#[servers.{{index $names $i}}.githubs."owner/repo"]
 | 
			
		||||
#token   = "yourToken"
 | 
			
		||||
 | 
			
		||||
#[servers.{{index $names $i}}.wordpress]
 | 
			
		||||
#cmdPath = "/usr/local/bin/wp"
 | 
			
		||||
#osUser = "wordpress"
 | 
			
		||||
#docRoot = "/path/to/DocumentRoot/"
 | 
			
		||||
#wpVulnDBToken = "xxxxTokenxxxx"
 | 
			
		||||
#ignoreInactive = true
 | 
			
		||||
 | 
			
		||||
#[servers.{{index $names $i}}.optional]
 | 
			
		||||
#key = "value1"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package commands
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package commands
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -23,26 +6,28 @@ import (
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/utils"
 | 
			
		||||
	c "github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/exploit"
 | 
			
		||||
	"github.com/future-architect/vuls/gost"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"github.com/future-architect/vuls/msf"
 | 
			
		||||
	"github.com/future-architect/vuls/oval"
 | 
			
		||||
	"github.com/future-architect/vuls/report"
 | 
			
		||||
	"github.com/future-architect/vuls/util"
 | 
			
		||||
	"github.com/google/subcommands"
 | 
			
		||||
	"github.com/k0kubun/pp"
 | 
			
		||||
	cvelog "github.com/kotakanbe/go-cve-dictionary/log"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ReportCmd is subcommand for reporting
 | 
			
		||||
type ReportCmd struct {
 | 
			
		||||
	configPath  string
 | 
			
		||||
	cveDict     c.GoCveDictConf
 | 
			
		||||
	ovalDict    c.GovalDictConf
 | 
			
		||||
	gostConf    c.GostConf
 | 
			
		||||
	exploitConf c.ExploitConf
 | 
			
		||||
	httpConf    c.HTTPConf
 | 
			
		||||
	configPath     string
 | 
			
		||||
	cveDict        c.GoCveDictConf
 | 
			
		||||
	ovalDict       c.GovalDictConf
 | 
			
		||||
	gostConf       c.GostConf
 | 
			
		||||
	exploitConf    c.ExploitConf
 | 
			
		||||
	metasploitConf c.MetasploitConf
 | 
			
		||||
	httpConf       c.HTTPConf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Name return subcommand name
 | 
			
		||||
@@ -62,6 +47,7 @@ func (*ReportCmd) Usage() string {
 | 
			
		||||
		[-refresh-cve]
 | 
			
		||||
		[-cvss-over=7]
 | 
			
		||||
		[-diff]
 | 
			
		||||
		[-wp-ignore-inactive]
 | 
			
		||||
		[-ignore-unscored-cves]
 | 
			
		||||
		[-ignore-unfixed]
 | 
			
		||||
		[-ignore-github-dismissed]
 | 
			
		||||
@@ -87,6 +73,8 @@ func (*ReportCmd) Usage() string {
 | 
			
		||||
		[-http-proxy=http://192.168.0.1:8080]
 | 
			
		||||
		[-debug]
 | 
			
		||||
		[-debug-sql]
 | 
			
		||||
		[-quiet]
 | 
			
		||||
		[-no-progress]
 | 
			
		||||
		[-pipe]
 | 
			
		||||
		[-cvedb-type=sqlite3|mysql|postgres|redis|http]
 | 
			
		||||
		[-cvedb-sqlite3-path=/path/to/cve.sqlite3]
 | 
			
		||||
@@ -100,7 +88,11 @@ func (*ReportCmd) Usage() string {
 | 
			
		||||
		[-exploitdb-type=sqlite3|mysql|redis|http]
 | 
			
		||||
		[-exploitdb-sqlite3-path=/path/to/exploitdb.sqlite3]
 | 
			
		||||
		[-exploitdb-url=http://127.0.0.1:1326 or DB connection string]
 | 
			
		||||
		[-msfdb-type=sqlite3|mysql|redis|http]
 | 
			
		||||
		[-msfdb-sqlite3-path=/path/to/msfdb.sqlite3]
 | 
			
		||||
		[-msfdb-url=http://127.0.0.1:1327 or DB connection string]
 | 
			
		||||
		[-http="http://vuls-report-server"]
 | 
			
		||||
		[-trivy-cachedb-dir=/path/to/dir]
 | 
			
		||||
 | 
			
		||||
		[RFC3339 datetime format under results dir]
 | 
			
		||||
`
 | 
			
		||||
@@ -111,6 +103,8 @@ func (p *ReportCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
	f.StringVar(&c.Conf.Lang, "lang", "en", "[en|ja]")
 | 
			
		||||
	f.BoolVar(&c.Conf.Debug, "debug", false, "debug mode")
 | 
			
		||||
	f.BoolVar(&c.Conf.DebugSQL, "debug-sql", false, "SQL debug mode")
 | 
			
		||||
	f.BoolVar(&c.Conf.Quiet, "quiet", false, "Quiet mode. No output on stdout")
 | 
			
		||||
	f.BoolVar(&c.Conf.NoProgress, "no-progress", false, "Suppress progress bar")
 | 
			
		||||
 | 
			
		||||
	wd, _ := os.Getwd()
 | 
			
		||||
	defaultConfPath := filepath.Join(wd, "config.toml")
 | 
			
		||||
@@ -131,6 +125,9 @@ func (p *ReportCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
	f.BoolVar(&c.Conf.Diff, "diff", false,
 | 
			
		||||
		"Difference between previous result and current result ")
 | 
			
		||||
 | 
			
		||||
	f.BoolVar(&c.Conf.WpIgnoreInactive, "wp-ignore-inactive", false,
 | 
			
		||||
		"ignore inactive on wordpress's plugin and theme")
 | 
			
		||||
 | 
			
		||||
	f.BoolVar(&c.Conf.IgnoreUnscoredCves, "ignore-unscored-cves", false,
 | 
			
		||||
		"Don't report the unscored CVEs")
 | 
			
		||||
 | 
			
		||||
@@ -199,17 +196,23 @@ func (p *ReportCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
	f.StringVar(&p.exploitConf.URL, "exploitdb-url", "",
 | 
			
		||||
		"http://exploit.com:1326 or DB connection string")
 | 
			
		||||
 | 
			
		||||
	f.StringVar(&p.metasploitConf.Type, "msfdb-type", "",
 | 
			
		||||
		"DB type of msf (sqlite3, mysql, postgres, redis or http)")
 | 
			
		||||
	f.StringVar(&p.metasploitConf.SQLite3Path, "msfdb-sqlite3-path", "", "/path/to/sqlite3")
 | 
			
		||||
	f.StringVar(&p.metasploitConf.URL, "msfdb-url", "",
 | 
			
		||||
		"http://metasploit.com:1327 or DB connection string")
 | 
			
		||||
 | 
			
		||||
	f.StringVar(&p.httpConf.URL, "http", "", "-to-http http://vuls-report")
 | 
			
		||||
 | 
			
		||||
	f.StringVar(&c.Conf.TrivyCacheDBDir, "trivy-cachedb-dir",
 | 
			
		||||
		utils.DefaultCacheDir(), "/path/to/dir")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Execute execute
 | 
			
		||||
func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
 | 
			
		||||
	util.Log = util.NewCustomLogger(c.ServerInfo{})
 | 
			
		||||
	cvelog.SetLogger(c.Conf.LogDir, false, c.Conf.Debug, false)
 | 
			
		||||
 | 
			
		||||
	if err := c.Load(p.configPath, ""); err != nil {
 | 
			
		||||
		util.Log.Errorf("Error loading %s, %s", p.configPath, err)
 | 
			
		||||
		util.Log.Errorf("Error loading %s, %+v", p.configPath, err)
 | 
			
		||||
		return subcommands.ExitUsageError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -217,6 +220,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
	c.Conf.OvalDict.Overwrite(p.ovalDict)
 | 
			
		||||
	c.Conf.Gost.Overwrite(p.gostConf)
 | 
			
		||||
	c.Conf.Exploit.Overwrite(p.exploitConf)
 | 
			
		||||
	c.Conf.Metasploit.Overwrite(p.metasploitConf)
 | 
			
		||||
	c.Conf.HTTP.Overwrite(p.httpConf)
 | 
			
		||||
 | 
			
		||||
	var dir string
 | 
			
		||||
@@ -227,7 +231,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
		dir, err = report.JSONDir(f.Args())
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		util.Log.Errorf("Failed to read from JSON: %s", err)
 | 
			
		||||
		util.Log.Errorf("Failed to read from JSON: %+v", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -276,7 +280,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
 | 
			
		||||
	if c.Conf.ToS3 {
 | 
			
		||||
		if err := report.CheckIfBucketExists(); err != nil {
 | 
			
		||||
			util.Log.Errorf("Check if there is a bucket beforehand: %s, err: %s",
 | 
			
		||||
			util.Log.Errorf("Check if there is a bucket beforehand: %s, err: %+v",
 | 
			
		||||
				c.Conf.AWS.S3Bucket, err)
 | 
			
		||||
			return subcommands.ExitUsageError
 | 
			
		||||
		}
 | 
			
		||||
@@ -297,7 +301,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
			return subcommands.ExitUsageError
 | 
			
		||||
		}
 | 
			
		||||
		if err := report.CheckIfAzureContainerExists(); err != nil {
 | 
			
		||||
			util.Log.Errorf("Check if there is a container beforehand: %s, err: %s",
 | 
			
		||||
			util.Log.Errorf("Check if there is a container beforehand: %s, err: %+v",
 | 
			
		||||
				c.Conf.Azure.ContainerName, err)
 | 
			
		||||
			return subcommands.ExitUsageError
 | 
			
		||||
		}
 | 
			
		||||
@@ -330,15 +334,21 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
	util.Log.Infof("Loaded: %s", dir)
 | 
			
		||||
 | 
			
		||||
	var res models.ScanResults
 | 
			
		||||
	hasError := false
 | 
			
		||||
	for _, r := range loaded {
 | 
			
		||||
		if len(r.Errors) == 0 {
 | 
			
		||||
			res = append(res, r)
 | 
			
		||||
		} else {
 | 
			
		||||
			util.Log.Warnf("Ignored since errors occurred during scanning: %s",
 | 
			
		||||
				r.ServerName)
 | 
			
		||||
			util.Log.Errorf("Ignored since errors occurred during scanning: %s, err: %v",
 | 
			
		||||
				r.ServerName, r.Errors)
 | 
			
		||||
			hasError = true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(res) == 0 {
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, r := range res {
 | 
			
		||||
		util.Log.Debugf("%s: %s",
 | 
			
		||||
			r.ServerInfo(),
 | 
			
		||||
@@ -348,7 +358,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
	if c.Conf.UUID {
 | 
			
		||||
		// Ensure UUIDs of scan target servers in config.toml
 | 
			
		||||
		if err := report.EnsureUUIDs(p.configPath, res); err != nil {
 | 
			
		||||
			util.Log.Errorf("Failed to ensure UUIDs: %s", err)
 | 
			
		||||
			util.Log.Errorf("Failed to ensure UUIDs. err: %+v", err)
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -361,7 +371,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
 | 
			
		||||
		if c.Conf.CveDict.URL != "" {
 | 
			
		||||
			if err := report.CveClient.CheckHealth(); err != nil {
 | 
			
		||||
				util.Log.Errorf("CVE HTTP server is not running. err: %s", err)
 | 
			
		||||
				util.Log.Errorf("CVE HTTP server is not running. err: %+v", err)
 | 
			
		||||
				util.Log.Errorf("Run go-cve-dictionary as server mode before reporting or run with `-cvedb-type=sqlite3 -cvedb-sqlite3-path` option instead of -cvedb-url")
 | 
			
		||||
				return subcommands.ExitFailure
 | 
			
		||||
			}
 | 
			
		||||
@@ -370,7 +380,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
		if c.Conf.OvalDict.URL != "" {
 | 
			
		||||
			err := oval.Base{}.CheckHTTPHealth()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				util.Log.Errorf("OVAL HTTP server is not running. err: %s", err)
 | 
			
		||||
				util.Log.Errorf("OVAL HTTP server is not running. err: %+v", err)
 | 
			
		||||
				util.Log.Errorf("Run goval-dictionary as server mode before reporting or run with `-ovaldb-type=sqlite3 -ovaldb-sqlite3-path` option instead of -ovaldb-url")
 | 
			
		||||
				return subcommands.ExitFailure
 | 
			
		||||
			}
 | 
			
		||||
@@ -380,7 +390,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
			util.Log.Infof("gost: %s", c.Conf.Gost.URL)
 | 
			
		||||
			err := gost.Base{}.CheckHTTPHealth()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				util.Log.Errorf("gost HTTP server is not running. err: %s", err)
 | 
			
		||||
				util.Log.Errorf("gost HTTP server is not running. err: %+v", err)
 | 
			
		||||
				util.Log.Errorf("Run gost as server mode before reporting or run with `-gostdb-type=sqlite3 -gostdb-sqlite3-path` option instead of -gostdb-url")
 | 
			
		||||
				return subcommands.ExitFailure
 | 
			
		||||
			}
 | 
			
		||||
@@ -389,40 +399,54 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
		if c.Conf.Exploit.URL != "" {
 | 
			
		||||
			err := exploit.CheckHTTPHealth()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				util.Log.Errorf("exploit HTTP server is not running. err: %s", err)
 | 
			
		||||
				util.Log.Errorf("exploit HTTP server is not running. err: %+v", err)
 | 
			
		||||
				util.Log.Errorf("Run go-exploitdb as server mode before reporting")
 | 
			
		||||
				return subcommands.ExitFailure
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if c.Conf.Metasploit.URL != "" {
 | 
			
		||||
			err := msf.CheckHTTPHealth()
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				util.Log.Errorf("metasploit HTTP server is not running. err: %+v", err)
 | 
			
		||||
				util.Log.Errorf("Run go-msfdb as server mode before reporting")
 | 
			
		||||
				return subcommands.ExitFailure
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		dbclient, locked, err := report.NewDBClient(report.DBClientConf{
 | 
			
		||||
			CveDictCnf:  c.Conf.CveDict,
 | 
			
		||||
			OvalDictCnf: c.Conf.OvalDict,
 | 
			
		||||
			GostCnf:     c.Conf.Gost,
 | 
			
		||||
			ExploitCnf:  c.Conf.Exploit,
 | 
			
		||||
			DebugSQL:    c.Conf.DebugSQL,
 | 
			
		||||
			CveDictCnf:    c.Conf.CveDict,
 | 
			
		||||
			OvalDictCnf:   c.Conf.OvalDict,
 | 
			
		||||
			GostCnf:       c.Conf.Gost,
 | 
			
		||||
			ExploitCnf:    c.Conf.Exploit,
 | 
			
		||||
			MetasploitCnf: c.Conf.Metasploit,
 | 
			
		||||
			DebugSQL:      c.Conf.DebugSQL,
 | 
			
		||||
		})
 | 
			
		||||
		if locked {
 | 
			
		||||
			util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again: %s", err)
 | 
			
		||||
			util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again. err: %+v", err)
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			util.Log.Errorf("Failed to init DB Clients: %s", err)
 | 
			
		||||
			util.Log.Errorf("Failed to init DB Clients. err: %+v", err)
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
		defer dbclient.CloseDB()
 | 
			
		||||
 | 
			
		||||
		if res, err = report.FillCveInfos(*dbclient, res, dir); err != nil {
 | 
			
		||||
			util.Log.Error(err)
 | 
			
		||||
			util.Log.Errorf("%+v", err)
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, w := range reports {
 | 
			
		||||
		if err := w.Write(res...); err != nil {
 | 
			
		||||
			util.Log.Errorf("Failed to report: %s", err)
 | 
			
		||||
			util.Log.Errorf("Failed to report. err: %+v", err)
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if hasError {
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return subcommands.ExitSuccess
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package commands
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -58,14 +41,19 @@ func (*ScanCmd) Usage() string {
 | 
			
		||||
		[-ssh-native-insecure]
 | 
			
		||||
		[-ssh-config]
 | 
			
		||||
		[-containers-only]
 | 
			
		||||
		[-libs-only]
 | 
			
		||||
		[-wordpress-only]
 | 
			
		||||
		[-skip-broken]
 | 
			
		||||
		[-http-proxy=http://192.168.0.1:8080]
 | 
			
		||||
		[-ask-key-password]
 | 
			
		||||
		[-timeout=300]
 | 
			
		||||
		[-timeout-scan=7200]
 | 
			
		||||
		[-debug]
 | 
			
		||||
		[-quiet]
 | 
			
		||||
		[-pipe]
 | 
			
		||||
		[-vvv]
 | 
			
		||||
		[-ips]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		[SERVER]...
 | 
			
		||||
`
 | 
			
		||||
@@ -74,6 +62,7 @@ func (*ScanCmd) Usage() string {
 | 
			
		||||
// SetFlags set flag
 | 
			
		||||
func (p *ScanCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
	f.BoolVar(&c.Conf.Debug, "debug", false, "debug mode")
 | 
			
		||||
	f.BoolVar(&c.Conf.Quiet, "quiet", false, "Quiet mode. No output on stdout")
 | 
			
		||||
 | 
			
		||||
	wd, _ := os.Getwd()
 | 
			
		||||
	defaultConfPath := filepath.Join(wd, "config.toml")
 | 
			
		||||
@@ -93,10 +82,16 @@ func (p *ScanCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
		"Use Native Go implementation of SSH. Default: Use the external command")
 | 
			
		||||
 | 
			
		||||
	f.BoolVar(&c.Conf.SSHConfig, "ssh-config", false,
 | 
			
		||||
		"Use SSH options specified in ssh_config preferentially")
 | 
			
		||||
		"[Deprecated] Use SSH options specified in ssh_config preferentially")
 | 
			
		||||
 | 
			
		||||
	f.BoolVar(&c.Conf.ContainersOnly, "containers-only", false,
 | 
			
		||||
		"Scan containers only. Default: Scan both of hosts and containers")
 | 
			
		||||
		"Scan running containers only. Default: Scan both of hosts and running containers")
 | 
			
		||||
 | 
			
		||||
	f.BoolVar(&c.Conf.LibsOnly, "libs-only", false,
 | 
			
		||||
		"Scan libraries (lock files) specified in config.toml only.")
 | 
			
		||||
 | 
			
		||||
	f.BoolVar(&c.Conf.WordPressOnly, "wordpress-only", false,
 | 
			
		||||
		"Scan WordPress only.")
 | 
			
		||||
 | 
			
		||||
	f.BoolVar(&c.Conf.SkipBroken, "skip-broken", false,
 | 
			
		||||
		"[For CentOS] yum update changelog with --skip-broken option")
 | 
			
		||||
@@ -109,6 +104,8 @@ func (p *ScanCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	f.BoolVar(&c.Conf.Pipe, "pipe", false, "Use stdin via PIPE")
 | 
			
		||||
 | 
			
		||||
	f.BoolVar(&c.Conf.DetectIPS, "ips", false, "retrieve IPS information")
 | 
			
		||||
	f.BoolVar(&c.Conf.Vvv, "vvv", false, "ssh -vvv")
 | 
			
		||||
 | 
			
		||||
	f.IntVar(&p.timeoutSec, "timeout", 5*60,
 | 
			
		||||
@@ -126,7 +123,7 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
 | 
			
		||||
	util.Log = util.NewCustomLogger(c.ServerInfo{})
 | 
			
		||||
 | 
			
		||||
	if err := mkdirDotVuls(); err != nil {
 | 
			
		||||
		util.Log.Errorf("Failed to create .vuls: %s", err)
 | 
			
		||||
		util.Log.Errorf("Failed to create .vuls. err: %+v", err)
 | 
			
		||||
		return subcommands.ExitUsageError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -142,9 +139,22 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
 | 
			
		||||
 | 
			
		||||
	err = c.Load(p.configPath, keyPass)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		util.Log.Errorf("Error loading %s, %s", p.configPath, err)
 | 
			
		||||
		util.Log.Errorf("If you update Vuls and get this error, there may be incompatible changes in config.toml")
 | 
			
		||||
		util.Log.Errorf("Please check README: https://github.com/future-architect/vuls#configuration")
 | 
			
		||||
		msg := []string{
 | 
			
		||||
			fmt.Sprintf("Error loading %s", p.configPath),
 | 
			
		||||
			"If you update Vuls and get this error, there may be incompatible changes in config.toml",
 | 
			
		||||
			"Please check config.toml template : https://vuls.io/docs/en/usage-settings.html",
 | 
			
		||||
		}
 | 
			
		||||
		util.Log.Errorf("%s\n%+v", strings.Join(msg, "\n"), err)
 | 
			
		||||
		return subcommands.ExitUsageError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.Conf.SSHConfig {
 | 
			
		||||
		msg := []string{
 | 
			
		||||
			"-ssh-config is deprecated",
 | 
			
		||||
			"If you update Vuls and get this error, there may be incompatible changes in config.toml",
 | 
			
		||||
			"Please check config.toml template : https://vuls.io/docs/en/usage-settings.html",
 | 
			
		||||
		}
 | 
			
		||||
		util.Log.Errorf("%s", strings.Join(msg, "\n"))
 | 
			
		||||
		return subcommands.ExitUsageError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -157,7 +167,7 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
 | 
			
		||||
	} else if c.Conf.Pipe {
 | 
			
		||||
		bytes, err := ioutil.ReadAll(os.Stdin)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			util.Log.Errorf("Failed to read stdin: %s", err)
 | 
			
		||||
			util.Log.Errorf("Failed to read stdin. err: %+v", err)
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
		fields := strings.Fields(string(bytes))
 | 
			
		||||
@@ -193,22 +203,24 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
 | 
			
		||||
 | 
			
		||||
	util.Log.Info("Detecting Server/Container OS... ")
 | 
			
		||||
	if err := scan.InitServers(p.timeoutSec); err != nil {
 | 
			
		||||
		util.Log.Errorf("Failed to init servers: %s", err)
 | 
			
		||||
		util.Log.Errorf("Failed to init servers: %+v", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	util.Log.Info("Checking Scan Modes... ")
 | 
			
		||||
	if err := scan.CheckScanModes(); err != nil {
 | 
			
		||||
		util.Log.Errorf("Fix config.toml: %s", err)
 | 
			
		||||
		util.Log.Errorf("Fix config.toml. err: %+v", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	util.Log.Info("Detecting Platforms... ")
 | 
			
		||||
	scan.DetectPlatforms(p.timeoutSec)
 | 
			
		||||
	util.Log.Info("Detecting IPS identifiers... ")
 | 
			
		||||
	scan.DetectIPSs(p.timeoutSec)
 | 
			
		||||
 | 
			
		||||
	util.Log.Info("Scanning vulnerabilities... ")
 | 
			
		||||
	if err := scan.Scan(p.scanTimeoutSec); err != nil {
 | 
			
		||||
		util.Log.Errorf("Failed to scan. err: %s", err)
 | 
			
		||||
		util.Log.Errorf("Failed to scan. err: %+v", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Printf("\n\n\n")
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Architect, Inc. Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package commands
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -30,22 +13,23 @@ import (
 | 
			
		||||
	c "github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/exploit"
 | 
			
		||||
	"github.com/future-architect/vuls/gost"
 | 
			
		||||
	"github.com/future-architect/vuls/msf"
 | 
			
		||||
	"github.com/future-architect/vuls/oval"
 | 
			
		||||
	"github.com/future-architect/vuls/report"
 | 
			
		||||
	"github.com/future-architect/vuls/server"
 | 
			
		||||
	"github.com/future-architect/vuls/util"
 | 
			
		||||
	"github.com/google/subcommands"
 | 
			
		||||
	cvelog "github.com/kotakanbe/go-cve-dictionary/log"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ServerCmd is subcommand for server
 | 
			
		||||
type ServerCmd struct {
 | 
			
		||||
	configPath  string
 | 
			
		||||
	listen      string
 | 
			
		||||
	cveDict     c.GoCveDictConf
 | 
			
		||||
	ovalDict    c.GovalDictConf
 | 
			
		||||
	gostConf    c.GostConf
 | 
			
		||||
	exploitConf c.ExploitConf
 | 
			
		||||
	configPath     string
 | 
			
		||||
	listen         string
 | 
			
		||||
	cveDict        c.GoCveDictConf
 | 
			
		||||
	ovalDict       c.GovalDictConf
 | 
			
		||||
	gostConf       c.GostConf
 | 
			
		||||
	exploitConf    c.ExploitConf
 | 
			
		||||
	metasploitConf c.MetasploitConf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Name return subcommand name
 | 
			
		||||
@@ -82,6 +66,9 @@ func (*ServerCmd) Usage() string {
 | 
			
		||||
		[-exploitdb-type=sqlite3|mysql|redis|http]
 | 
			
		||||
		[-exploitdb-sqlite3-path=/path/to/exploitdb.sqlite3]
 | 
			
		||||
		[-exploitdb-url=http://127.0.0.1:1326 or DB connection string]
 | 
			
		||||
		[-msfdb-type=sqlite3|mysql|redis|http]
 | 
			
		||||
		[-msfdb-sqlite3-path=/path/to/msfdb.sqlite3]
 | 
			
		||||
		[-msfdb-url=http://127.0.0.1:1327 or DB connection string]
 | 
			
		||||
 | 
			
		||||
		[RFC3339 datetime format under results dir]
 | 
			
		||||
`
 | 
			
		||||
@@ -94,8 +81,7 @@ func (p *ServerCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
	f.BoolVar(&c.Conf.DebugSQL, "debug-sql", false, "SQL debug mode")
 | 
			
		||||
 | 
			
		||||
	wd, _ := os.Getwd()
 | 
			
		||||
	defaultConfPath := filepath.Join(wd, "config.toml")
 | 
			
		||||
	f.StringVar(&p.configPath, "config", defaultConfPath, "/path/to/toml")
 | 
			
		||||
	f.StringVar(&p.configPath, "config", "", "/path/to/toml")
 | 
			
		||||
 | 
			
		||||
	defaultResultsDir := filepath.Join(wd, "results")
 | 
			
		||||
	f.StringVar(&c.Conf.ResultsDir, "results-dir", defaultResultsDir, "/path/to/results")
 | 
			
		||||
@@ -144,22 +130,29 @@ func (p *ServerCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
	f.StringVar(&p.exploitConf.SQLite3Path, "exploitdb-sqlite3-path", "", "/path/to/sqlite3")
 | 
			
		||||
	f.StringVar(&p.exploitConf.URL, "exploitdb-url", "",
 | 
			
		||||
		"http://exploit.com:1326 or DB connection string")
 | 
			
		||||
 | 
			
		||||
	f.StringVar(&p.metasploitConf.Type, "msfdb-type", "",
 | 
			
		||||
		"DB type of msf (sqlite3, mysql, postgres, redis or http)")
 | 
			
		||||
	f.StringVar(&p.metasploitConf.SQLite3Path, "msfdb-sqlite3-path", "", "/path/to/sqlite3")
 | 
			
		||||
	f.StringVar(&p.metasploitConf.URL, "msfdb-url", "",
 | 
			
		||||
		"http://metasploit.com:1327 or DB connection string")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Execute execute
 | 
			
		||||
func (p *ServerCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
 | 
			
		||||
	util.Log = util.NewCustomLogger(c.ServerInfo{})
 | 
			
		||||
	cvelog.SetLogger(c.Conf.LogDir, false, c.Conf.Debug, false)
 | 
			
		||||
 | 
			
		||||
	if err := c.Load(p.configPath, ""); err != nil {
 | 
			
		||||
		util.Log.Errorf("Error loading %s, %s", p.configPath, err)
 | 
			
		||||
		return subcommands.ExitUsageError
 | 
			
		||||
	if p.configPath != "" {
 | 
			
		||||
		if err := c.Load(p.configPath, ""); err != nil {
 | 
			
		||||
			util.Log.Errorf("Error loading %s. err: %+v", p.configPath, err)
 | 
			
		||||
			return subcommands.ExitUsageError
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.Conf.CveDict.Overwrite(p.cveDict)
 | 
			
		||||
	c.Conf.OvalDict.Overwrite(p.ovalDict)
 | 
			
		||||
	c.Conf.Gost.Overwrite(p.gostConf)
 | 
			
		||||
	c.Conf.Exploit.Overwrite(p.exploitConf)
 | 
			
		||||
	c.Conf.Metasploit.Overwrite(p.metasploitConf)
 | 
			
		||||
 | 
			
		||||
	util.Log.Info("Validating config...")
 | 
			
		||||
	if !c.Conf.ValidateOnReport() {
 | 
			
		||||
@@ -173,7 +166,7 @@ func (p *ServerCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
 | 
			
		||||
	if c.Conf.CveDict.URL != "" {
 | 
			
		||||
		if err := report.CveClient.CheckHealth(); err != nil {
 | 
			
		||||
			util.Log.Errorf("CVE HTTP server is not running. err: %s", err)
 | 
			
		||||
			util.Log.Errorf("CVE HTTP server is not running. err: %+v", err)
 | 
			
		||||
			util.Log.Errorf("Run go-cve-dictionary as server mode before reporting or run with `-cvedb-type=sqlite3 -cvedb-sqlite3-path` option instead of -cvedb-url")
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
@@ -192,7 +185,7 @@ func (p *ServerCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
		util.Log.Infof("gost: %s", c.Conf.Gost.URL)
 | 
			
		||||
		err := gost.Base{}.CheckHTTPHealth()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			util.Log.Errorf("gost HTTP server is not running. err: %s", err)
 | 
			
		||||
			util.Log.Errorf("gost HTTP server is not running. err: %+v", err)
 | 
			
		||||
			util.Log.Errorf("Run gost as server mode before reporting or run with `-gostdb-type=sqlite3 -gostdb-sqlite3-path` option instead of -gostdb-url")
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
@@ -201,26 +194,35 @@ func (p *ServerCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
	if c.Conf.Exploit.URL != "" {
 | 
			
		||||
		err := exploit.CheckHTTPHealth()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			util.Log.Errorf("exploit HTTP server is not running. err: %s", err)
 | 
			
		||||
			util.Log.Errorf("exploit HTTP server is not running. err: %+v", err)
 | 
			
		||||
			util.Log.Errorf("Run go-exploitdb as server mode before reporting")
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.Conf.Metasploit.URL != "" {
 | 
			
		||||
		err := msf.CheckHTTPHealth()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			util.Log.Errorf("metasploit HTTP server is not running. err: %+v", err)
 | 
			
		||||
			util.Log.Errorf("Run go-msfdb as server mode before reporting")
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	dbclient, locked, err := report.NewDBClient(report.DBClientConf{
 | 
			
		||||
		CveDictCnf:  c.Conf.CveDict,
 | 
			
		||||
		OvalDictCnf: c.Conf.OvalDict,
 | 
			
		||||
		GostCnf:     c.Conf.Gost,
 | 
			
		||||
		ExploitCnf:  c.Conf.Exploit,
 | 
			
		||||
		DebugSQL:    c.Conf.DebugSQL,
 | 
			
		||||
		CveDictCnf:    c.Conf.CveDict,
 | 
			
		||||
		OvalDictCnf:   c.Conf.OvalDict,
 | 
			
		||||
		GostCnf:       c.Conf.Gost,
 | 
			
		||||
		ExploitCnf:    c.Conf.Exploit,
 | 
			
		||||
		MetasploitCnf: c.Conf.Metasploit,
 | 
			
		||||
		DebugSQL:      c.Conf.DebugSQL,
 | 
			
		||||
	})
 | 
			
		||||
	if locked {
 | 
			
		||||
		util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again: %s", err)
 | 
			
		||||
		util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again: %+v", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		util.Log.Errorf("Failed to init DB Clients: %s", err)
 | 
			
		||||
		util.Log.Errorf("Failed to init DB Clients. err: %+v", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -232,7 +234,7 @@ func (p *ServerCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
 | 
			
		||||
	})
 | 
			
		||||
	util.Log.Infof("Listening on %s", p.listen)
 | 
			
		||||
	if err := http.ListenAndServe(p.listen, nil); err != nil {
 | 
			
		||||
		util.Log.Errorf("Failed to start server: %s", err)
 | 
			
		||||
		util.Log.Errorf("Failed to start server. err: %+v", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
	return subcommands.ExitSuccess
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package commands
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -23,24 +6,26 @@ import (
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/utils"
 | 
			
		||||
	c "github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/exploit"
 | 
			
		||||
	"github.com/future-architect/vuls/gost"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"github.com/future-architect/vuls/msf"
 | 
			
		||||
	"github.com/future-architect/vuls/oval"
 | 
			
		||||
	"github.com/future-architect/vuls/report"
 | 
			
		||||
	"github.com/future-architect/vuls/util"
 | 
			
		||||
	"github.com/google/subcommands"
 | 
			
		||||
	cvelog "github.com/kotakanbe/go-cve-dictionary/log"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TuiCmd is Subcommand of host discovery mode
 | 
			
		||||
type TuiCmd struct {
 | 
			
		||||
	configPath  string
 | 
			
		||||
	cveDict     c.GoCveDictConf
 | 
			
		||||
	ovalDict    c.GovalDictConf
 | 
			
		||||
	gostConf    c.GostConf
 | 
			
		||||
	exploitConf c.ExploitConf
 | 
			
		||||
	configPath     string
 | 
			
		||||
	cveDict        c.GoCveDictConf
 | 
			
		||||
	ovalDict       c.GovalDictConf
 | 
			
		||||
	gostConf       c.GostConf
 | 
			
		||||
	exploitConf    c.ExploitConf
 | 
			
		||||
	metasploitConf c.MetasploitConf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Name return subcommand name
 | 
			
		||||
@@ -63,6 +48,8 @@ func (*TuiCmd) Usage() string {
 | 
			
		||||
		[-log-dir=/path/to/log]
 | 
			
		||||
		[-debug]
 | 
			
		||||
		[-debug-sql]
 | 
			
		||||
		[-quiet]
 | 
			
		||||
		[-no-progress]
 | 
			
		||||
		[-pipe]
 | 
			
		||||
		[-cvedb-type=sqlite3|mysql|postgres|redis|http]
 | 
			
		||||
		[-cvedb-sqlite3-path=/path/to/cve.sqlite3]
 | 
			
		||||
@@ -76,6 +63,10 @@ func (*TuiCmd) Usage() string {
 | 
			
		||||
		[-exploitdb-type=sqlite3|mysql|redis|http]
 | 
			
		||||
		[-exploitdb-sqlite3-path=/path/to/exploitdb.sqlite3]
 | 
			
		||||
		[-exploitdb-url=http://127.0.0.1:1326 or DB connection string]
 | 
			
		||||
		[-msfdb-type=sqlite3|mysql|redis|http]
 | 
			
		||||
		[-msfdb-sqlite3-path=/path/to/msfdb.sqlite3]
 | 
			
		||||
		[-msfdb-url=http://127.0.0.1:1327 or DB connection string]
 | 
			
		||||
		[-trivy-cachedb-dir=/path/to/dir]
 | 
			
		||||
 | 
			
		||||
`
 | 
			
		||||
}
 | 
			
		||||
@@ -85,6 +76,8 @@ func (p *TuiCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
	//  f.StringVar(&p.lang, "lang", "en", "[en|ja]")
 | 
			
		||||
	f.BoolVar(&c.Conf.DebugSQL, "debug-sql", false, "debug SQL")
 | 
			
		||||
	f.BoolVar(&c.Conf.Debug, "debug", false, "debug mode")
 | 
			
		||||
	f.BoolVar(&c.Conf.Quiet, "quiet", false, "Quiet mode. No output on stdout")
 | 
			
		||||
	f.BoolVar(&c.Conf.NoProgress, "no-progress", false, "Suppress progress bar")
 | 
			
		||||
 | 
			
		||||
	defaultLogDir := util.GetDefaultLogDir()
 | 
			
		||||
	f.StringVar(&c.Conf.LogDir, "log-dir", defaultLogDir, "/path/to/log")
 | 
			
		||||
@@ -138,25 +131,30 @@ func (p *TuiCmd) SetFlags(f *flag.FlagSet) {
 | 
			
		||||
	f.StringVar(&p.exploitConf.URL, "exploitdb-url", "",
 | 
			
		||||
		"http://exploit.com:1326 or DB connection string")
 | 
			
		||||
 | 
			
		||||
	f.StringVar(&p.metasploitConf.Type, "msfdb-type", "",
 | 
			
		||||
		"DB type of msf (sqlite3, mysql, postgres, redis or http)")
 | 
			
		||||
	f.StringVar(&p.metasploitConf.SQLite3Path, "msfdb-sqlite3-path", "", "/path/to/sqlite3")
 | 
			
		||||
	f.StringVar(&p.metasploitConf.URL, "msfdb-url", "",
 | 
			
		||||
		"http://metasploit.com:1327 or DB connection string")
 | 
			
		||||
 | 
			
		||||
	f.StringVar(&c.Conf.TrivyCacheDBDir, "trivy-cachedb-dir",
 | 
			
		||||
		utils.DefaultCacheDir(), "/path/to/dir")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Execute execute
 | 
			
		||||
func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
 | 
			
		||||
	c.Conf.Lang = "en"
 | 
			
		||||
 | 
			
		||||
	// Setup Logger
 | 
			
		||||
	util.Log = util.NewCustomLogger(c.ServerInfo{})
 | 
			
		||||
	cvelog.SetLogger(c.Conf.LogDir, false, c.Conf.Debug, false)
 | 
			
		||||
 | 
			
		||||
	if err := c.Load(p.configPath, ""); err != nil {
 | 
			
		||||
		util.Log.Errorf("Error loading %s, %s", p.configPath, err)
 | 
			
		||||
		util.Log.Errorf("Error loading %s, err: %+v", p.configPath, err)
 | 
			
		||||
		return subcommands.ExitUsageError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.Conf.Lang = "en"
 | 
			
		||||
	c.Conf.CveDict.Overwrite(p.cveDict)
 | 
			
		||||
	c.Conf.OvalDict.Overwrite(p.ovalDict)
 | 
			
		||||
	c.Conf.Gost.Overwrite(p.gostConf)
 | 
			
		||||
	c.Conf.Exploit.Overwrite(p.exploitConf)
 | 
			
		||||
	c.Conf.Metasploit.Overwrite(p.metasploitConf)
 | 
			
		||||
 | 
			
		||||
	var dir string
 | 
			
		||||
	var err error
 | 
			
		||||
@@ -166,7 +164,7 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
 | 
			
		||||
		dir, err = report.JSONDir(f.Args())
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		util.Log.Errorf("Failed to read from JSON: %s", err)
 | 
			
		||||
		util.Log.Errorf("Failed to read from JSON. err: %+v", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -189,7 +187,7 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
 | 
			
		||||
 | 
			
		||||
	if c.Conf.CveDict.URL != "" {
 | 
			
		||||
		if err := report.CveClient.CheckHealth(); err != nil {
 | 
			
		||||
			util.Log.Errorf("CVE HTTP server is not running. err: %s", err)
 | 
			
		||||
			util.Log.Errorf("CVE HTTP server is not running. err: %+v", err)
 | 
			
		||||
			util.Log.Errorf("Run go-cve-dictionary as server mode before reporting or run with `-cvedb-type=sqlite3 -cvedb-sqlite3-path` option instead of -cvedb-url")
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
@@ -198,7 +196,7 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
 | 
			
		||||
	if c.Conf.OvalDict.URL != "" {
 | 
			
		||||
		err := oval.Base{}.CheckHTTPHealth()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			util.Log.Errorf("OVAL HTTP server is not running. err: %s", err)
 | 
			
		||||
			util.Log.Errorf("OVAL HTTP server is not running. err: %+v", err)
 | 
			
		||||
			util.Log.Errorf("Run goval-dictionary as server mode before reporting or run with `-ovaldb-type=sqlite3 -ovaldb-sqlite3-path` option instead of -ovaldb-url")
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
@@ -208,7 +206,7 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
 | 
			
		||||
		util.Log.Infof("gost: %s", c.Conf.Gost.URL)
 | 
			
		||||
		err := gost.Base{}.CheckHTTPHealth()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			util.Log.Errorf("gost HTTP server is not running. err: %s", err)
 | 
			
		||||
			util.Log.Errorf("gost HTTP server is not running. err: %+v", err)
 | 
			
		||||
			util.Log.Errorf("Run gost as server mode before reporting or run with `-gostdb-type=sqlite3 -gostdb-sqlite3-path` option instead of -gostdb-url")
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
@@ -217,25 +215,35 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
 | 
			
		||||
	if c.Conf.Exploit.URL != "" {
 | 
			
		||||
		err := exploit.CheckHTTPHealth()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			util.Log.Errorf("exploit HTTP server is not running. err: %s", err)
 | 
			
		||||
			util.Log.Errorf("exploit HTTP server is not running. err: %+v", err)
 | 
			
		||||
			util.Log.Errorf("Run go-exploitdb as server mode before reporting")
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.Conf.Metasploit.URL != "" {
 | 
			
		||||
		err := msf.CheckHTTPHealth()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			util.Log.Errorf("metasploit HTTP server is not running. err: %+v", err)
 | 
			
		||||
			util.Log.Errorf("Run go-msfdb as server mode before reporting")
 | 
			
		||||
			return subcommands.ExitFailure
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	dbclient, locked, err := report.NewDBClient(report.DBClientConf{
 | 
			
		||||
		CveDictCnf:  c.Conf.CveDict,
 | 
			
		||||
		OvalDictCnf: c.Conf.OvalDict,
 | 
			
		||||
		GostCnf:     c.Conf.Gost,
 | 
			
		||||
		ExploitCnf:  c.Conf.Exploit,
 | 
			
		||||
		DebugSQL:    c.Conf.DebugSQL,
 | 
			
		||||
		CveDictCnf:    c.Conf.CveDict,
 | 
			
		||||
		OvalDictCnf:   c.Conf.OvalDict,
 | 
			
		||||
		GostCnf:       c.Conf.Gost,
 | 
			
		||||
		ExploitCnf:    c.Conf.Exploit,
 | 
			
		||||
		MetasploitCnf: c.Conf.Metasploit,
 | 
			
		||||
		DebugSQL:      c.Conf.DebugSQL,
 | 
			
		||||
	})
 | 
			
		||||
	if locked {
 | 
			
		||||
		util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again: %s", err)
 | 
			
		||||
		util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again: %+v", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		util.Log.Errorf("Failed to init DB Clients: %s", err)
 | 
			
		||||
		util.Log.Errorf("Failed to init DB Clients. err: %+v", err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -245,5 +253,13 @@ func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) s
 | 
			
		||||
		util.Log.Error(err)
 | 
			
		||||
		return subcommands.ExitFailure
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, r := range res {
 | 
			
		||||
		if len(r.Warnings) != 0 {
 | 
			
		||||
			util.Log.Warnf("Warning: Some warnings occurred while scanning on %s: %s",
 | 
			
		||||
				r.FormatServerName(), r.Warnings)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return report.RunTui(res)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package commands
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -24,6 +7,7 @@ import (
 | 
			
		||||
 | 
			
		||||
	"github.com/howeyc/gopass"
 | 
			
		||||
	homedir "github.com/mitchellh/go-homedir"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func getPasswd(prompt string) (string, error) {
 | 
			
		||||
@@ -31,7 +15,7 @@ func getPasswd(prompt string) (string, error) {
 | 
			
		||||
		fmt.Print(prompt)
 | 
			
		||||
		pass, err := gopass.GetPasswdMasked()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", fmt.Errorf("Failed to read password")
 | 
			
		||||
			return "", xerrors.New("Failed to read a password")
 | 
			
		||||
		}
 | 
			
		||||
		if 0 < len(pass) {
 | 
			
		||||
			return string(pass), nil
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package commands
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										290
									
								
								config/config.go
									
									
									
									
									
								
							
							
						
						@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -27,13 +10,13 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	syslog "github.com/RackSec/srslog"
 | 
			
		||||
 | 
			
		||||
	valid "github.com/asaskevich/govalidator"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Version of Vuls
 | 
			
		||||
var Version = "0.6.3"
 | 
			
		||||
var Version = "`make build` or `make install` will show the version"
 | 
			
		||||
 | 
			
		||||
// Revision of Git
 | 
			
		||||
var Revision string
 | 
			
		||||
@@ -105,6 +88,8 @@ type Config struct {
 | 
			
		||||
	LogDir     string `json:"logDir,omitempty"`
 | 
			
		||||
	ResultsDir string `json:"resultsDir,omitempty"`
 | 
			
		||||
	Pipe       bool   `json:"pipe,omitempty"`
 | 
			
		||||
	Quiet      bool   `json:"quiet,omitempty"`
 | 
			
		||||
	NoProgress bool   `json:"noProgress,omitempty"`
 | 
			
		||||
 | 
			
		||||
	Default       ServerInfo            `json:"default,omitempty"`
 | 
			
		||||
	Servers       map[string]ServerInfo `json:"servers,omitempty"`
 | 
			
		||||
@@ -114,18 +99,26 @@ type Config struct {
 | 
			
		||||
	IgnoreUnfixed         bool `json:"ignoreUnfixed,omitempty"`
 | 
			
		||||
	IgnoreGitHubDismissed bool `json:"ignore_git_hub_dismissed,omitempty"`
 | 
			
		||||
 | 
			
		||||
	SSHNative      bool   `json:"sshNative,omitempty"`
 | 
			
		||||
	SSHConfig      bool   `json:"sshConfig,omitempty"`
 | 
			
		||||
	ContainersOnly bool   `json:"containersOnly,omitempty"`
 | 
			
		||||
	SkipBroken     bool   `json:"skipBroken,omitempty"`
 | 
			
		||||
	CacheDBPath    string `json:"cacheDBPath,omitempty"`
 | 
			
		||||
	Vvv            bool   `json:"vvv,omitempty"`
 | 
			
		||||
	UUID           bool   `json:"uuid,omitempty"`
 | 
			
		||||
	SSHNative bool `json:"sshNative,omitempty"`
 | 
			
		||||
	SSHConfig bool `json:"sshConfig,omitempty"`
 | 
			
		||||
 | 
			
		||||
	CveDict  GoCveDictConf `json:"cveDict,omitempty"`
 | 
			
		||||
	OvalDict GovalDictConf `json:"ovalDict,omitempty"`
 | 
			
		||||
	Gost     GostConf      `json:"gost,omitempty"`
 | 
			
		||||
	Exploit  ExploitConf   `json:"exploit,omitempty"`
 | 
			
		||||
	ContainersOnly bool `json:"containersOnly,omitempty"`
 | 
			
		||||
	LibsOnly       bool `json:"libsOnly,omitempty"`
 | 
			
		||||
	WordPressOnly  bool `json:"wordpressOnly,omitempty"`
 | 
			
		||||
 | 
			
		||||
	CacheDBPath     string `json:"cacheDBPath,omitempty"`
 | 
			
		||||
	TrivyCacheDBDir string `json:"trivyCacheDBDir,omitempty"`
 | 
			
		||||
 | 
			
		||||
	SkipBroken bool `json:"skipBroken,omitempty"`
 | 
			
		||||
	Vvv        bool `json:"vvv,omitempty"`
 | 
			
		||||
	UUID       bool `json:"uuid,omitempty"`
 | 
			
		||||
	DetectIPS  bool `json:"detectIps,omitempty"`
 | 
			
		||||
 | 
			
		||||
	CveDict    GoCveDictConf  `json:"cveDict,omitempty"`
 | 
			
		||||
	OvalDict   GovalDictConf  `json:"ovalDict,omitempty"`
 | 
			
		||||
	Gost       GostConf       `json:"gost,omitempty"`
 | 
			
		||||
	Exploit    ExploitConf    `json:"exploit,omitempty"`
 | 
			
		||||
	Metasploit MetasploitConf `json:"metasploit,omitempty"`
 | 
			
		||||
 | 
			
		||||
	Slack    SlackConf    `json:"-"`
 | 
			
		||||
	EMail    SMTPConf     `json:"-"`
 | 
			
		||||
@@ -160,14 +153,15 @@ type Config struct {
 | 
			
		||||
	FormatFullText    bool `json:"formatFullText,omitempty"`
 | 
			
		||||
	GZIP              bool `json:"gzip,omitempty"`
 | 
			
		||||
	Diff              bool `json:"diff,omitempty"`
 | 
			
		||||
	WpIgnoreInactive  bool `json:"wpIgnoreInactive,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ValidateOnConfigtest validates
 | 
			
		||||
func (c Config) ValidateOnConfigtest() bool {
 | 
			
		||||
	errs := []error{}
 | 
			
		||||
	errs := c.checkSSHKeyExist()
 | 
			
		||||
 | 
			
		||||
	if runtime.GOOS == "windows" && !c.SSHNative {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("-ssh-native-insecure is needed on windows"))
 | 
			
		||||
		errs = append(errs, xerrors.New("-ssh-native-insecure is needed on windows"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := valid.ValidateStruct(c)
 | 
			
		||||
@@ -184,29 +178,22 @@ func (c Config) ValidateOnConfigtest() bool {
 | 
			
		||||
 | 
			
		||||
// ValidateOnScan validates configuration
 | 
			
		||||
func (c Config) ValidateOnScan() bool {
 | 
			
		||||
	errs := []error{}
 | 
			
		||||
 | 
			
		||||
	if len(c.ResultsDir) != 0 {
 | 
			
		||||
		if ok, _ := valid.IsFilePath(c.ResultsDir); !ok {
 | 
			
		||||
			errs = append(errs, fmt.Errorf(
 | 
			
		||||
				"JSON base directory must be a *Absolute* file path. -results-dir: %s", c.ResultsDir))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	errs := c.checkSSHKeyExist()
 | 
			
		||||
 | 
			
		||||
	if runtime.GOOS == "windows" && !c.SSHNative {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("-ssh-native-insecure is needed on windows"))
 | 
			
		||||
		errs = append(errs, xerrors.New("-ssh-native-insecure is needed on windows"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.ResultsDir) != 0 {
 | 
			
		||||
		if ok, _ := valid.IsFilePath(c.ResultsDir); !ok {
 | 
			
		||||
			errs = append(errs, fmt.Errorf(
 | 
			
		||||
			errs = append(errs, xerrors.Errorf(
 | 
			
		||||
				"JSON base directory must be a *Absolute* file path. -results-dir: %s", c.ResultsDir))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.CacheDBPath) != 0 {
 | 
			
		||||
		if ok, _ := valid.IsFilePath(c.CacheDBPath); !ok {
 | 
			
		||||
			errs = append(errs, fmt.Errorf(
 | 
			
		||||
			errs = append(errs, xerrors.Errorf(
 | 
			
		||||
				"Cache DB path must be a *Absolute* file path. -cache-dbpath: %s",
 | 
			
		||||
				c.CacheDBPath))
 | 
			
		||||
		}
 | 
			
		||||
@@ -224,6 +211,21 @@ func (c Config) ValidateOnScan() bool {
 | 
			
		||||
	return len(errs) == 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c Config) checkSSHKeyExist() (errs []error) {
 | 
			
		||||
	for serverName, v := range c.Servers {
 | 
			
		||||
		if v.Type == ServerTypePseudo {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if v.KeyPath != "" {
 | 
			
		||||
			if _, err := os.Stat(v.KeyPath); err != nil {
 | 
			
		||||
				errs = append(errs, xerrors.Errorf(
 | 
			
		||||
					"%s is invalid. keypath: %s not exists", serverName, v.KeyPath))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return errs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ValidateOnReportDB validates configuration
 | 
			
		||||
func (c Config) ValidateOnReportDB() bool {
 | 
			
		||||
	errs := []error{}
 | 
			
		||||
@@ -231,11 +233,6 @@ func (c Config) ValidateOnReportDB() bool {
 | 
			
		||||
	if err := validateDB("cvedb", c.CveDict.Type, c.CveDict.SQLite3Path, c.CveDict.URL); err != nil {
 | 
			
		||||
		errs = append(errs, err)
 | 
			
		||||
	}
 | 
			
		||||
	if c.CveDict.Type == "sqlite3" {
 | 
			
		||||
		if _, err := os.Stat(c.CveDict.SQLite3Path); os.IsNotExist(err) {
 | 
			
		||||
			errs = append(errs, fmt.Errorf("SQLite3 DB path (%s) is not exist: %s", "cvedb", c.CveDict.SQLite3Path))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := validateDB("ovaldb", c.OvalDict.Type, c.OvalDict.SQLite3Path, c.OvalDict.URL); err != nil {
 | 
			
		||||
		errs = append(errs, err)
 | 
			
		||||
@@ -249,6 +246,10 @@ func (c Config) ValidateOnReportDB() bool {
 | 
			
		||||
		errs = append(errs, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := validateDB("msfdb", c.Metasploit.Type, c.Metasploit.SQLite3Path, c.Metasploit.URL); err != nil {
 | 
			
		||||
		errs = append(errs, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, err := range errs {
 | 
			
		||||
		log.Error(err)
 | 
			
		||||
	}
 | 
			
		||||
@@ -262,7 +263,7 @@ func (c Config) ValidateOnReport() bool {
 | 
			
		||||
 | 
			
		||||
	if len(c.ResultsDir) != 0 {
 | 
			
		||||
		if ok, _ := valid.IsFilePath(c.ResultsDir); !ok {
 | 
			
		||||
			errs = append(errs, fmt.Errorf(
 | 
			
		||||
			errs = append(errs, xerrors.Errorf(
 | 
			
		||||
				"JSON base directory must be a *Absolute* file path. -results-dir: %s", c.ResultsDir))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -321,7 +322,7 @@ func (c Config) ValidateOnTui() bool {
 | 
			
		||||
 | 
			
		||||
	if len(c.ResultsDir) != 0 {
 | 
			
		||||
		if ok, _ := valid.IsFilePath(c.ResultsDir); !ok {
 | 
			
		||||
			errs = append(errs, fmt.Errorf(
 | 
			
		||||
			errs = append(errs, xerrors.Errorf(
 | 
			
		||||
				"JSON base directory must be a *Absolute* file path. -results-dir: %s", c.ResultsDir))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -329,11 +330,6 @@ func (c Config) ValidateOnTui() bool {
 | 
			
		||||
	if err := validateDB("cvedb", c.CveDict.Type, c.CveDict.SQLite3Path, c.CveDict.URL); err != nil {
 | 
			
		||||
		errs = append(errs, err)
 | 
			
		||||
	}
 | 
			
		||||
	if c.CveDict.Type == "sqlite3" {
 | 
			
		||||
		if _, err := os.Stat(c.CveDict.SQLite3Path); os.IsNotExist(err) {
 | 
			
		||||
			errs = append(errs, fmt.Errorf("SQLite3 DB path (%s) is not exist: %s", "cvedb", c.CveDict.SQLite3Path))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, err := range errs {
 | 
			
		||||
		log.Error(err)
 | 
			
		||||
@@ -351,35 +347,35 @@ func validateDB(dictionaryDBName, dbType, dbPath, dbURL string) error {
 | 
			
		||||
	switch dbType {
 | 
			
		||||
	case "sqlite3":
 | 
			
		||||
		if dbURL != "" {
 | 
			
		||||
			return fmt.Errorf("To use SQLite3, specify -%s-type=sqlite3 and -%s-path. To use as http server mode, specify -%s-type=http and -%s-url",
 | 
			
		||||
			return xerrors.Errorf("To use SQLite3, specify -%s-type=sqlite3 and -%s-path. To use as http server mode, specify -%s-type=http and -%s-url",
 | 
			
		||||
				dictionaryDBName, dictionaryDBName, dictionaryDBName, dictionaryDBName)
 | 
			
		||||
		}
 | 
			
		||||
		if ok, _ := valid.IsFilePath(dbPath); !ok {
 | 
			
		||||
			return fmt.Errorf("SQLite3 path must be a *Absolute* file path. -%s-path: %s",
 | 
			
		||||
			return xerrors.Errorf("SQLite3 path must be a *Absolute* file path. -%s-path: %s",
 | 
			
		||||
				dictionaryDBName, dbPath)
 | 
			
		||||
		}
 | 
			
		||||
	case "mysql":
 | 
			
		||||
		if dbURL == "" {
 | 
			
		||||
			return fmt.Errorf(`MySQL connection string is needed. -%s-url="user:pass@tcp(localhost:3306)/dbname"`,
 | 
			
		||||
			return xerrors.Errorf(`MySQL connection string is needed. -%s-url="user:pass@tcp(localhost:3306)/dbname"`,
 | 
			
		||||
				dictionaryDBName)
 | 
			
		||||
		}
 | 
			
		||||
	case "postgres":
 | 
			
		||||
		if dbURL == "" {
 | 
			
		||||
			return fmt.Errorf(`PostgreSQL connection string is needed. -%s-url="host=myhost user=user dbname=dbname sslmode=disable password=password"`,
 | 
			
		||||
			return xerrors.Errorf(`PostgreSQL connection string is needed. -%s-url="host=myhost user=user dbname=dbname sslmode=disable password=password"`,
 | 
			
		||||
				dictionaryDBName)
 | 
			
		||||
		}
 | 
			
		||||
	case "redis":
 | 
			
		||||
		if dbURL == "" {
 | 
			
		||||
			return fmt.Errorf(`Redis connection string is needed. -%s-url="redis://localhost/0"`,
 | 
			
		||||
			return xerrors.Errorf(`Redis connection string is needed. -%s-url="redis://localhost/0"`,
 | 
			
		||||
				dictionaryDBName)
 | 
			
		||||
		}
 | 
			
		||||
	case "http":
 | 
			
		||||
		if dbURL == "" {
 | 
			
		||||
			return fmt.Errorf(`URL is needed. -%s-url="http://localhost:1323"`,
 | 
			
		||||
			return xerrors.Errorf(`URL is needed. -%s-url="http://localhost:1323"`,
 | 
			
		||||
				dictionaryDBName)
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		return fmt.Errorf("%s type must be either 'sqlite3', 'mysql', 'postgres', 'redis' or 'http'.  -%s-type: %s",
 | 
			
		||||
		return xerrors.Errorf("%s type must be either 'sqlite3', 'mysql', 'postgres', 'redis' or 'http'.  -%s-type: %s",
 | 
			
		||||
			dictionaryDBName, dictionaryDBName, dbType)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
@@ -403,7 +399,7 @@ func checkEmails(emails []string) (errs []error) {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if ok := valid.IsEmail(addr); !ok {
 | 
			
		||||
			errs = append(errs, fmt.Errorf("Invalid email address. email: %s", addr))
 | 
			
		||||
			errs = append(errs, xerrors.Errorf("Invalid email address. email: %s", addr))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
@@ -425,16 +421,16 @@ func (c *SMTPConf) Validate() (errs []error) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.SMTPAddr) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("email.smtpAddr must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("email.smtpAddr must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
	if len(c.SMTPPort) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("email.smtpPort must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("email.smtpPort must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
	if len(c.To) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("email.To required at least one address"))
 | 
			
		||||
		errs = append(errs, xerrors.New("email.To required at least one address"))
 | 
			
		||||
	}
 | 
			
		||||
	if len(c.From) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("email.From required at least one address"))
 | 
			
		||||
		errs = append(errs, xerrors.New("email.From required at least one address"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := valid.ValidateStruct(c)
 | 
			
		||||
@@ -457,11 +453,11 @@ func (c *StrideConf) Validate() (errs []error) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.HookURL) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("stride.HookURL must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("stride.HookURL must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.AuthToken) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("stride.AuthToken must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("stride.AuthToken must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := valid.ValidateStruct(c)
 | 
			
		||||
@@ -489,21 +485,21 @@ func (c *SlackConf) Validate() (errs []error) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.HookURL) == 0 && len(c.LegacyToken) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("slack.hookURL or slack.LegacyToken must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("slack.hookURL or slack.LegacyToken must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.Channel) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("slack.channel must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("slack.channel must not be empty"))
 | 
			
		||||
	} else {
 | 
			
		||||
		if !(strings.HasPrefix(c.Channel, "#") ||
 | 
			
		||||
			c.Channel == "${servername}") {
 | 
			
		||||
			errs = append(errs, fmt.Errorf(
 | 
			
		||||
			errs = append(errs, xerrors.Errorf(
 | 
			
		||||
				"channel's prefix must be '#', channel: %s", c.Channel))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.AuthUser) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("slack.authUser must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("slack.authUser must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := valid.ValidateStruct(c)
 | 
			
		||||
@@ -526,11 +522,11 @@ func (c *HipChatConf) Validate() (errs []error) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if len(c.Room) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("hipcaht.room must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("hipchat.room must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.AuthToken) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("hipcaht.AuthToken must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("hipchat.AuthToken must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := valid.ValidateStruct(c)
 | 
			
		||||
@@ -552,11 +548,11 @@ func (c *ChatWorkConf) Validate() (errs []error) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if len(c.Room) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("chatworkcaht.room must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("chatWorkConf.room must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.APIToken) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("chatworkcaht.ApiToken must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("chatWorkConf.ApiToken must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := valid.ValidateStruct(c)
 | 
			
		||||
@@ -578,11 +574,11 @@ func (c *TelegramConf) Validate() (errs []error) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if len(c.ChatID) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("TelegramConf.ChatID must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("TelegramConf.ChatID must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.Token) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("TelegramConf.Token must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("TelegramConf.Token must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := valid.ValidateStruct(c)
 | 
			
		||||
@@ -594,7 +590,7 @@ func (c *TelegramConf) Validate() (errs []error) {
 | 
			
		||||
 | 
			
		||||
// SaasConf is stride config
 | 
			
		||||
type SaasConf struct {
 | 
			
		||||
	GroupID int    `json:"-"`
 | 
			
		||||
	GroupID int64  `json:"-"`
 | 
			
		||||
	Token   string `json:"-"`
 | 
			
		||||
	URL     string `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
@@ -606,15 +602,15 @@ func (c *SaasConf) Validate() (errs []error) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if c.GroupID == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("saas.GroupID must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("saas.GroupID must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.Token) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("saas.Token must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("saas.Token must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(c.URL) == 0 {
 | 
			
		||||
		errs = append(errs, fmt.Errorf("saas.URL must not be empty"))
 | 
			
		||||
		errs = append(errs, xerrors.New("saas.URL must not be empty"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := valid.ValidateStruct(c)
 | 
			
		||||
@@ -688,7 +684,7 @@ func (c *SyslogConf) GetSeverity() (syslog.Priority, error) {
 | 
			
		||||
	case "debug":
 | 
			
		||||
		return syslog.LOG_DEBUG, nil
 | 
			
		||||
	default:
 | 
			
		||||
		return -1, fmt.Errorf("Invalid severity: %s", c.Severity)
 | 
			
		||||
		return -1, xerrors.Errorf("Invalid severity: %s", c.Severity)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -740,7 +736,7 @@ func (c *SyslogConf) GetFacility() (syslog.Priority, error) {
 | 
			
		||||
	case "local7":
 | 
			
		||||
		return syslog.LOG_LOCAL7, nil
 | 
			
		||||
	default:
 | 
			
		||||
		return -1, fmt.Errorf("Invalid facility: %s", c.Facility)
 | 
			
		||||
		return -1, xerrors.Errorf("Invalid facility: %s", c.Facility)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1009,6 +1005,64 @@ func (cnf *ExploitConf) IsFetchViaHTTP() bool {
 | 
			
		||||
	return Conf.Exploit.Type == "http"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MetasploitConf is metasploit config
 | 
			
		||||
type MetasploitConf struct {
 | 
			
		||||
	// DB type for metasploit dictionary (sqlite3, mysql, postgres or redis)
 | 
			
		||||
	Type string
 | 
			
		||||
 | 
			
		||||
	// http://metasploit-dictionary.com:1324 or DB connection string
 | 
			
		||||
	URL string `json:"-"`
 | 
			
		||||
 | 
			
		||||
	// /path/to/metasploit.sqlite3
 | 
			
		||||
	SQLite3Path string `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cnf *MetasploitConf) setDefault() {
 | 
			
		||||
	if cnf.Type == "" {
 | 
			
		||||
		cnf.Type = "sqlite3"
 | 
			
		||||
	}
 | 
			
		||||
	if cnf.URL == "" && cnf.SQLite3Path == "" {
 | 
			
		||||
		wd, _ := os.Getwd()
 | 
			
		||||
		cnf.SQLite3Path = filepath.Join(wd, "go-msfdb.sqlite3")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const metasploitDBType = "METASPLOITDB_TYPE"
 | 
			
		||||
const metasploitDBURL = "METASPLOITDB_URL"
 | 
			
		||||
const metasploitDBPATH = "METASPLOITDB_SQLITE3_PATH"
 | 
			
		||||
 | 
			
		||||
// Overwrite set options with the following priority.
 | 
			
		||||
// 1. Command line option
 | 
			
		||||
// 2. Environment variable
 | 
			
		||||
// 3. config.toml
 | 
			
		||||
func (cnf *MetasploitConf) Overwrite(cmdOpt MetasploitConf) {
 | 
			
		||||
	if os.Getenv(metasploitDBType) != "" {
 | 
			
		||||
		cnf.Type = os.Getenv(metasploitDBType)
 | 
			
		||||
	}
 | 
			
		||||
	if os.Getenv(metasploitDBURL) != "" {
 | 
			
		||||
		cnf.URL = os.Getenv(metasploitDBURL)
 | 
			
		||||
	}
 | 
			
		||||
	if os.Getenv(metasploitDBPATH) != "" {
 | 
			
		||||
		cnf.SQLite3Path = os.Getenv(metasploitDBPATH)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if cmdOpt.Type != "" {
 | 
			
		||||
		cnf.Type = cmdOpt.Type
 | 
			
		||||
	}
 | 
			
		||||
	if cmdOpt.URL != "" {
 | 
			
		||||
		cnf.URL = cmdOpt.URL
 | 
			
		||||
	}
 | 
			
		||||
	if cmdOpt.SQLite3Path != "" {
 | 
			
		||||
		cnf.SQLite3Path = cmdOpt.SQLite3Path
 | 
			
		||||
	}
 | 
			
		||||
	cnf.setDefault()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsFetchViaHTTP returns wether fetch via http
 | 
			
		||||
func (cnf *MetasploitConf) IsFetchViaHTTP() bool {
 | 
			
		||||
	return Conf.Metasploit.Type == "http"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AWS is aws config
 | 
			
		||||
type AWS struct {
 | 
			
		||||
	// AWS profile to use
 | 
			
		||||
@@ -1041,16 +1095,18 @@ type Azure struct {
 | 
			
		||||
 | 
			
		||||
// ServerInfo has SSH Info, additional CPE packages to scan.
 | 
			
		||||
type ServerInfo struct {
 | 
			
		||||
	ServerName             string                      `toml:"-" json:"serverName"`
 | 
			
		||||
	User                   string                      `toml:"user,omitempty" json:"user"`
 | 
			
		||||
	Host                   string                      `toml:"host,omitempty" json:"host"`
 | 
			
		||||
	Port                   string                      `toml:"port,omitempty" json:"port"`
 | 
			
		||||
	KeyPath                string                      `toml:"keyPath,omitempty" json:"keyPath"`
 | 
			
		||||
	KeyPassword            string                      `json:"-" toml:"-"`
 | 
			
		||||
	ServerName             string                      `toml:"-" json:"serverName,omitempty"`
 | 
			
		||||
	User                   string                      `toml:"user,omitempty" json:"user,omitempty"`
 | 
			
		||||
	Host                   string                      `toml:"host,omitempty" json:"host,omitempty"`
 | 
			
		||||
	JumpServer             []string                    `toml:"jumpServer,omitempty" json:"jumpServer,omitempty"`
 | 
			
		||||
	Port                   string                      `toml:"port,omitempty" json:"port,omitempty"`
 | 
			
		||||
	SSHConfigPath          string                      `toml:"sshConfigPath,omitempty" json:"sshConfigPath,omitempty"`
 | 
			
		||||
	KeyPath                string                      `toml:"keyPath,omitempty" json:"keyPath,omitempty"`
 | 
			
		||||
	KeyPassword            string                      `json:"-,omitempty" toml:"-"`
 | 
			
		||||
	CpeNames               []string                    `toml:"cpeNames,omitempty" json:"cpeNames,omitempty"`
 | 
			
		||||
	ScanMode               []string                    `toml:"scanMode,omitempty" json:"scanMode,omitempty"`
 | 
			
		||||
	DependencyCheckXMLPath string                      `toml:"dependencyCheckXMLPath,omitempty" json:"-"` // TODO Deprecated remove in near future
 | 
			
		||||
	OwaspDCXMLPath         string                      `toml:"owaspDCXMLPath,omitempty" json:"owaspDCXMLPath"`
 | 
			
		||||
	OwaspDCXMLPath         string                      `toml:"owaspDCXMLPath,omitempty" json:"owaspDCXMLPath,omitempty"`
 | 
			
		||||
	ContainersIncluded     []string                    `toml:"containersIncluded,omitempty" json:"containersIncluded,omitempty"`
 | 
			
		||||
	ContainersExcluded     []string                    `toml:"containersExcluded,omitempty" json:"containersExcluded,omitempty"`
 | 
			
		||||
	ContainerType          string                      `toml:"containerType,omitempty" json:"containerType,omitempty"`
 | 
			
		||||
@@ -1059,14 +1115,20 @@ type ServerInfo struct {
 | 
			
		||||
	IgnorePkgsRegexp       []string                    `toml:"ignorePkgsRegexp,omitempty" json:"ignorePkgsRegexp,omitempty"`
 | 
			
		||||
	GitHubRepos            map[string]GitHubConf       `toml:"githubs" json:"githubs,omitempty"` // key: owner/repo
 | 
			
		||||
	UUIDs                  map[string]string           `toml:"uuids,omitempty" json:"uuids,omitempty"`
 | 
			
		||||
	Memo                   string                      `toml:"memo,omitempty" json:"memo"`
 | 
			
		||||
	Memo                   string                      `toml:"memo,omitempty" json:"memo,omitempty"`
 | 
			
		||||
	Enablerepo             []string                    `toml:"enablerepo,omitempty" json:"enablerepo,omitempty"` // For CentOS, RHEL, Amazon
 | 
			
		||||
	Optional               map[string]interface{}      `toml:"optional,omitempty" json:"optional,omitempty"`     // Optional key-value set that will be outputted to JSON
 | 
			
		||||
	Type                   string                      `toml:"type,omitempty" json:"type"`                       // "pseudo" or ""
 | 
			
		||||
	IPv4Addrs              []string                    `toml:"-" json:"ipv4Addrs,omitempty"`
 | 
			
		||||
	IPv6Addrs              []string                    `toml:"-" json:"ipv6Addrs,omitempty"`
 | 
			
		||||
	Lockfiles              []string                    `toml:"lockfiles,omitempty" json:"lockfiles,omitempty"`   // ie) path/to/package-lock.json
 | 
			
		||||
	FindLock               bool                        `toml:"findLock,omitempty" json:"findLock,omitempty"`
 | 
			
		||||
	Type                   string                      `toml:"type,omitempty" json:"type,omitempty"` // "pseudo" or ""
 | 
			
		||||
 | 
			
		||||
	WordPress WordPressConf `toml:"wordpress,omitempty" json:"wordpress,omitempty"`
 | 
			
		||||
 | 
			
		||||
	// used internal
 | 
			
		||||
	IPv4Addrs      []string       `toml:"-" json:"ipv4Addrs,omitempty"`
 | 
			
		||||
	IPv6Addrs      []string       `toml:"-" json:"ipv6Addrs,omitempty"`
 | 
			
		||||
	IPSIdentifiers map[IPS]string `toml:"-" json:"ipsIdentifiers,omitempty"`
 | 
			
		||||
 | 
			
		||||
	LogMsgAnsiColor string    `toml:"-" json:"-"` // DebugLog Color
 | 
			
		||||
	Container       Container `toml:"-" json:"-"`
 | 
			
		||||
	Distro          Distro    `toml:"-" json:"-"`
 | 
			
		||||
@@ -1081,21 +1143,18 @@ type ContainerSetting struct {
 | 
			
		||||
	IgnoreCves       []string `json:"ignoreCves,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IntegrationConf is used for integration configuration
 | 
			
		||||
type IntegrationConf struct {
 | 
			
		||||
	GitHubConf map[string]GitHubConf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New creates IntegrationConf and initialize fields
 | 
			
		||||
func (c IntegrationConf) New() IntegrationConf {
 | 
			
		||||
	return IntegrationConf{
 | 
			
		||||
		GitHubConf: map[string]GitHubConf{},
 | 
			
		||||
	}
 | 
			
		||||
// WordPressConf used for WordPress Scanning
 | 
			
		||||
type WordPressConf struct {
 | 
			
		||||
	OSUser         string `toml:"osUser" json:"osUser,omitempty"`
 | 
			
		||||
	DocRoot        string `toml:"docRoot" json:"docRoot,omitempty"`
 | 
			
		||||
	CmdPath        string `toml:"cmdPath" json:"cmdPath,omitempty"`
 | 
			
		||||
	WPVulnDBToken  string `toml:"wpVulnDBToken" json:"-,omitempty"`
 | 
			
		||||
	IgnoreInactive bool   `json:"ignoreInactive,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GitHubConf is used for GitHub integration
 | 
			
		||||
type GitHubConf struct {
 | 
			
		||||
	Token string `json:"token"`
 | 
			
		||||
	Token string `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ScanMode has a type of scan mode. fast, fast-root, deep and offline
 | 
			
		||||
@@ -1138,9 +1197,9 @@ func (s ScanMode) validate() error {
 | 
			
		||||
	if numTrue == 0 {
 | 
			
		||||
		s.Set(Fast)
 | 
			
		||||
	} else if s.IsDeep() && s.IsOffline() {
 | 
			
		||||
		return fmt.Errorf("Don't specify both of -deep and offline")
 | 
			
		||||
		return xerrors.New("Don't specify both of -deep and offline")
 | 
			
		||||
	} else if numTrue != 1 {
 | 
			
		||||
		return fmt.Errorf("Specify only one of -fast, -fast-root or -deep")
 | 
			
		||||
		return xerrors.New("Specify only one of -fast, -fast-root or -deep")
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
@@ -1172,7 +1231,7 @@ const (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetServerName returns ServerName if this serverInfo is about host.
 | 
			
		||||
// If this serverInfo is abount a container, returns containerID@ServerName
 | 
			
		||||
// If this serverInfo is about a container, returns containerID@ServerName
 | 
			
		||||
func (s ServerInfo) GetServerName() string {
 | 
			
		||||
	if len(s.Container.ContainerID) == 0 {
 | 
			
		||||
		return s.ServerName
 | 
			
		||||
@@ -1191,21 +1250,18 @@ func (l Distro) String() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MajorVersion returns Major version
 | 
			
		||||
func (l Distro) MajorVersion() (ver int, err error) {
 | 
			
		||||
func (l Distro) MajorVersion() (int, error) {
 | 
			
		||||
	if l.Family == Amazon {
 | 
			
		||||
		ss := strings.Fields(l.Release)
 | 
			
		||||
		if len(ss) == 1 {
 | 
			
		||||
			return 1, nil
 | 
			
		||||
		}
 | 
			
		||||
		ver, err = strconv.Atoi(ss[0])
 | 
			
		||||
		return
 | 
			
		||||
		return strconv.Atoi(ss[0])
 | 
			
		||||
	}
 | 
			
		||||
	if 0 < len(l.Release) {
 | 
			
		||||
		ver, err = strconv.Atoi(strings.Split(l.Release, ".")[0])
 | 
			
		||||
	} else {
 | 
			
		||||
		err = fmt.Errorf("Release is empty")
 | 
			
		||||
		return strconv.Atoi(strings.Split(l.Release, ".")[0])
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
	return 0, xerrors.New("Release is empty")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsContainer returns whether this ServerInfo is about container
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ func TestSyslogConfValidate(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestMajorVersion(t *testing.T) {
 | 
			
		||||
func TestDistro_MajorVersion(t *testing.T) {
 | 
			
		||||
	var tests = []struct {
 | 
			
		||||
		in  Distro
 | 
			
		||||
		out int
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								config/ips.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,9 @@
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
// IPS is
 | 
			
		||||
type IPS string
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// DeepSecurity is
 | 
			
		||||
	DeepSecurity IPS = "deepsecurity"
 | 
			
		||||
)
 | 
			
		||||
@@ -1,23 +1,6 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
import "golang.org/x/xerrors"
 | 
			
		||||
 | 
			
		||||
// JSONLoader loads configuration
 | 
			
		||||
type JSONLoader struct {
 | 
			
		||||
@@ -25,5 +8,5 @@ type JSONLoader struct {
 | 
			
		||||
 | 
			
		||||
// Load load the configuration JSON file specified by path arg.
 | 
			
		||||
func (c JSONLoader) Load(path, sudoPass, keyPass string) (err error) {
 | 
			
		||||
	return fmt.Errorf("Not implement yet")
 | 
			
		||||
	return xerrors.New("Not implement yet")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
// Load loads configuration
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,12 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package config
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/BurntSushi/toml"
 | 
			
		||||
	"github.com/knqyf263/go-cpe/naming"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TOMLLoader loads config
 | 
			
		||||
@@ -53,6 +35,7 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
 | 
			
		||||
	Conf.OvalDict = conf.OvalDict
 | 
			
		||||
	Conf.Gost = conf.Gost
 | 
			
		||||
	Conf.Exploit = conf.Exploit
 | 
			
		||||
	Conf.Metasploit = conf.Metasploit
 | 
			
		||||
 | 
			
		||||
	d := conf.Default
 | 
			
		||||
	Conf.Default = d
 | 
			
		||||
@@ -65,14 +48,19 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
 | 
			
		||||
	i := 0
 | 
			
		||||
	for serverName, v := range conf.Servers {
 | 
			
		||||
		if 0 < len(v.KeyPassword) {
 | 
			
		||||
			return fmt.Errorf("[Deprecated] KEYPASSWORD IN CONFIG FILE ARE UNSECURE. REMOVE THEM IMMEDIATELY FOR A SECURITY REASONS. THEY WILL BE REMOVED IN A FUTURE RELEASE: %s", serverName)
 | 
			
		||||
			return xerrors.Errorf("[Deprecated] KEYPASSWORD IN CONFIG FILE ARE UNSECURE. REMOVE THEM IMMEDIATELY FOR A SECURITY REASONS. THEY WILL BE REMOVED IN A FUTURE RELEASE: %s", serverName)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s := ServerInfo{ServerName: serverName}
 | 
			
		||||
		if v.Type != ServerTypePseudo {
 | 
			
		||||
			s.Host = v.Host
 | 
			
		||||
			if len(s.Host) == 0 {
 | 
			
		||||
				return fmt.Errorf("%s is invalid. host is empty", serverName)
 | 
			
		||||
				return xerrors.Errorf("%s is invalid. host is empty", serverName)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			s.JumpServer = v.JumpServer
 | 
			
		||||
			if len(s.JumpServer) == 0 {
 | 
			
		||||
				s.JumpServer = d.JumpServer
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			switch {
 | 
			
		||||
@@ -91,21 +79,19 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
 | 
			
		||||
				s.User = d.User
 | 
			
		||||
			default:
 | 
			
		||||
				if s.Port != "local" {
 | 
			
		||||
					return fmt.Errorf("%s is invalid. User is empty", serverName)
 | 
			
		||||
					return xerrors.Errorf("%s is invalid. User is empty", serverName)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			s.SSHConfigPath = v.SSHConfigPath
 | 
			
		||||
			if len(s.SSHConfigPath) == 0 {
 | 
			
		||||
				s.SSHConfigPath = d.SSHConfigPath
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			s.KeyPath = v.KeyPath
 | 
			
		||||
			if len(s.KeyPath) == 0 {
 | 
			
		||||
				s.KeyPath = d.KeyPath
 | 
			
		||||
			}
 | 
			
		||||
			if s.KeyPath != "" {
 | 
			
		||||
				if _, err := os.Stat(s.KeyPath); err != nil {
 | 
			
		||||
					return fmt.Errorf(
 | 
			
		||||
						"%s is invalid. keypath: %s not exists", serverName, s.KeyPath)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			s.KeyPassword = v.KeyPassword
 | 
			
		||||
			if len(s.KeyPassword) == 0 {
 | 
			
		||||
				s.KeyPassword = d.KeyPassword
 | 
			
		||||
@@ -130,11 +116,11 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
 | 
			
		||||
			case "offline":
 | 
			
		||||
				s.Mode.Set(Offline)
 | 
			
		||||
			default:
 | 
			
		||||
				return fmt.Errorf("scanMode: %s of %s is invalie. Specify -fast, -fast-root, -deep or offline", m, serverName)
 | 
			
		||||
				return xerrors.Errorf("scanMode: %s of %s is invalid. Specify -fast, -fast-root, -deep or offline", m, serverName)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if err := s.Mode.validate(); err != nil {
 | 
			
		||||
			return fmt.Errorf("%s in %s", err, serverName)
 | 
			
		||||
			return xerrors.Errorf("%s in %s", err, serverName)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s.CpeNames = v.CpeNames
 | 
			
		||||
@@ -142,10 +128,17 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
 | 
			
		||||
			s.CpeNames = d.CpeNames
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s.Lockfiles = v.Lockfiles
 | 
			
		||||
		if len(s.Lockfiles) == 0 {
 | 
			
		||||
			s.Lockfiles = d.Lockfiles
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s.FindLock = v.FindLock
 | 
			
		||||
 | 
			
		||||
		for i, n := range s.CpeNames {
 | 
			
		||||
			uri, err := toCpeURI(n)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return fmt.Errorf("Failed to parse CPENames %s in %s: %s", n, serverName, err)
 | 
			
		||||
				return xerrors.Errorf("Failed to parse CPENames %s in %s, err: %w", n, serverName, err)
 | 
			
		||||
			}
 | 
			
		||||
			s.CpeNames[i] = uri
 | 
			
		||||
		}
 | 
			
		||||
@@ -172,7 +165,7 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(v.DependencyCheckXMLPath) != 0 || len(d.DependencyCheckXMLPath) != 0 {
 | 
			
		||||
			return fmt.Errorf("[DEPRECATED] dependencyCheckXMLPath IS DEPRECATED. USE owaspDCXMLPath INSTEAD: %s", serverName)
 | 
			
		||||
			return xerrors.Errorf("[DEPRECATED] dependencyCheckXMLPath IS DEPRECATED. USE owaspDCXMLPath INSTEAD: %s", serverName)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s.OwaspDCXMLPath = v.OwaspDCXMLPath
 | 
			
		||||
@@ -215,14 +208,14 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
 | 
			
		||||
		for _, reg := range s.IgnorePkgsRegexp {
 | 
			
		||||
			_, err := regexp.Compile(reg)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return fmt.Errorf("Faild to parse %s in %s. err: %s", reg, serverName, err)
 | 
			
		||||
				return xerrors.Errorf("Failed to parse %s in %s. err: %w", reg, serverName, err)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		for contName, cont := range s.Containers {
 | 
			
		||||
			for _, reg := range cont.IgnorePkgsRegexp {
 | 
			
		||||
				_, err := regexp.Compile(reg)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return fmt.Errorf("Faild to parse %s in %s@%s. err: %s",
 | 
			
		||||
					return xerrors.Errorf("Failed to parse %s in %s@%s. err: %w",
 | 
			
		||||
						reg, contName, serverName, err)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
@@ -247,7 +240,7 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
 | 
			
		||||
				case "base", "updates":
 | 
			
		||||
					// nop
 | 
			
		||||
				default:
 | 
			
		||||
					return fmt.Errorf(
 | 
			
		||||
					return xerrors.Errorf(
 | 
			
		||||
						"For now, enablerepo have to be base or updates: %s, servername: %s",
 | 
			
		||||
						s.Enablerepo, serverName)
 | 
			
		||||
				}
 | 
			
		||||
@@ -257,11 +250,11 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
 | 
			
		||||
		s.GitHubRepos = v.GitHubRepos
 | 
			
		||||
		for ownerRepo, githubSetting := range s.GitHubRepos {
 | 
			
		||||
			if ss := strings.Split(ownerRepo, "/"); len(ss) != 2 {
 | 
			
		||||
				return fmt.Errorf("Failed to parse GitHub owner/repo: %s in %s",
 | 
			
		||||
				return xerrors.Errorf("Failed to parse GitHub owner/repo: %s in %s",
 | 
			
		||||
					ownerRepo, serverName)
 | 
			
		||||
			}
 | 
			
		||||
			if githubSetting.Token == "" {
 | 
			
		||||
				return fmt.Errorf("GitHub owner/repo: %s in %s token is empty",
 | 
			
		||||
				return xerrors.Errorf("GitHub owner/repo: %s in %s token is empty",
 | 
			
		||||
					ownerRepo, serverName)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -269,6 +262,12 @@ func (c TOMLLoader) Load(pathToToml, keyPass string) error {
 | 
			
		||||
		s.UUIDs = v.UUIDs
 | 
			
		||||
		s.Type = v.Type
 | 
			
		||||
 | 
			
		||||
		s.WordPress.WPVulnDBToken = v.WordPress.WPVulnDBToken
 | 
			
		||||
		s.WordPress.CmdPath = v.WordPress.CmdPath
 | 
			
		||||
		s.WordPress.DocRoot = v.WordPress.DocRoot
 | 
			
		||||
		s.WordPress.OSUser = v.WordPress.OSUser
 | 
			
		||||
		s.WordPress.IgnoreInactive = v.WordPress.IgnoreInactive
 | 
			
		||||
 | 
			
		||||
		s.LogMsgAnsiColor = Colors[i%len(Colors)]
 | 
			
		||||
		i++
 | 
			
		||||
 | 
			
		||||
@@ -292,5 +291,5 @@ func toCpeURI(cpename string) (string, error) {
 | 
			
		||||
		}
 | 
			
		||||
		return naming.BindToURI(wfn), nil
 | 
			
		||||
	}
 | 
			
		||||
	return "", fmt.Errorf("Unknow CPE format: %s", cpename)
 | 
			
		||||
	return "", xerrors.Errorf("Unknown CPE format: %s", cpename)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								contrib/future-vuls/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,38 @@
 | 
			
		||||
# future-vuls
 | 
			
		||||
 | 
			
		||||
## Main Features
 | 
			
		||||
 | 
			
		||||
- upload vuls results json to future-vuls
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
git clone https://github.com/future-architect/vuls.git
 | 
			
		||||
make build-future-vuls
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Command Reference
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
Upload to FutureVuls
 | 
			
		||||
 | 
			
		||||
Usage:
 | 
			
		||||
  future-vuls upload [flags]
 | 
			
		||||
 | 
			
		||||
Flags:
 | 
			
		||||
      --config string   config file (default is $HOME/.cobra.yaml)
 | 
			
		||||
  -g, --group-id int    future vuls group id, ENV: VULS_GROUP_ID
 | 
			
		||||
  -h, --help            help for upload
 | 
			
		||||
  -s, --stdin           input from stdin. ENV: VULS_STDIN
 | 
			
		||||
  -t, --token string    future vuls token
 | 
			
		||||
      --url string      future vuls upload url
 | 
			
		||||
      --uuid string     server uuid. ENV: VULS_SERVER_UUID
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
- update results json
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 cat results.json | future-vuls upload --stdin --token xxxx --url https://xxxx --group-id 1 --uuid xxxx
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										98
									
								
								contrib/future-vuls/cmd/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,98 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"github.com/future-architect/vuls/report"
 | 
			
		||||
	"github.com/spf13/cobra"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	configFile string
 | 
			
		||||
	stdIn      bool
 | 
			
		||||
	jsonDir    string
 | 
			
		||||
	serverUUID string
 | 
			
		||||
	groupID    int64
 | 
			
		||||
	token      string
 | 
			
		||||
	url        string
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	var err error
 | 
			
		||||
	var cmdFvulsUploader = &cobra.Command{
 | 
			
		||||
		Use:   "upload",
 | 
			
		||||
		Short: "Upload to FutureVuls",
 | 
			
		||||
		Long:  `Upload to FutureVuls`,
 | 
			
		||||
		Run: func(cmd *cobra.Command, args []string) {
 | 
			
		||||
			if len(serverUUID) == 0 {
 | 
			
		||||
				serverUUID = os.Getenv("VULS_SERVER_UUID")
 | 
			
		||||
			}
 | 
			
		||||
			if groupID == 0 {
 | 
			
		||||
				envGroupID := os.Getenv("VULS_GROUP_ID")
 | 
			
		||||
				if groupID, err = strconv.ParseInt(envGroupID, 10, 64); err != nil {
 | 
			
		||||
					fmt.Printf("Invalid GroupID: %s\n", envGroupID)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if len(url) == 0 {
 | 
			
		||||
				url = os.Getenv("VULS_URL")
 | 
			
		||||
			}
 | 
			
		||||
			if len(token) == 0 {
 | 
			
		||||
				token = os.Getenv("VULS_TOKEN")
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var scanResultJSON []byte
 | 
			
		||||
			if stdIn {
 | 
			
		||||
				reader := bufio.NewReader(os.Stdin)
 | 
			
		||||
				buf := new(bytes.Buffer)
 | 
			
		||||
				if _, err = buf.ReadFrom(reader); err != nil {
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				scanResultJSON = buf.Bytes()
 | 
			
		||||
			} else {
 | 
			
		||||
				fmt.Println("use --stdin option")
 | 
			
		||||
				os.Exit(1)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var scanResult models.ScanResult
 | 
			
		||||
			if err = json.Unmarshal(scanResultJSON, &scanResult); err != nil {
 | 
			
		||||
				fmt.Println("Failed to parse json", err)
 | 
			
		||||
				os.Exit(1)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			scanResult.ServerUUID = serverUUID
 | 
			
		||||
 | 
			
		||||
			config.Conf.Saas.GroupID = groupID
 | 
			
		||||
			config.Conf.Saas.Token = token
 | 
			
		||||
			config.Conf.Saas.URL = url
 | 
			
		||||
			if err = (report.SaasWriter{}).Write(scanResult); err != nil {
 | 
			
		||||
				fmt.Println(err)
 | 
			
		||||
				os.Exit(1)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			return
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	cmdFvulsUploader.PersistentFlags().StringVar(&serverUUID, "uuid", "", "server uuid. ENV: VULS_SERVER_UUID")
 | 
			
		||||
	cmdFvulsUploader.PersistentFlags().StringVar(&configFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
 | 
			
		||||
	cmdFvulsUploader.PersistentFlags().BoolVarP(&stdIn, "stdin", "s", false, "input from stdin. ENV: VULS_STDIN")
 | 
			
		||||
	// TODO Read JSON file from directory
 | 
			
		||||
	//	cmdFvulsUploader.Flags().StringVarP(&jsonDir, "results-dir", "d", "./", "vuls scan results json dir")
 | 
			
		||||
	cmdFvulsUploader.PersistentFlags().Int64VarP(&groupID, "group-id", "g", 0, "future vuls group id, ENV: VULS_GROUP_ID")
 | 
			
		||||
	cmdFvulsUploader.PersistentFlags().StringVarP(&token, "token", "t", "", "future vuls token")
 | 
			
		||||
	cmdFvulsUploader.PersistentFlags().StringVar(&url, "url", "", "future vuls upload url")
 | 
			
		||||
 | 
			
		||||
	var rootCmd = &cobra.Command{Use: "future-vuls"}
 | 
			
		||||
	rootCmd.AddCommand(cmdFvulsUploader)
 | 
			
		||||
	if err = rootCmd.Execute(); err != nil {
 | 
			
		||||
		fmt.Println("Failed to execute command", err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -2,12 +2,13 @@ package parser
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/xml"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/knqyf263/go-cpe/naming"
 | 
			
		||||
	log "github.com/sirupsen/logrus"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type analysis struct {
 | 
			
		||||
@@ -15,12 +16,11 @@ type analysis struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type dependency struct {
 | 
			
		||||
	Identifiers []identifier `xml:"identifiers>identifier"`
 | 
			
		||||
	Identifiers []vulnerabilityID `xml:"identifiers>vulnerabilityIds"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type identifier struct {
 | 
			
		||||
	Name string `xml:"name"`
 | 
			
		||||
	Type string `xml:"type,attr"`
 | 
			
		||||
type vulnerabilityID struct {
 | 
			
		||||
	ID string `xml:"id"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func appendIfMissing(slice []string, str string) []string {
 | 
			
		||||
@@ -49,17 +49,22 @@ func Parse(path string) ([]string, error) {
 | 
			
		||||
 | 
			
		||||
	var anal analysis
 | 
			
		||||
	if err := xml.Unmarshal(b, &anal); err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("Failed to unmarshal: %s", err)
 | 
			
		||||
		return nil, xerrors.Errorf("Failed to unmarshal: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cpes := []string{}
 | 
			
		||||
	for _, d := range anal.Dependencies {
 | 
			
		||||
		for _, ident := range d.Identifiers {
 | 
			
		||||
			if ident.Type == "cpe" {
 | 
			
		||||
				name := strings.TrimPrefix(ident.Name, "(")
 | 
			
		||||
				name = strings.TrimSuffix(name, ")")
 | 
			
		||||
				cpes = appendIfMissing(cpes, name)
 | 
			
		||||
			id := ident.ID // Start with cpe:2.3:
 | 
			
		||||
			// Convert from CPE 2.3 to CPE 2.2
 | 
			
		||||
			if strings.HasPrefix(id, "cpe:2.3:") {
 | 
			
		||||
				wfn, err := naming.UnbindFS(id)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					return []string{}, err
 | 
			
		||||
				}
 | 
			
		||||
				id = naming.BindToURI(wfn)
 | 
			
		||||
			}
 | 
			
		||||
			cpes = appendIfMissing(cpes, id)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return cpes, nil
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								contrib/trivy/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,35 @@
 | 
			
		||||
# trivy-to-vuls
 | 
			
		||||
 | 
			
		||||
## Main Features
 | 
			
		||||
 | 
			
		||||
- convert trivy's results json to vuls's report json
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
git clone https://github.com/future-architect/vuls.git
 | 
			
		||||
make build-trivy-to-vuls
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Command Reference
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
Parse trivy json to vuls results
 | 
			
		||||
 | 
			
		||||
Usage:
 | 
			
		||||
  trivy-to-vuls parse [flags]
 | 
			
		||||
 | 
			
		||||
Flags:
 | 
			
		||||
  -h, --help                          help for parse
 | 
			
		||||
  -s, --stdin                         input from stdin
 | 
			
		||||
  -d, --trivy-json-dir string         trivy json dir (default "./")
 | 
			
		||||
  -f, --trivy-json-file-name string   trivy json file name (default "results.json")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
- use trivy output
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 trivy -q image -f=json python:3.4-alpine | trivy-to-vuls parse --stdin
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										78
									
								
								contrib/trivy/cmd/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,78 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
 | 
			
		||||
	"github.com/future-architect/vuls/contrib/trivy/parser"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"github.com/spf13/cobra"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	serverUUID   string
 | 
			
		||||
	stdIn        bool
 | 
			
		||||
	jsonDir      string
 | 
			
		||||
	jsonFileName string
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	var err error
 | 
			
		||||
	var cmdTrivyToVuls = &cobra.Command{
 | 
			
		||||
		Use:   "parse",
 | 
			
		||||
		Short: "Parse trivy json to vuls results",
 | 
			
		||||
		Long:  `Parse trivy json to vuls results`,
 | 
			
		||||
		Run: func(cmd *cobra.Command, args []string) {
 | 
			
		||||
			jsonFilePath := filepath.Join(jsonDir, jsonFileName)
 | 
			
		||||
			var trivyJSON []byte
 | 
			
		||||
			if stdIn {
 | 
			
		||||
				reader := bufio.NewReader(os.Stdin)
 | 
			
		||||
				buf := new(bytes.Buffer)
 | 
			
		||||
				if _, err = buf.ReadFrom(reader); err != nil {
 | 
			
		||||
					os.Exit(1)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				trivyJSON = buf.Bytes()
 | 
			
		||||
			} else {
 | 
			
		||||
				if trivyJSON, err = ioutil.ReadFile(jsonFilePath); err != nil {
 | 
			
		||||
					fmt.Println("Failed to read file", err)
 | 
			
		||||
					os.Exit(1)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			scanResult := &models.ScanResult{
 | 
			
		||||
				JSONVersion: models.JSONVersion,
 | 
			
		||||
				ScannedCves: models.VulnInfos{},
 | 
			
		||||
			}
 | 
			
		||||
			if scanResult, err = parser.Parse(trivyJSON, scanResult); err != nil {
 | 
			
		||||
				fmt.Println("Failed to execute command", err)
 | 
			
		||||
				os.Exit(1)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			var resultJSON []byte
 | 
			
		||||
			if resultJSON, err = json.MarshalIndent(scanResult, "", "   "); err != nil {
 | 
			
		||||
				fmt.Println("Failed to create json", err)
 | 
			
		||||
				os.Exit(1)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			fmt.Println(string(resultJSON))
 | 
			
		||||
			return
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	cmdTrivyToVuls.Flags().BoolVarP(&stdIn, "stdin", "s", false, "input from stdin")
 | 
			
		||||
	cmdTrivyToVuls.Flags().StringVarP(&jsonDir, "trivy-json-dir", "d", "./", "trivy json dir")
 | 
			
		||||
	cmdTrivyToVuls.Flags().StringVarP(&jsonFileName, "trivy-json-file-name", "f", "results.json", "trivy json file name")
 | 
			
		||||
 | 
			
		||||
	var rootCmd = &cobra.Command{Use: "trivy-to-vuls"}
 | 
			
		||||
	rootCmd.AddCommand(cmdTrivyToVuls)
 | 
			
		||||
	if err = rootCmd.Execute(); err != nil {
 | 
			
		||||
		fmt.Println("Failed to execute command", err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										164
									
								
								contrib/trivy/parser/parser.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,164 @@
 | 
			
		||||
package parser
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/aquasecurity/fanal/analyzer/os"
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/report"
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/types"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Parse :
 | 
			
		||||
func Parse(vulnJSON []byte, scanResult *models.ScanResult) (result *models.ScanResult, err error) {
 | 
			
		||||
	var trivyResults report.Results
 | 
			
		||||
	if err = json.Unmarshal(vulnJSON, &trivyResults); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pkgs := models.Packages{}
 | 
			
		||||
	vulnInfos := models.VulnInfos{}
 | 
			
		||||
	uniqueLibraryScannerPaths := map[string]models.LibraryScanner{}
 | 
			
		||||
	for _, trivyResult := range trivyResults {
 | 
			
		||||
		for _, vuln := range trivyResult.Vulnerabilities {
 | 
			
		||||
			if _, ok := vulnInfos[vuln.VulnerabilityID]; !ok {
 | 
			
		||||
				vulnInfos[vuln.VulnerabilityID] = models.VulnInfo{
 | 
			
		||||
					CveID: vuln.VulnerabilityID,
 | 
			
		||||
					Confidences: models.Confidences{
 | 
			
		||||
						{
 | 
			
		||||
							Score:           100,
 | 
			
		||||
							DetectionMethod: models.TrivyMatchStr,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
					AffectedPackages: models.PackageFixStatuses{},
 | 
			
		||||
					CveContents:      models.CveContents{},
 | 
			
		||||
					LibraryFixedIns:  models.LibraryFixedIns{},
 | 
			
		||||
					// VulnType : "",
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			vulnInfo := vulnInfos[vuln.VulnerabilityID]
 | 
			
		||||
			var notFixedYet bool
 | 
			
		||||
			fixState := ""
 | 
			
		||||
			if len(vuln.FixedVersion) == 0 {
 | 
			
		||||
				notFixedYet = true
 | 
			
		||||
				fixState = "Affected"
 | 
			
		||||
			}
 | 
			
		||||
			var references models.References
 | 
			
		||||
			for _, reference := range vuln.References {
 | 
			
		||||
				references = append(references, models.Reference{
 | 
			
		||||
					Source: "trivy",
 | 
			
		||||
					Link:   reference,
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			sort.Slice(references, func(i, j int) bool {
 | 
			
		||||
				return references[i].Link < references[j].Link
 | 
			
		||||
			})
 | 
			
		||||
 | 
			
		||||
			vulnInfo.CveContents = models.CveContents{
 | 
			
		||||
				models.Trivy: models.CveContent{
 | 
			
		||||
					Cvss3Severity: vuln.Severity,
 | 
			
		||||
					References:    references,
 | 
			
		||||
					Title:         vuln.Title,
 | 
			
		||||
					Summary:       vuln.Description,
 | 
			
		||||
				},
 | 
			
		||||
			}
 | 
			
		||||
			// do only if image type is Vuln
 | 
			
		||||
			if IsTrivySupportedOS(trivyResult.Type) {
 | 
			
		||||
				pkgs[vuln.PkgName] = models.Package{
 | 
			
		||||
					Name:    vuln.PkgName,
 | 
			
		||||
					Version: vuln.InstalledVersion,
 | 
			
		||||
				}
 | 
			
		||||
				vulnInfo.AffectedPackages = append(vulnInfo.AffectedPackages, models.PackageFixStatus{
 | 
			
		||||
					Name:        vuln.PkgName,
 | 
			
		||||
					NotFixedYet: notFixedYet,
 | 
			
		||||
					FixState:    fixState,
 | 
			
		||||
					FixedIn:     vuln.FixedVersion,
 | 
			
		||||
				})
 | 
			
		||||
 | 
			
		||||
				// overwrite every time if os package
 | 
			
		||||
				scanResult.Family = trivyResult.Type
 | 
			
		||||
				scanResult.ServerName = trivyResult.Target
 | 
			
		||||
				scanResult.Optional = map[string]interface{}{
 | 
			
		||||
					"trivy-target": trivyResult.Target,
 | 
			
		||||
				}
 | 
			
		||||
				scanResult.ScannedAt = time.Now()
 | 
			
		||||
				scanResult.ScannedBy = "trivy"
 | 
			
		||||
				scanResult.ScannedVia = "trivy"
 | 
			
		||||
			} else {
 | 
			
		||||
				// LibraryScanの結果
 | 
			
		||||
				vulnInfo.LibraryFixedIns = append(vulnInfo.LibraryFixedIns, models.LibraryFixedIn{
 | 
			
		||||
					Key:     trivyResult.Type,
 | 
			
		||||
					Name:    vuln.PkgName,
 | 
			
		||||
					Path:    trivyResult.Target,
 | 
			
		||||
					FixedIn: vuln.FixedVersion,
 | 
			
		||||
				})
 | 
			
		||||
				libScanner := uniqueLibraryScannerPaths[trivyResult.Target]
 | 
			
		||||
				libScanner.Libs = append(libScanner.Libs, types.Library{
 | 
			
		||||
					Name:    vuln.PkgName,
 | 
			
		||||
					Version: vuln.InstalledVersion,
 | 
			
		||||
				})
 | 
			
		||||
				uniqueLibraryScannerPaths[trivyResult.Target] = libScanner
 | 
			
		||||
			}
 | 
			
		||||
			vulnInfos[vuln.VulnerabilityID] = vulnInfo
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// flatten and unique libraries
 | 
			
		||||
	libraryScanners := make([]models.LibraryScanner, 0, len(uniqueLibraryScannerPaths))
 | 
			
		||||
	for path, v := range uniqueLibraryScannerPaths {
 | 
			
		||||
		uniqueLibrary := map[string]types.Library{}
 | 
			
		||||
		for _, lib := range v.Libs {
 | 
			
		||||
			uniqueLibrary[lib.Name+lib.Version] = lib
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var libraries []types.Library
 | 
			
		||||
		for _, library := range uniqueLibrary {
 | 
			
		||||
			libraries = append(libraries, library)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sort.Slice(libraries, func(i, j int) bool {
 | 
			
		||||
			return libraries[i].Name < libraries[j].Name
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		libscanner := models.LibraryScanner{
 | 
			
		||||
			Path: path,
 | 
			
		||||
			Libs: libraries,
 | 
			
		||||
		}
 | 
			
		||||
		libraryScanners = append(libraryScanners, libscanner)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Slice(libraryScanners, func(i, j int) bool {
 | 
			
		||||
		return libraryScanners[i].Path < libraryScanners[j].Path
 | 
			
		||||
	})
 | 
			
		||||
	scanResult.ScannedCves = vulnInfos
 | 
			
		||||
	scanResult.Packages = pkgs
 | 
			
		||||
	scanResult.LibraryScanners = libraryScanners
 | 
			
		||||
	return scanResult, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsTrivySupportedOS :
 | 
			
		||||
func IsTrivySupportedOS(family string) bool {
 | 
			
		||||
	supportedFamilies := []string{
 | 
			
		||||
		os.RedHat,
 | 
			
		||||
		os.Debian,
 | 
			
		||||
		os.Ubuntu,
 | 
			
		||||
		os.CentOS,
 | 
			
		||||
		os.Fedora,
 | 
			
		||||
		os.Amazon,
 | 
			
		||||
		os.Oracle,
 | 
			
		||||
		os.Windows,
 | 
			
		||||
		os.OpenSUSE,
 | 
			
		||||
		os.OpenSUSELeap,
 | 
			
		||||
		os.OpenSUSETumbleweed,
 | 
			
		||||
		os.SLES,
 | 
			
		||||
		os.Photon,
 | 
			
		||||
		os.Alpine,
 | 
			
		||||
	}
 | 
			
		||||
	for _, supportedFamily := range supportedFamilies {
 | 
			
		||||
		if family == supportedFamily {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5482
									
								
								contrib/trivy/parser/parser_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										33
									
								
								cwe/cwe.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,33 @@
 | 
			
		||||
package cwe
 | 
			
		||||
 | 
			
		||||
// CweTopTwentyfive2019 has CWE-ID in CWE Top 25
 | 
			
		||||
var CweTopTwentyfive2019 = map[string]string{
 | 
			
		||||
	"119": "1",
 | 
			
		||||
	"79":  "2",
 | 
			
		||||
	"20":  "3",
 | 
			
		||||
	"200": "4",
 | 
			
		||||
	"125": "5",
 | 
			
		||||
	"89":  "6",
 | 
			
		||||
	"416": "7",
 | 
			
		||||
	"190": "8",
 | 
			
		||||
	"352": "9",
 | 
			
		||||
	"22":  "10",
 | 
			
		||||
	"78":  "11",
 | 
			
		||||
	"787": "12",
 | 
			
		||||
	"287": "13",
 | 
			
		||||
	"476": "14",
 | 
			
		||||
	"732": "16",
 | 
			
		||||
	"434": "16",
 | 
			
		||||
	"611": "17",
 | 
			
		||||
	"94":  "18",
 | 
			
		||||
	"798": "19",
 | 
			
		||||
	"400": "20",
 | 
			
		||||
	"772": "21",
 | 
			
		||||
	"426": "22",
 | 
			
		||||
	"502": "23",
 | 
			
		||||
	"269": "24",
 | 
			
		||||
	"295": "25",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CweTopTwentyfive2019URL has CWE Top25 links
 | 
			
		||||
var CweTopTwentyfive2019URL = "https://cwe.mitre.org/top25/archive/2019/2019_cwe_top25.html"
 | 
			
		||||
							
								
								
									
										33
									
								
								cwe/sans.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,33 @@
 | 
			
		||||
package cwe
 | 
			
		||||
 | 
			
		||||
// SansTopTwentyfive has CWE-ID in CWE/SANS Top 25
 | 
			
		||||
var SansTopTwentyfive = map[string]string{
 | 
			
		||||
	"89":  "1",
 | 
			
		||||
	"78":  "2",
 | 
			
		||||
	"120": "3",
 | 
			
		||||
	"79":  "4",
 | 
			
		||||
	"306": "5",
 | 
			
		||||
	"862": "6",
 | 
			
		||||
	"798": "7",
 | 
			
		||||
	"311": "8",
 | 
			
		||||
	"434": "9",
 | 
			
		||||
	"807": "10",
 | 
			
		||||
	"250": "11",
 | 
			
		||||
	"352": "12",
 | 
			
		||||
	"22":  "13",
 | 
			
		||||
	"494": "14",
 | 
			
		||||
	"863": "15",
 | 
			
		||||
	"829": "16",
 | 
			
		||||
	"732": "17",
 | 
			
		||||
	"676": "18",
 | 
			
		||||
	"327": "19",
 | 
			
		||||
	"131": "20",
 | 
			
		||||
	"307": "21",
 | 
			
		||||
	"601": "22",
 | 
			
		||||
	"134": "23",
 | 
			
		||||
	"190": "24",
 | 
			
		||||
	"759": "25",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SansTopTwentyfiveURL is a URL of sans 25
 | 
			
		||||
var SansTopTwentyfiveURL = "https://www.sans.org/top25-software-errors/"
 | 
			
		||||
							
								
								
									
										27
									
								
								errof/errof.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,27 @@
 | 
			
		||||
package errof
 | 
			
		||||
 | 
			
		||||
// ErrorCode is vuls error code
 | 
			
		||||
type ErrorCode string
 | 
			
		||||
 | 
			
		||||
// Error is vuls error
 | 
			
		||||
type Error struct {
 | 
			
		||||
	Code    ErrorCode
 | 
			
		||||
	Message string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e Error) Error() string {
 | 
			
		||||
	return e.Message
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// ErrFailedToAccessGithubAPI is error of github alert's api access
 | 
			
		||||
	ErrFailedToAccessGithubAPI ErrorCode = "ErrFailedToAccessGithubAPI"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// New :
 | 
			
		||||
func New(code ErrorCode, msg string) Error {
 | 
			
		||||
	return Error{
 | 
			
		||||
		Code:    code,
 | 
			
		||||
		Message: msg,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Architect, Inc. Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package exploit
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -28,6 +11,7 @@ import (
 | 
			
		||||
	"github.com/mozqnet/go-exploitdb/db"
 | 
			
		||||
	exploitmodels "github.com/mozqnet/go-exploitdb/models"
 | 
			
		||||
	"github.com/parnurzeal/gorequest"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// FillWithExploit fills exploit information that has in Exploit
 | 
			
		||||
@@ -60,6 +44,9 @@ func FillWithExploit(driver db.DB, r *models.ScanResult) (nExploitCve int, err e
 | 
			
		||||
			return 0, nil
 | 
			
		||||
		}
 | 
			
		||||
		for cveID, vuln := range r.ScannedCves {
 | 
			
		||||
			if cveID == "" {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			es := driver.GetExploitByCveID(cveID)
 | 
			
		||||
			if len(es) == 0 {
 | 
			
		||||
				continue
 | 
			
		||||
@@ -112,8 +99,7 @@ func CheckHTTPHealth() error {
 | 
			
		||||
	//  resp, _, errs = gorequest.New().SetDebug(config.Conf.Debug).Get(url).End()
 | 
			
		||||
	//  resp, _, errs = gorequest.New().Proxy(api.httpProxy).Get(url).End()
 | 
			
		||||
	if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
 | 
			
		||||
		return fmt.Errorf("Failed to connect to exploit server. url: %s, errs: %v",
 | 
			
		||||
			url, errs)
 | 
			
		||||
		return xerrors.Errorf("Failed to connect to exploit server. url: %s, errs: %w", url, errs)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
package exploit
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestSetPackageStates(t *testing.T) {
 | 
			
		||||
}
 | 
			
		||||
@@ -1,30 +1,13 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Architect, Inc. Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package exploit
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/cenkalti/backoff"
 | 
			
		||||
	"github.com/future-architect/vuls/util"
 | 
			
		||||
	"github.com/parnurzeal/gorequest"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type response struct {
 | 
			
		||||
@@ -79,11 +62,11 @@ func getCvesViaHTTP(cveIDs []string, urlPrefix string) (
 | 
			
		||||
		case err := <-errChan:
 | 
			
		||||
			errs = append(errs, err)
 | 
			
		||||
		case <-timeout:
 | 
			
		||||
			return nil, fmt.Errorf("Timeout Fetching OVAL")
 | 
			
		||||
			return nil, xerrors.New("Timeout Fetching OVAL")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(errs) != 0 {
 | 
			
		||||
		return nil, fmt.Errorf("Failed to fetch OVAL. err: %v", errs)
 | 
			
		||||
		return nil, xerrors.Errorf("Failed to fetch OVAL. err: %w", errs)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
@@ -108,8 +91,7 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
 | 
			
		||||
			if count == retryMax {
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
			return fmt.Errorf("HTTP GET error: %v, url: %s, resp: %v",
 | 
			
		||||
				errs, url, resp)
 | 
			
		||||
			return xerrors.Errorf("HTTP GET error, url: %s, resp: %v, err: %w", url, resp, errs)
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
@@ -118,11 +100,11 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
 | 
			
		||||
	}
 | 
			
		||||
	err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		errChan <- fmt.Errorf("HTTP Error %s", err)
 | 
			
		||||
		errChan <- xerrors.Errorf("HTTP Error %w", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if count == retryMax {
 | 
			
		||||
		errChan <- fmt.Errorf("HRetry count exceeded")
 | 
			
		||||
		errChan <- xerrors.New("Retry count exceeded")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										153
									
								
								github/github.go
									
									
									
									
									
								
							
							
						
						@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package github
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -22,17 +5,17 @@ import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/errof"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"github.com/future-architect/vuls/util"
 | 
			
		||||
	"github.com/k0kubun/pp"
 | 
			
		||||
	"golang.org/x/oauth2"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// FillGitHubSecurityAlerts access to owner/repo on GitHub and fetch scurity alerts of the repository via GitHub API v4 GraphQL and then set to the given ScanResult.
 | 
			
		||||
// FillGitHubSecurityAlerts access to owner/repo on GitHub and fetch security alerts of the repository via GitHub API v4 GraphQL and then set to the given ScanResult.
 | 
			
		||||
// https://help.github.com/articles/about-security-alerts-for-vulnerable-dependencies/
 | 
			
		||||
func FillGitHubSecurityAlerts(r *models.ScanResult, owner, repo, token string) (nCVEs int, err error) {
 | 
			
		||||
	src := oauth2.StaticTokenSource(
 | 
			
		||||
@@ -41,8 +24,9 @@ func FillGitHubSecurityAlerts(r *models.ScanResult, owner, repo, token string) (
 | 
			
		||||
	httpClient := oauth2.NewClient(context.Background(), src)
 | 
			
		||||
 | 
			
		||||
	// TODO Use `https://github.com/shurcooL/githubv4` if the tool supports vulnerabilityAlerts Endpoint
 | 
			
		||||
	// Memo : https://developer.github.com/v4/explorer/
 | 
			
		||||
	const jsonfmt = `{"query":
 | 
			
		||||
	"query { repository(owner:\"%s\", name:\"%s\") { url, vulnerabilityAlerts(first: %d, %s) { pageInfo{ endCursor, hasNextPage, startCursor}, edges { node { id, externalIdentifier, externalReference, fixedIn, packageName,  dismissReason, dismissedAt } } } } }"}`
 | 
			
		||||
	"query { repository(owner:\"%s\", name:\"%s\") { url vulnerabilityAlerts(first: %d, %s) { pageInfo { endCursor hasNextPage startCursor } edges { node { id dismissReason dismissedAt securityVulnerability{ package { name ecosystem } severity vulnerableVersionRange firstPatchedVersion { identifier } } securityAdvisory { description ghsaId permalink publishedAt summary updatedAt withdrawnAt origin severity references { url } identifiers { type value } } } } } } } "}`
 | 
			
		||||
	after := ""
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
@@ -59,7 +43,7 @@ func FillGitHubSecurityAlerts(r *models.ScanResult, owner, repo, token string) (
 | 
			
		||||
		// To toggle this preview and access data, need to provide a custom media type in the Accept header:
 | 
			
		||||
		// MEMO: I tried to get the affected version via GitHub API. Bit it seems difficult to determin the affected version if there are multiple dependency files such as package.json.
 | 
			
		||||
		// TODO remove this header if it is no longer preview status in the future.
 | 
			
		||||
		req.Header.Set("Accept", "application/vnd.github.vixen-preview+json")
 | 
			
		||||
		req.Header.Set("Accept", "application/vnd.github.package-deletes-preview+json")
 | 
			
		||||
		req.Header.Set("Content-Type", "application/json")
 | 
			
		||||
 | 
			
		||||
		resp, err := httpClient.Do(req)
 | 
			
		||||
@@ -67,12 +51,25 @@ func FillGitHubSecurityAlerts(r *models.ScanResult, owner, repo, token string) (
 | 
			
		||||
			return 0, err
 | 
			
		||||
		}
 | 
			
		||||
		defer resp.Body.Close()
 | 
			
		||||
		alerts := SecurityAlerts{}
 | 
			
		||||
		if json.NewDecoder(resp.Body).Decode(&alerts); err != nil {
 | 
			
		||||
 | 
			
		||||
		body, err := ioutil.ReadAll(resp.Body)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return 0, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		util.Log.Debugf("%s", pp.Sprint(alerts))
 | 
			
		||||
		alerts := SecurityAlerts{}
 | 
			
		||||
		if err := json.Unmarshal(body, &alerts); err != nil {
 | 
			
		||||
			return 0, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// util.Log.Debugf("%s", pp.Sprint(alerts))
 | 
			
		||||
		// util.Log.Debugf("%s", string(body))
 | 
			
		||||
		if alerts.Data.Repository.URL == "" {
 | 
			
		||||
			return 0, errof.New(
 | 
			
		||||
				errof.ErrFailedToAccessGithubAPI,
 | 
			
		||||
				fmt.Sprintf("Failed to access to GitHub API. Response: %s", string(body)),
 | 
			
		||||
			)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, v := range alerts.Data.Repository.VulnerabilityAlerts.Edges {
 | 
			
		||||
			if config.Conf.IgnoreGitHubDismissed && v.Node.DismissReason != "" {
 | 
			
		||||
@@ -80,31 +77,45 @@ func FillGitHubSecurityAlerts(r *models.ScanResult, owner, repo, token string) (
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			pkgName := fmt.Sprintf("%s %s",
 | 
			
		||||
				alerts.Data.Repository.URL, v.Node.PackageName)
 | 
			
		||||
				alerts.Data.Repository.URL, v.Node.SecurityVulnerability.Package.Name)
 | 
			
		||||
 | 
			
		||||
			m := models.GitHubSecurityAlert{
 | 
			
		||||
				PackageName:   pkgName,
 | 
			
		||||
				FixedIn:       v.Node.FixedIn,
 | 
			
		||||
				AffectedRange: v.Node.AffectedRange,
 | 
			
		||||
				FixedIn:       v.Node.SecurityVulnerability.FirstPatchedVersion.Identifier,
 | 
			
		||||
				AffectedRange: v.Node.SecurityVulnerability.VulnerableVersionRange,
 | 
			
		||||
				Dismissed:     len(v.Node.DismissReason) != 0,
 | 
			
		||||
				DismissedAt:   v.Node.DismissedAt,
 | 
			
		||||
				DismissReason: v.Node.DismissReason,
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			cveID := v.Node.ExternalIdentifier
 | 
			
		||||
 | 
			
		||||
			if val, ok := r.ScannedCves[cveID]; ok {
 | 
			
		||||
				val.GitHubSecurityAlerts = val.GitHubSecurityAlerts.Add(m)
 | 
			
		||||
				r.ScannedCves[cveID] = val
 | 
			
		||||
				nCVEs++
 | 
			
		||||
			} else {
 | 
			
		||||
				v := models.VulnInfo{
 | 
			
		||||
					CveID:                cveID,
 | 
			
		||||
					Confidences:          models.Confidences{models.GitHubMatch},
 | 
			
		||||
					GitHubSecurityAlerts: models.GitHubSecurityAlerts{m},
 | 
			
		||||
			cveIDs, other := []string{}, []string{}
 | 
			
		||||
			for _, identifier := range v.Node.SecurityAdvisory.Identifiers {
 | 
			
		||||
				if identifier.Type == "CVE" {
 | 
			
		||||
					cveIDs = append(cveIDs, identifier.Value)
 | 
			
		||||
				} else {
 | 
			
		||||
					other = append(other, identifier.Value)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// If CVE-ID has not been assigned, use the GHSA ID etc as a ID.
 | 
			
		||||
			if len(cveIDs) == 0 {
 | 
			
		||||
				cveIDs = other
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for _, cveID := range cveIDs {
 | 
			
		||||
				if val, ok := r.ScannedCves[cveID]; ok {
 | 
			
		||||
					val.GitHubSecurityAlerts = val.GitHubSecurityAlerts.Add(m)
 | 
			
		||||
					r.ScannedCves[cveID] = val
 | 
			
		||||
					nCVEs++
 | 
			
		||||
				} else {
 | 
			
		||||
					v := models.VulnInfo{
 | 
			
		||||
						CveID:                cveID,
 | 
			
		||||
						Confidences:          models.Confidences{models.GitHubMatch},
 | 
			
		||||
						GitHubSecurityAlerts: models.GitHubSecurityAlerts{m},
 | 
			
		||||
					}
 | 
			
		||||
					r.ScannedCves[cveID] = v
 | 
			
		||||
					nCVEs++
 | 
			
		||||
				}
 | 
			
		||||
				r.ScannedCves[cveID] = v
 | 
			
		||||
				nCVEs++
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if !alerts.Data.Repository.VulnerabilityAlerts.PageInfo.HasNextPage {
 | 
			
		||||
@@ -119,26 +130,50 @@ func FillGitHubSecurityAlerts(r *models.ScanResult, owner, repo, token string) (
 | 
			
		||||
type SecurityAlerts struct {
 | 
			
		||||
	Data struct {
 | 
			
		||||
		Repository struct {
 | 
			
		||||
			URL                 string `json:"url,omitempty"`
 | 
			
		||||
			URL                 string `json:"url"`
 | 
			
		||||
			VulnerabilityAlerts struct {
 | 
			
		||||
				PageInfo struct {
 | 
			
		||||
					EndCursor   string `json:"endCursor,omitempty"`
 | 
			
		||||
					HasNextPage bool   `json:"hasNextPage,omitempty"`
 | 
			
		||||
					StartCursor string `json:"startCursor,omitempty"`
 | 
			
		||||
				} `json:"pageInfo,omitempty"`
 | 
			
		||||
					EndCursor   string `json:"endCursor"`
 | 
			
		||||
					HasNextPage bool   `json:"hasNextPage"`
 | 
			
		||||
					StartCursor string `json:"startCursor"`
 | 
			
		||||
				} `json:"pageInfo"`
 | 
			
		||||
				Edges []struct {
 | 
			
		||||
					Node struct {
 | 
			
		||||
						ID                 string    `json:"id,omitempty"`
 | 
			
		||||
						ExternalIdentifier string    `json:"externalIdentifier,omitempty"`
 | 
			
		||||
						ExternalReference  string    `json:"externalReference,omitempty"`
 | 
			
		||||
						FixedIn            string    `json:"fixedIn,omitempty"`
 | 
			
		||||
						AffectedRange      string    `json:"affectedRange,omitempty"`
 | 
			
		||||
						PackageName        string    `json:"packageName,omitempty"`
 | 
			
		||||
						DismissReason      string    `json:"dismissReason,omitempty"`
 | 
			
		||||
						DismissedAt        time.Time `json:"dismissedAt,omitempty"`
 | 
			
		||||
					} `json:"node,omitempty"`
 | 
			
		||||
				} `json:"edges,omitempty"`
 | 
			
		||||
			} `json:"vulnerabilityAlerts,omitempty"`
 | 
			
		||||
		} `json:"repository,omitempty"`
 | 
			
		||||
	} `json:"data,omitempty"`
 | 
			
		||||
						ID                    string    `json:"id"`
 | 
			
		||||
						DismissReason         string    `json:"dismissReason"`
 | 
			
		||||
						DismissedAt           time.Time `json:"dismissedAt"`
 | 
			
		||||
						SecurityVulnerability struct {
 | 
			
		||||
							Package struct {
 | 
			
		||||
								Name      string `json:"name"`
 | 
			
		||||
								Ecosystem string `json:"ecosystem"`
 | 
			
		||||
							} `json:"package"`
 | 
			
		||||
							Severity               string `json:"severity"`
 | 
			
		||||
							VulnerableVersionRange string `json:"vulnerableVersionRange"`
 | 
			
		||||
							FirstPatchedVersion    struct {
 | 
			
		||||
								Identifier string `json:"identifier"`
 | 
			
		||||
							} `json:"firstPatchedVersion"`
 | 
			
		||||
						} `json:"securityVulnerability"`
 | 
			
		||||
						SecurityAdvisory struct {
 | 
			
		||||
							Description string    `json:"description"`
 | 
			
		||||
							GhsaID      string    `json:"ghsaId"`
 | 
			
		||||
							Permalink   string    `json:"permalink"`
 | 
			
		||||
							PublishedAt time.Time `json:"publishedAt"`
 | 
			
		||||
							Summary     string    `json:"summary"`
 | 
			
		||||
							UpdatedAt   time.Time `json:"updatedAt"`
 | 
			
		||||
							WithdrawnAt time.Time `json:"withdrawnAt"`
 | 
			
		||||
							Origin      string    `json:"origin"`
 | 
			
		||||
							Severity    string    `json:"severity"`
 | 
			
		||||
							References  []struct {
 | 
			
		||||
								URL string `json:"url"`
 | 
			
		||||
							} `json:"references"`
 | 
			
		||||
							Identifiers []struct {
 | 
			
		||||
								Type  string `json:"type"`
 | 
			
		||||
								Value string `json:"value"`
 | 
			
		||||
							} `json:"identifiers"`
 | 
			
		||||
						} `json:"securityAdvisory"`
 | 
			
		||||
					} `json:"node"`
 | 
			
		||||
				} `json:"edges"`
 | 
			
		||||
			} `json:"vulnerabilityAlerts"`
 | 
			
		||||
		} `json:"repository"`
 | 
			
		||||
	} `json:"data"`
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										58
									
								
								go.mod
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,58 @@
 | 
			
		||||
module github.com/future-architect/vuls
 | 
			
		||||
 | 
			
		||||
go 1.14
 | 
			
		||||
 | 
			
		||||
replace (
 | 
			
		||||
	gopkg.in/mattn/go-colorable.v0 => github.com/mattn/go-colorable v0.1.0
 | 
			
		||||
	gopkg.in/mattn/go-isatty.v0 => github.com/mattn/go-isatty v0.0.6
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/Azure/azure-sdk-for-go v43.3.0+incompatible
 | 
			
		||||
	github.com/BurntSushi/toml v0.3.1
 | 
			
		||||
	github.com/RackSec/srslog v0.0.0-20180709174129-a4725f04ec91
 | 
			
		||||
	github.com/aquasecurity/fanal v0.0.0-20200615091807-df25cfa5f9af
 | 
			
		||||
	github.com/aquasecurity/trivy v0.9.1
 | 
			
		||||
	github.com/aquasecurity/trivy-db v0.0.0-20200616161554-cd5b3da29bc8
 | 
			
		||||
	github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a
 | 
			
		||||
	github.com/aws/aws-sdk-go v1.33.21
 | 
			
		||||
	github.com/boltdb/bolt v1.3.1
 | 
			
		||||
	github.com/cenkalti/backoff v2.2.1+incompatible
 | 
			
		||||
	github.com/d4l3k/messagediff v1.2.2-0.20190829033028-7e0a312ae40b
 | 
			
		||||
	github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21
 | 
			
		||||
	github.com/emersion/go-smtp v0.13.0
 | 
			
		||||
	github.com/google/subcommands v1.2.0
 | 
			
		||||
	github.com/gosuri/uitable v0.0.4
 | 
			
		||||
	github.com/hashicorp/go-uuid v1.0.2
 | 
			
		||||
	github.com/hashicorp/go-version v1.2.1
 | 
			
		||||
	github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c
 | 
			
		||||
	github.com/jesseduffield/gocui v0.3.0
 | 
			
		||||
	github.com/k0kubun/pp v3.0.1+incompatible
 | 
			
		||||
	github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f
 | 
			
		||||
	github.com/knqyf263/go-cpe v0.0.0-20180327054844-659663f6eca2
 | 
			
		||||
	github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d
 | 
			
		||||
	github.com/knqyf263/go-rpm-version v0.0.0-20170716094938-74609b86c936
 | 
			
		||||
	github.com/knqyf263/go-version v1.1.1
 | 
			
		||||
	github.com/knqyf263/gost v0.1.4
 | 
			
		||||
	github.com/kotakanbe/go-cve-dictionary v0.5.0
 | 
			
		||||
	github.com/kotakanbe/go-pingscanner v0.1.0
 | 
			
		||||
	github.com/kotakanbe/goval-dictionary v0.2.10
 | 
			
		||||
	github.com/kotakanbe/logrus-prefixed-formatter v0.0.0-20180123152602-928f7356cb96
 | 
			
		||||
	github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
 | 
			
		||||
	github.com/mitchellh/go-homedir v1.1.0
 | 
			
		||||
	github.com/mozqnet/go-exploitdb v0.1.0
 | 
			
		||||
	github.com/nlopes/slack v0.6.0
 | 
			
		||||
	github.com/nsf/termbox-go v0.0.0-20200418040025-38ba6e5628f1 // indirect
 | 
			
		||||
	github.com/olekukonko/tablewriter v0.0.4
 | 
			
		||||
	github.com/parnurzeal/gorequest v0.2.16
 | 
			
		||||
	github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
 | 
			
		||||
	github.com/sirupsen/logrus v1.6.0
 | 
			
		||||
	github.com/spf13/afero v1.3.0
 | 
			
		||||
	github.com/spf13/cobra v1.0.0
 | 
			
		||||
	github.com/takuzoo3868/go-msfdb v0.1.1
 | 
			
		||||
	golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
 | 
			
		||||
	golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
 | 
			
		||||
	golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
 | 
			
		||||
	golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
 | 
			
		||||
	k8s.io/utils v0.0.0-20200619165400-6e3d28b6ed19
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										51
									
								
								gost/base.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,51 @@
 | 
			
		||||
package gost
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	cnf "github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"github.com/knqyf263/gost/db"
 | 
			
		||||
	"github.com/parnurzeal/gorequest"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Base is a base struct
 | 
			
		||||
type Base struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FillCVEsWithRedHat fills cve information that has in Gost
 | 
			
		||||
func (b Base) FillCVEsWithRedHat(driver db.DB, r *models.ScanResult) error {
 | 
			
		||||
	return RedHat{}.fillFixed(driver, r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CheckHTTPHealth do health check
 | 
			
		||||
func (b Base) CheckHTTPHealth() error {
 | 
			
		||||
	if !cnf.Conf.Gost.IsFetchViaHTTP() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	url := fmt.Sprintf("%s/health", cnf.Conf.Gost.URL)
 | 
			
		||||
	var errs []error
 | 
			
		||||
	var resp *http.Response
 | 
			
		||||
	resp, _, errs = gorequest.New().Get(url).End()
 | 
			
		||||
	//  resp, _, errs = gorequest.New().SetDebug(config.Conf.Debug).Get(url).End()
 | 
			
		||||
	//  resp, _, errs = gorequest.New().Proxy(api.httpProxy).Get(url).End()
 | 
			
		||||
	if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
 | 
			
		||||
		return xerrors.Errorf("Failed to connect to gost server. url: %s, errs: %w", url, errs)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CheckIfGostFetched checks if oval entries are in DB by family, release.
 | 
			
		||||
func (b Base) CheckIfGostFetched(driver db.DB, osFamily string) (fetched bool, err error) {
 | 
			
		||||
	//TODO
 | 
			
		||||
	return true, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CheckIfGostFresh checks if oval entries are fresh enough
 | 
			
		||||
func (b Base) CheckIfGostFresh(driver db.DB, osFamily string) (ok bool, err error) {
 | 
			
		||||
	//TODO
 | 
			
		||||
	return true, nil
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Architect, Inc. Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package gost
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -38,8 +21,23 @@ type packCves struct {
 | 
			
		||||
	cves      []models.CveContent
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FillWithGost fills cve information that has in Gost
 | 
			
		||||
func (deb Debian) FillWithGost(driver db.DB, r *models.ScanResult) (nCVEs int, err error) {
 | 
			
		||||
func (deb Debian) Supported(major string) bool {
 | 
			
		||||
	_, ok := map[string]string{
 | 
			
		||||
		"8":  "jessie",
 | 
			
		||||
		"9":  "stretch",
 | 
			
		||||
		"10": "buster",
 | 
			
		||||
	}[major]
 | 
			
		||||
	return ok
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DetectUnfixed fills cve information that has in Gost
 | 
			
		||||
func (deb Debian) DetectUnfixed(driver db.DB, r *models.ScanResult, _ bool) (nCVEs int, err error) {
 | 
			
		||||
	if !deb.Supported(major(r.Release)) {
 | 
			
		||||
		// only logging
 | 
			
		||||
		util.Log.Warnf("Debian %s is not supported yet", r.Release)
 | 
			
		||||
		return 0, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	linuxImage := "linux-image-" + r.RunningKernel.Release
 | 
			
		||||
	// Add linux and set the version of running kernel to search OVAL.
 | 
			
		||||
	if r.Container.ContainerID == "" {
 | 
			
		||||
@@ -54,9 +52,17 @@ func (deb Debian) FillWithGost(driver db.DB, r *models.ScanResult) (nCVEs int, e
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Debian Security Tracker does not support Package for Raspbian, so skip it.
 | 
			
		||||
	var scanResult models.ScanResult
 | 
			
		||||
	if r.Family != config.Raspbian {
 | 
			
		||||
		scanResult = *r
 | 
			
		||||
	} else {
 | 
			
		||||
		scanResult = r.RemoveRaspbianPackFromResult()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	packCvesList := []packCves{}
 | 
			
		||||
	if config.Conf.Gost.IsFetchViaHTTP() {
 | 
			
		||||
		url, _ := util.URLPathJoin(config.Conf.Gost.URL, "debian", major(r.Release), "pkgs")
 | 
			
		||||
		url, _ := util.URLPathJoin(config.Conf.Gost.URL, "debian", major(scanResult.Release), "pkgs")
 | 
			
		||||
		responses, err := getAllUnfixedCvesViaHTTP(r, url)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return 0, err
 | 
			
		||||
@@ -81,8 +87,8 @@ func (deb Debian) FillWithGost(driver db.DB, r *models.ScanResult) (nCVEs int, e
 | 
			
		||||
		if driver == nil {
 | 
			
		||||
			return 0, nil
 | 
			
		||||
		}
 | 
			
		||||
		for _, pack := range r.Packages {
 | 
			
		||||
			cveDebs := driver.GetUnfixedCvesDebian(major(r.Release), pack.Name)
 | 
			
		||||
		for _, pack := range scanResult.Packages {
 | 
			
		||||
			cveDebs := driver.GetUnfixedCvesDebian(major(scanResult.Release), pack.Name)
 | 
			
		||||
			cves := []models.CveContent{}
 | 
			
		||||
			for _, cveDeb := range cveDebs {
 | 
			
		||||
				cves = append(cves, *deb.ConvertToModel(&cveDeb))
 | 
			
		||||
@@ -95,8 +101,8 @@ func (deb Debian) FillWithGost(driver db.DB, r *models.ScanResult) (nCVEs int, e
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// SrcPack
 | 
			
		||||
		for _, pack := range r.SrcPackages {
 | 
			
		||||
			cveDebs := driver.GetUnfixedCvesDebian(major(r.Release), pack.Name)
 | 
			
		||||
		for _, pack := range scanResult.SrcPackages {
 | 
			
		||||
			cveDebs := driver.GetUnfixedCvesDebian(major(scanResult.Release), pack.Name)
 | 
			
		||||
			cves := []models.CveContent{}
 | 
			
		||||
			for _, cveDeb := range cveDebs {
 | 
			
		||||
				cves = append(cves, *deb.ConvertToModel(&cveDeb))
 | 
			
		||||
@@ -147,7 +153,7 @@ func (deb Debian) FillWithGost(driver db.DB, r *models.ScanResult) (nCVEs int, e
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for _, name := range names {
 | 
			
		||||
				v.AffectedPackages = v.AffectedPackages.Store(models.PackageStatus{
 | 
			
		||||
				v.AffectedPackages = v.AffectedPackages.Store(models.PackageFixStatus{
 | 
			
		||||
					Name:        name,
 | 
			
		||||
					FixState:    "open",
 | 
			
		||||
					NotFixedYet: true,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										61
									
								
								gost/debian_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,61 @@
 | 
			
		||||
package gost
 | 
			
		||||
 | 
			
		||||
import "testing"
 | 
			
		||||
 | 
			
		||||
func TestDebian_Supported(t *testing.T) {
 | 
			
		||||
	type fields struct {
 | 
			
		||||
		Base Base
 | 
			
		||||
	}
 | 
			
		||||
	type args struct {
 | 
			
		||||
		major string
 | 
			
		||||
	}
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name string
 | 
			
		||||
		args args
 | 
			
		||||
		want bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "8 is supported",
 | 
			
		||||
			args: args{
 | 
			
		||||
				major: "8",
 | 
			
		||||
			},
 | 
			
		||||
			want: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "9 is supported",
 | 
			
		||||
			args: args{
 | 
			
		||||
				major: "9",
 | 
			
		||||
			},
 | 
			
		||||
			want: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "10 is supported",
 | 
			
		||||
			args: args{
 | 
			
		||||
				major: "10",
 | 
			
		||||
			},
 | 
			
		||||
			want: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "11 is not supported yet",
 | 
			
		||||
			args: args{
 | 
			
		||||
				major: "11",
 | 
			
		||||
			},
 | 
			
		||||
			want: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "empty string is not supported yet",
 | 
			
		||||
			args: args{
 | 
			
		||||
				major: "",
 | 
			
		||||
			},
 | 
			
		||||
			want: false,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.name, func(t *testing.T) {
 | 
			
		||||
			deb := Debian{}
 | 
			
		||||
			if got := deb.Supported(tt.args.major); got != tt.want {
 | 
			
		||||
				t.Errorf("Debian.Supported() = %v, want %v", got, tt.want)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								gost/gost.go
									
									
									
									
									
								
							
							
						
						@@ -1,36 +1,15 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Architect, Inc. Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package gost
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	cnf "github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"github.com/knqyf263/gost/db"
 | 
			
		||||
	"github.com/parnurzeal/gorequest"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Client is the interface of OVAL client.
 | 
			
		||||
type Client interface {
 | 
			
		||||
	FillWithGost(db.DB, *models.ScanResult) (int, error)
 | 
			
		||||
	DetectUnfixed(db.DB, *models.ScanResult, bool) (int, error)
 | 
			
		||||
	FillCVEsWithRedHat(db.DB, *models.ScanResult) error
 | 
			
		||||
 | 
			
		||||
	//TODO implement
 | 
			
		||||
	// CheckHTTPHealth() error
 | 
			
		||||
@@ -44,7 +23,7 @@ func NewClient(family string) Client {
 | 
			
		||||
	switch family {
 | 
			
		||||
	case cnf.RedHat, cnf.CentOS:
 | 
			
		||||
		return RedHat{}
 | 
			
		||||
	case cnf.Debian:
 | 
			
		||||
	case cnf.Debian, cnf.Raspbian:
 | 
			
		||||
		return Debian{}
 | 
			
		||||
	case cnf.Windows:
 | 
			
		||||
		return Microsoft{}
 | 
			
		||||
@@ -52,53 +31,3 @@ func NewClient(family string) Client {
 | 
			
		||||
		return Pseudo{}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Base is a base struct
 | 
			
		||||
type Base struct {
 | 
			
		||||
	family string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CheckHTTPHealth do health check
 | 
			
		||||
func (b Base) CheckHTTPHealth() error {
 | 
			
		||||
	if !cnf.Conf.Gost.IsFetchViaHTTP() {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	url := fmt.Sprintf("%s/health", cnf.Conf.Gost.URL)
 | 
			
		||||
	var errs []error
 | 
			
		||||
	var resp *http.Response
 | 
			
		||||
	resp, _, errs = gorequest.New().Get(url).End()
 | 
			
		||||
	//  resp, _, errs = gorequest.New().SetDebug(config.Conf.Debug).Get(url).End()
 | 
			
		||||
	//  resp, _, errs = gorequest.New().Proxy(api.httpProxy).Get(url).End()
 | 
			
		||||
	if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
 | 
			
		||||
		return fmt.Errorf("Failed to connect to gost server. url: %s, errs: %v",
 | 
			
		||||
			url, errs)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CheckIfGostFetched checks if oval entries are in DB by family, release.
 | 
			
		||||
func (b Base) CheckIfGostFetched(driver db.DB, osFamily string) (fetched bool, err error) {
 | 
			
		||||
	//TODO
 | 
			
		||||
	return true, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CheckIfGostFresh checks if oval entries are fresh enough
 | 
			
		||||
func (b Base) CheckIfGostFresh(driver db.DB, osFamily string) (ok bool, err error) {
 | 
			
		||||
	//TODO
 | 
			
		||||
	return true, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pseudo is Gost client except for RedHat family and Debian
 | 
			
		||||
type Pseudo struct {
 | 
			
		||||
	Base
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FillWithGost fills cve information that has in Gost
 | 
			
		||||
func (pse Pseudo) FillWithGost(driver db.DB, r *models.ScanResult) (int, error) {
 | 
			
		||||
	return 0, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func major(osVer string) (majorVersion string) {
 | 
			
		||||
	return strings.Split(osVer, ".")[0]
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ func TestSetPackageStates(t *testing.T) {
 | 
			
		||||
		installed models.Packages
 | 
			
		||||
		release   string
 | 
			
		||||
		in        models.VulnInfo
 | 
			
		||||
		out       models.PackageStatuses
 | 
			
		||||
		out       models.PackageFixStatuses
 | 
			
		||||
	}{
 | 
			
		||||
 | 
			
		||||
		//0 one
 | 
			
		||||
@@ -31,7 +31,7 @@ func TestSetPackageStates(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			release: "7",
 | 
			
		||||
			in:      models.VulnInfo{},
 | 
			
		||||
			out: []models.PackageStatus{
 | 
			
		||||
			out: []models.PackageFixStatus{
 | 
			
		||||
				{
 | 
			
		||||
					Name:        "bouncycastle",
 | 
			
		||||
					FixState:    "Will not fix",
 | 
			
		||||
@@ -66,7 +66,7 @@ func TestSetPackageStates(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			release: "7",
 | 
			
		||||
			in:      models.VulnInfo{},
 | 
			
		||||
			out: []models.PackageStatus{
 | 
			
		||||
			out: []models.PackageFixStatus{
 | 
			
		||||
				{
 | 
			
		||||
					Name:        "bouncycastle",
 | 
			
		||||
					FixState:    "Will not fix",
 | 
			
		||||
@@ -94,9 +94,9 @@ func TestSetPackageStates(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			release: "7",
 | 
			
		||||
			in: models.VulnInfo{
 | 
			
		||||
				AffectedPackages: models.PackageStatuses{},
 | 
			
		||||
				AffectedPackages: models.PackageFixStatuses{},
 | 
			
		||||
			},
 | 
			
		||||
			out: models.PackageStatuses{},
 | 
			
		||||
			out: models.PackageFixStatuses{},
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		//3 look only the same os release.
 | 
			
		||||
@@ -113,9 +113,9 @@ func TestSetPackageStates(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			release: "7",
 | 
			
		||||
			in: models.VulnInfo{
 | 
			
		||||
				AffectedPackages: models.PackageStatuses{},
 | 
			
		||||
				AffectedPackages: models.PackageFixStatuses{},
 | 
			
		||||
			},
 | 
			
		||||
			out: models.PackageStatuses{},
 | 
			
		||||
			out: models.PackageFixStatuses{},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package gost
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -30,12 +13,12 @@ type Microsoft struct {
 | 
			
		||||
	Base
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FillWithGost fills cve information that has in Gost
 | 
			
		||||
func (ms Microsoft) FillWithGost(driver db.DB, r *models.ScanResult) (nCVEs int, err error) {
 | 
			
		||||
// DetectUnfixed fills cve information that has in Gost
 | 
			
		||||
func (ms Microsoft) DetectUnfixed(driver db.DB, r *models.ScanResult, _ bool) (nCVEs int, err error) {
 | 
			
		||||
	if driver == nil {
 | 
			
		||||
		return 0, nil
 | 
			
		||||
	}
 | 
			
		||||
	var cveIDs []string
 | 
			
		||||
	cveIDs := []string{}
 | 
			
		||||
	for cveID := range r.ScannedCves {
 | 
			
		||||
		cveIDs = append(cveIDs, cveID)
 | 
			
		||||
	}
 | 
			
		||||
@@ -89,7 +72,7 @@ func (ms Microsoft) ConvertToModel(cve *gostmodels.MicrosoftCVE) *models.CveCont
 | 
			
		||||
	if 0 < len(cve.Workaround) {
 | 
			
		||||
		option["workaround"] = cve.Workaround
 | 
			
		||||
	}
 | 
			
		||||
	var kbids []string
 | 
			
		||||
	kbids := []string{}
 | 
			
		||||
	for _, kbid := range cve.KBIDs {
 | 
			
		||||
		kbids = append(kbids, kbid.KBID)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								gost/pseudo.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,22 @@
 | 
			
		||||
package gost
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"github.com/knqyf263/gost/db"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Pseudo is Gost client except for RedHat family and Debian
 | 
			
		||||
type Pseudo struct {
 | 
			
		||||
	Base
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DetectUnfixed fills cve information that has in Gost
 | 
			
		||||
func (pse Pseudo) DetectUnfixed(driver db.DB, r *models.ScanResult, _ bool) (int, error) {
 | 
			
		||||
	return 0, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func major(osVer string) (majorVersion string) {
 | 
			
		||||
	return strings.Split(osVer, ".")[0]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Architect, Inc. Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package gost
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -34,16 +17,13 @@ type RedHat struct {
 | 
			
		||||
	Base
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FillWithGost fills cve information that has in Gost
 | 
			
		||||
func (red RedHat) FillWithGost(driver db.DB, r *models.ScanResult) (nCVEs int, err error) {
 | 
			
		||||
	if nCVEs, err = red.fillUnfixed(driver, r); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return nCVEs, red.fillFixed(driver, r)
 | 
			
		||||
// DetectUnfixed fills cve information that has in Gost
 | 
			
		||||
func (red RedHat) DetectUnfixed(driver db.DB, r *models.ScanResult, ignoreWillNotFix bool) (nCVEs int, err error) {
 | 
			
		||||
	return red.fillUnfixed(driver, r, ignoreWillNotFix)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (red RedHat) fillFixed(driver db.DB, r *models.ScanResult) error {
 | 
			
		||||
	var cveIDs []string
 | 
			
		||||
	cveIDs := []string{}
 | 
			
		||||
	for cveID, vuln := range r.ScannedCves {
 | 
			
		||||
		if _, ok := vuln.CveContents[models.RedHatAPI]; ok {
 | 
			
		||||
			continue
 | 
			
		||||
@@ -88,7 +68,7 @@ func (red RedHat) fillFixed(driver db.DB, r *models.ScanResult) error {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
		for cveID, redCve := range driver.GetRedhatMulti(cveIDs) {
 | 
			
		||||
			if redCve.ID == 0 {
 | 
			
		||||
			if len(redCve.Name) == 0 {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			cveCont := red.ConvertToModel(&redCve)
 | 
			
		||||
@@ -113,7 +93,7 @@ func (red RedHat) fillFixed(driver db.DB, r *models.ScanResult) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (red RedHat) fillUnfixed(driver db.DB, r *models.ScanResult) (nCVEs int, err error) {
 | 
			
		||||
func (red RedHat) fillUnfixed(driver db.DB, r *models.ScanResult, ignoreWillNotFix bool) (nCVEs int, err error) {
 | 
			
		||||
	if config.Conf.Gost.IsFetchViaHTTP() {
 | 
			
		||||
		prefix, _ := util.URLPathJoin(config.Conf.Gost.URL,
 | 
			
		||||
			"redhat", major(r.Release), "pkgs")
 | 
			
		||||
@@ -159,8 +139,7 @@ func (red RedHat) fillUnfixed(driver db.DB, r *models.ScanResult) (nCVEs int, er
 | 
			
		||||
		}
 | 
			
		||||
		for _, pack := range r.Packages {
 | 
			
		||||
			// CVE-ID: RedhatCVE
 | 
			
		||||
			cves := map[string]gostmodels.RedhatCVE{}
 | 
			
		||||
			cves = driver.GetUnfixedCvesRedhat(major(r.Release), pack.Name)
 | 
			
		||||
			cves := driver.GetUnfixedCvesRedhat(major(r.Release), pack.Name, ignoreWillNotFix)
 | 
			
		||||
			for _, cve := range cves {
 | 
			
		||||
				cveCont := red.ConvertToModel(&cve)
 | 
			
		||||
				v, ok := r.ScannedCves[cve.Name]
 | 
			
		||||
@@ -191,7 +170,7 @@ func (red RedHat) fillUnfixed(driver db.DB, r *models.ScanResult) (nCVEs int, er
 | 
			
		||||
	return nCVEs, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (red RedHat) mergePackageStates(v models.VulnInfo, ps []gostmodels.RedhatPackageState, installed models.Packages, release string) (pkgStats models.PackageStatuses) {
 | 
			
		||||
func (red RedHat) mergePackageStates(v models.VulnInfo, ps []gostmodels.RedhatPackageState, installed models.Packages, release string) (pkgStats models.PackageFixStatuses) {
 | 
			
		||||
	pkgStats = v.AffectedPackages
 | 
			
		||||
	for _, pstate := range ps {
 | 
			
		||||
		if pstate.Cpe !=
 | 
			
		||||
@@ -200,7 +179,8 @@ func (red RedHat) mergePackageStates(v models.VulnInfo, ps []gostmodels.RedhatPa
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !(pstate.FixState == "Will not fix" ||
 | 
			
		||||
			pstate.FixState == "Fix deferred") {
 | 
			
		||||
			pstate.FixState == "Fix deferred" ||
 | 
			
		||||
			pstate.FixState == "Affected") {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -210,11 +190,11 @@ func (red RedHat) mergePackageStates(v models.VulnInfo, ps []gostmodels.RedhatPa
 | 
			
		||||
 | 
			
		||||
		notFixedYet := false
 | 
			
		||||
		switch pstate.FixState {
 | 
			
		||||
		case "Will not fix", "Fix deferred":
 | 
			
		||||
		case "Will not fix", "Fix deferred", "Affected":
 | 
			
		||||
			notFixedYet = true
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pkgStats = pkgStats.Store(models.PackageStatus{
 | 
			
		||||
		pkgStats = pkgStats.Store(models.PackageFixStatus{
 | 
			
		||||
			Name:        pstate.PackageName,
 | 
			
		||||
			FixState:    pstate.FixState,
 | 
			
		||||
			NotFixedYet: notFixedYet,
 | 
			
		||||
@@ -264,7 +244,7 @@ func (red RedHat) ConvertToModel(cve *gostmodels.RedhatCVE) *models.CveContent {
 | 
			
		||||
		v3severity = cve.ThreatSeverity
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var refs []models.Reference
 | 
			
		||||
	refs := []models.Reference{}
 | 
			
		||||
	for _, r := range cve.References {
 | 
			
		||||
		refs = append(refs, models.Reference{Link: r.Reference})
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								gost/util.go
									
									
									
									
									
								
							
							
						
						@@ -1,24 +1,6 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Architect, Inc. Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package gost
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
@@ -26,6 +8,7 @@ import (
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"github.com/future-architect/vuls/util"
 | 
			
		||||
	"github.com/parnurzeal/gorequest"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type response struct {
 | 
			
		||||
@@ -80,11 +63,11 @@ func getCvesViaHTTP(cveIDs []string, urlPrefix string) (
 | 
			
		||||
		case err := <-errChan:
 | 
			
		||||
			errs = append(errs, err)
 | 
			
		||||
		case <-timeout:
 | 
			
		||||
			return nil, fmt.Errorf("Timeout Fetching OVAL")
 | 
			
		||||
			return nil, xerrors.New("Timeout Fetching OVAL")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(errs) != 0 {
 | 
			
		||||
		return nil, fmt.Errorf("Failed to fetch OVAL. err: %v", errs)
 | 
			
		||||
		return nil, xerrors.Errorf("Failed to fetch OVAL. err: %w", errs)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
@@ -154,11 +137,11 @@ func getAllUnfixedCvesViaHTTP(r *models.ScanResult, urlPrefix string) (
 | 
			
		||||
		case err := <-errChan:
 | 
			
		||||
			errs = append(errs, err)
 | 
			
		||||
		case <-timeout:
 | 
			
		||||
			return nil, fmt.Errorf("Timeout Fetching OVAL")
 | 
			
		||||
			return nil, xerrors.New("Timeout Fetching OVAL")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(errs) != 0 {
 | 
			
		||||
		return nil, fmt.Errorf("Failed to fetch OVAL. err: %v", errs)
 | 
			
		||||
		return nil, xerrors.Errorf("Failed to fetch OVAL. err: %w", errs)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
@@ -176,8 +159,7 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
 | 
			
		||||
			if count == retryMax {
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
			return fmt.Errorf("HTTP GET error: %v, url: %s, resp: %v",
 | 
			
		||||
				errs, url, resp)
 | 
			
		||||
			return xerrors.Errorf("HTTP GET error, url: %s, resp: %v, err: %w", url, resp, errs)
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
@@ -186,11 +168,11 @@ func httpGet(url string, req request, resChan chan<- response, errChan chan<- er
 | 
			
		||||
	}
 | 
			
		||||
	err := backoff.RetryNotify(f, backoff.NewExponentialBackOff(), notify)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		errChan <- fmt.Errorf("HTTP Error %s", err)
 | 
			
		||||
		errChan <- xerrors.Errorf("HTTP Error %w", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if count == retryMax {
 | 
			
		||||
		errChan <- fmt.Errorf("HRetry count exceeded")
 | 
			
		||||
		errChan <- xerrors.New("Retry count exceeded")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 247 KiB  | 
| 
		 Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 297 KiB  | 
| 
		 Before Width: | Height: | Size: 97 KiB  | 
| 
		 Before Width: | Height: | Size: 91 KiB  | 
@@ -1,414 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
 | 
			
		||||
  <!--Created by yEd 3.17-->
 | 
			
		||||
  <key attr.name="Description" attr.type="string" for="graph" id="d0"/>
 | 
			
		||||
  <key for="port" id="d1" yfiles.type="portgraphics"/>
 | 
			
		||||
  <key for="port" id="d2" yfiles.type="portgeometry"/>
 | 
			
		||||
  <key for="port" id="d3" yfiles.type="portuserdata"/>
 | 
			
		||||
  <key attr.name="url" attr.type="string" for="node" id="d4"/>
 | 
			
		||||
  <key attr.name="description" attr.type="string" for="node" id="d5"/>
 | 
			
		||||
  <key for="node" id="d6" yfiles.type="nodegraphics"/>
 | 
			
		||||
  <key for="graphml" id="d7" yfiles.type="resources"/>
 | 
			
		||||
  <key attr.name="url" attr.type="string" for="edge" id="d8"/>
 | 
			
		||||
  <key attr.name="description" attr.type="string" for="edge" id="d9"/>
 | 
			
		||||
  <key for="edge" id="d10" yfiles.type="edgegraphics"/>
 | 
			
		||||
  <graph edgedefault="directed" id="G">
 | 
			
		||||
    <data key="d0"/>
 | 
			
		||||
    <node id="n0">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="309.6849206349206" y="0.0"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="83.482421875" x="92.2587890625" y="18.93359375">Detect the OS<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="0.1619001116071429" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n1">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.decision">
 | 
			
		||||
          <y:Geometry height="40.0" width="80.0" x="403.6849206349206" y="206.44247787610618"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="4.0" x="38.0" y="18.0">
 | 
			
		||||
            <y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n2">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="90.44247787610618" width="268.0" x="309.6849206349206" y="86.0"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="right" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="88.796875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="170.763671875" x="48.61816406250006" y="0.8228014380530908">Get installed packages
 | 
			
		||||
Alpine: apk
 | 
			
		||||
Debian/Ubuntu: dpkg-query
 | 
			
		||||
Amazon/RHEL/CentOS: rpm
 | 
			
		||||
SUSE: zypper
 | 
			
		||||
FreeBSD: pkg<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="2.220446049250313E-16" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n3">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="609.3698412698412" y="630.0546766682629"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="152.634765625" x="57.6826171875" y="18.93359375">Write results to JSON files<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="0.1619001116071429" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n4">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="609.3698412698412" y="287.8409153761062"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="46.3984375" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="232.744140625" x="17.6279296875" y="4.80078125">Get CVE IDs by using package manager
 | 
			
		||||
Amazon: yum plugin security
 | 
			
		||||
FreeBSD: pkg audit<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n5">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="609.3698412698412" y="750.4705298628534"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="42.595703125" x="112.7021484375" y="18.93359375">Report<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n6" yfiles.foldertype="group">
 | 
			
		||||
      <data key="d4"/>
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:ProxyAutoBoundsNode>
 | 
			
		||||
          <y:Realizers active="0">
 | 
			
		||||
            <y:GroupNode>
 | 
			
		||||
              <y:Geometry height="116.89483989807195" width="333.6788874841973" x="234.29467728596296" y="709.1901021013174"/>
 | 
			
		||||
              <y:Fill color="#F5F5F5" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="333.6788874841973" x="0.0" y="0.0">Vulnerability Database</y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
              <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
 | 
			
		||||
              <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
 | 
			
		||||
              <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
 | 
			
		||||
            </y:GroupNode>
 | 
			
		||||
            <y:GroupNode>
 | 
			
		||||
              <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
 | 
			
		||||
              <y:Fill color="#F5F5F5" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="63.75830078125" x="-6.879150390625" y="0.0">Folder 1</y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
              <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
 | 
			
		||||
              <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
 | 
			
		||||
              <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
 | 
			
		||||
            </y:GroupNode>
 | 
			
		||||
          </y:Realizers>
 | 
			
		||||
        </y:ProxyAutoBoundsNode>
 | 
			
		||||
      </data>
 | 
			
		||||
      <graph edgedefault="directed" id="n6:">
 | 
			
		||||
        <node id="n6::n0">
 | 
			
		||||
          <data key="d6">
 | 
			
		||||
            <y:GenericNode configuration="com.yworks.flowchart.dataBase">
 | 
			
		||||
              <y:Geometry height="65.22882427307195" width="136.83944374209864" x="416.1341210280616" y="745.8561177263174"/>
 | 
			
		||||
              <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="117.970703125" x="9.434370308549205" y="23.548005886535975">CVE DB (NVD / JVN)<y:LabelModel>
 | 
			
		||||
                  <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
                </y:LabelModel>
 | 
			
		||||
                <y:ModelParameter>
 | 
			
		||||
                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="-8.326672684688674E-16" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
                </y:ModelParameter>
 | 
			
		||||
              </y:NodeLabel>
 | 
			
		||||
            </y:GenericNode>
 | 
			
		||||
          </data>
 | 
			
		||||
        </node>
 | 
			
		||||
        <node id="n6::n1">
 | 
			
		||||
          <data key="d6">
 | 
			
		||||
            <y:GenericNode configuration="com.yworks.flowchart.dataBase">
 | 
			
		||||
              <y:Geometry height="65.22882427307195" width="136.83944374209864" x="249.29467728596296" y="745.8561177263174"/>
 | 
			
		||||
              <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="55.533203125" x="40.653120308549205" y="23.548005886535975">OVAL DB<y:LabelModel>
 | 
			
		||||
                  <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
                </y:LabelModel>
 | 
			
		||||
                <y:ModelParameter>
 | 
			
		||||
                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="-8.326672684688674E-16" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
                </y:ModelParameter>
 | 
			
		||||
              </y:NodeLabel>
 | 
			
		||||
            </y:GenericNode>
 | 
			
		||||
          </data>
 | 
			
		||||
        </node>
 | 
			
		||||
      </graph>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n7">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="27.144753476611868" y="287.8409153761062"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="260.83984375" x="3.580078125" y="11.8671875">Check upgradable packages
 | 
			
		||||
Debian/Ubuntu: apt-get upgrade --dry-run<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n8">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.loopLimit">
 | 
			
		||||
          <y:Geometry height="51.10998735777497" width="137.19216182048035" x="92.54867256637169" y="376.28592169721867"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="131.751953125" x="2.7201043477401754" y="9.422181178887513">foreach 
 | 
			
		||||
upgradable  packages<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="5.551115123125783E-16" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n9">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="27.144753476611868" y="459.8409153761062"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="213.619140625" x="27.1904296875" y="11.8671875">Parse changelog and get  CVE IDs
 | 
			
		||||
Debian/Ubuntu: aptitude changelog<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n10">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.loopLimitEnd">
 | 
			
		||||
          <y:Geometry height="50.0" width="137.0" x="92.64475347661187" y="545.8409153761062"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="55.24609375" x="40.876953125" y="15.93359375">end loop<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <edge id="e0" source="n2" target="n1">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="45.22123893805309" tx="0.0" ty="-20.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="none"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e1" source="n1" target="n4">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="40.0" sy="0.0" tx="0.0" ty="-28.0">
 | 
			
		||||
            <y:Point x="743.3698412698412" y="226.44247787610618"/>
 | 
			
		||||
          </y:Path>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:EdgeLabel alignment="right" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="51.806640625" x="183.35883739927397" y="2.000003510871693">Amazon
 | 
			
		||||
FreeBSD<y:LabelModel>
 | 
			
		||||
              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="1.9999999999998863" distanceToCenter="false" position="right" ratio="0.7796030035582084" segment="0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
 | 
			
		||||
          </y:EdgeLabel>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e2" source="n0" target="n2">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="28.0" tx="0.0" ty="-45.22123893805309"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e3" source="n5" target="n6">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="10.8330078125"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="none"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e4" source="n1" target="n3">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="-123.36984126984123" ty="0.0">
 | 
			
		||||
            <y:Point x="443.6849206349206" y="658.0546766682629"/>
 | 
			
		||||
          </y:Path>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:EdgeLabel alignment="right" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="102.9296875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="77.078125" x="-97.68364242524859" y="5.005267793098369">Alpine Linux
 | 
			
		||||
CentOS
 | 
			
		||||
RHEL
 | 
			
		||||
Ubuntu
 | 
			
		||||
Debian
 | 
			
		||||
Oracle Linux
 | 
			
		||||
Suse<y:LabelModel>
 | 
			
		||||
              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="59.14459455430983" distanceToCenter="true" position="right" ratio="0.0" segment="0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
 | 
			
		||||
          </y:EdgeLabel>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e5" source="n4" target="n3">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e6" source="n7" target="n8">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="28.0" tx="0.0" ty="-25.554993678887485"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e7" source="n8" target="n9">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="25.554993678887485" tx="0.0" ty="-28.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e8" source="n9" target="n10">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="28.0" tx="0.0" ty="-25.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e9" source="n3" target="n5">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e10" source="n1" target="n7">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
 | 
			
		||||
            <y:Point x="161.14475347661187" y="226.44247787610618"/>
 | 
			
		||||
          </y:Path>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="56.98046875" x="-196.80057112212188" y="20.933597260871807">Raspbian<y:LabelModel>
 | 
			
		||||
              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="left" ratio="0.6447921222409765" segment="0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
 | 
			
		||||
          </y:EdgeLabel>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e11" source="n10" target="n3">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="-125.78842258255952" ty="0.0">
 | 
			
		||||
            <y:Point x="161.14475347661187" y="658.0546766682629"/>
 | 
			
		||||
          </y:Path>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
  </graph>
 | 
			
		||||
  <data key="d7">
 | 
			
		||||
    <y:Resources/>
 | 
			
		||||
  </data>
 | 
			
		||||
</graphml>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 78 KiB  | 
@@ -1,515 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
 | 
			
		||||
  <!--Created by yEd 3.17-->
 | 
			
		||||
  <key attr.name="Description" attr.type="string" for="graph" id="d0"/>
 | 
			
		||||
  <key for="port" id="d1" yfiles.type="portgraphics"/>
 | 
			
		||||
  <key for="port" id="d2" yfiles.type="portgeometry"/>
 | 
			
		||||
  <key for="port" id="d3" yfiles.type="portuserdata"/>
 | 
			
		||||
  <key attr.name="url" attr.type="string" for="node" id="d4"/>
 | 
			
		||||
  <key attr.name="description" attr.type="string" for="node" id="d5"/>
 | 
			
		||||
  <key for="node" id="d6" yfiles.type="nodegraphics"/>
 | 
			
		||||
  <key for="graphml" id="d7" yfiles.type="resources"/>
 | 
			
		||||
  <key attr.name="url" attr.type="string" for="edge" id="d8"/>
 | 
			
		||||
  <key attr.name="description" attr.type="string" for="edge" id="d9"/>
 | 
			
		||||
  <key for="edge" id="d10" yfiles.type="edgegraphics"/>
 | 
			
		||||
  <graph edgedefault="directed" id="G">
 | 
			
		||||
    <data key="d0"/>
 | 
			
		||||
    <node id="n0">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="309.6849206349206" y="0.0"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="83.482421875" x="92.2587890625" y="18.93359375">Detect the OS<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="0.1619001116071429" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n1">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.decision">
 | 
			
		||||
          <y:Geometry height="40.0" width="80.0" x="403.6849206349206" y="206.44247787610618"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="4.0" x="38.0" y="18.0">
 | 
			
		||||
            <y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n2">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="90.44247787610618" width="268.0" x="309.6849206349206" y="86.0"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="right" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="88.796875" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="170.763671875" x="48.61816406250006" y="0.8228014380530908">Get installed packages
 | 
			
		||||
Alpine Linux: apk
 | 
			
		||||
Debian/Ubuntu: dpkg-query
 | 
			
		||||
Amazon/RHEL/CentOS: rpm
 | 
			
		||||
FreeBSD: pkg
 | 
			
		||||
SUSE: zypper<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="2.220446049250313E-16" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n3">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="10.0" y="287.8409153761062"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="260.83984375" x="3.580078125" y="11.8671875">Check upgradable packages
 | 
			
		||||
Debian/Ubuntu: apt-get upgrade --dry-run<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n4">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.loopLimit">
 | 
			
		||||
          <y:Geometry height="51.10998735777497" width="137.19216182048035" x="75.40391908975982" y="376.28592169721867"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="131.751953125" x="2.7201043477401754" y="9.422181178887513">foreach 
 | 
			
		||||
upgradable  packages<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="5.551115123125783E-16" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n5">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="10.0" y="459.8409153761062"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="213.619140625" x="27.1904296875" y="11.8671875">Parse changelog and get  CVE IDs
 | 
			
		||||
Debian/Ubuntu: aptitude changelog<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n6">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.loopLimitEnd">
 | 
			
		||||
          <y:Geometry height="50.0" width="137.0" x="75.5" y="545.8409153761062"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="55.24609375" x="40.876953125" y="15.93359375">end loop<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n7">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="609.3698412698412" y="625.8409153761062"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="152.634765625" x="57.6826171875" y="18.93359375">Write results to JSON files<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="0.0" nodeRatioY="0.1619001116071429" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n8">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="609.3698412698412" y="287.8409153761062"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="46.3984375" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="232.744140625" x="17.6279296875" y="4.80078125">Get CVE IDs by using package manager
 | 
			
		||||
Amazon/RHEL: yum plugin security
 | 
			
		||||
FreeBSD: pkg audit<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n9">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="609.3698412698412" y="716.4553275126422"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="42.595703125" x="112.7021484375" y="18.93359375">Report<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n10">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="309.6849206349206" y="371.39590905499364"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="293.06640625" x="-12.533203124999943" y="11.8671875">Get all changelogs of updatable packages at once
 | 
			
		||||
yum changelog<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="2.220446049250313E-16" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n11">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="309.68492063492056" y="459.8409153761062"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="205.52734375" x="31.236328125000057" y="18.93359375">Parse changelogs and get CVE IDs <y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.5" nodeRatioX="2.220446049250313E-16" nodeRatioY="0.1619001116071429" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n12">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:GenericNode configuration="com.yworks.flowchart.process">
 | 
			
		||||
          <y:Geometry height="56.0" width="268.0" x="609.3698412698412" y="373.8409153761062"/>
 | 
			
		||||
          <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="293.06640625" x="-12.533203124999886" y="11.8671875">Get all changelogs of updatable packages at once
 | 
			
		||||
Amazon / RHEL: yum changelog<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="2.220446049250313E-16" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
        </y:GenericNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n13" yfiles.foldertype="group">
 | 
			
		||||
      <data key="d4"/>
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:ProxyAutoBoundsNode>
 | 
			
		||||
          <y:Realizers active="0">
 | 
			
		||||
            <y:GroupNode>
 | 
			
		||||
              <y:Geometry height="116.89483989807195" width="333.6788874841973" x="229.74083438685204" y="675.1748997511062"/>
 | 
			
		||||
              <y:Fill color="#F5F5F5" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="333.6788874841973" x="0.0" y="0.0">Vulnerability Database</y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
              <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
 | 
			
		||||
              <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
 | 
			
		||||
              <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
 | 
			
		||||
            </y:GroupNode>
 | 
			
		||||
            <y:GroupNode>
 | 
			
		||||
              <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
 | 
			
		||||
              <y:Fill color="#F5F5F5" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="63.75830078125" x="-6.879150390625" y="0.0">Folder 1</y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
              <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
 | 
			
		||||
              <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
 | 
			
		||||
              <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
 | 
			
		||||
            </y:GroupNode>
 | 
			
		||||
          </y:Realizers>
 | 
			
		||||
        </y:ProxyAutoBoundsNode>
 | 
			
		||||
      </data>
 | 
			
		||||
      <graph edgedefault="directed" id="n13:">
 | 
			
		||||
        <node id="n13::n0">
 | 
			
		||||
          <data key="d6">
 | 
			
		||||
            <y:GenericNode configuration="com.yworks.flowchart.dataBase">
 | 
			
		||||
              <y:Geometry height="65.22882427307195" width="136.83944374209864" x="411.5802781289507" y="711.8409153761062"/>
 | 
			
		||||
              <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="117.970703125" x="9.434370308549205" y="23.548005886535975">CVE DB (NVD / JVN)<y:LabelModel>
 | 
			
		||||
                  <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
                </y:LabelModel>
 | 
			
		||||
                <y:ModelParameter>
 | 
			
		||||
                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="-8.326672684688674E-16" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
                </y:ModelParameter>
 | 
			
		||||
              </y:NodeLabel>
 | 
			
		||||
            </y:GenericNode>
 | 
			
		||||
          </data>
 | 
			
		||||
        </node>
 | 
			
		||||
        <node id="n13::n1">
 | 
			
		||||
          <data key="d6">
 | 
			
		||||
            <y:GenericNode configuration="com.yworks.flowchart.dataBase">
 | 
			
		||||
              <y:Geometry height="65.22882427307195" width="136.83944374209864" x="244.74083438685204" y="711.8409153761062"/>
 | 
			
		||||
              <y:Fill color="#E8EEF7" color2="#B7C9E3" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="55.533203125" x="40.653120308549205" y="23.548005886535975">OVAL DB<y:LabelModel>
 | 
			
		||||
                  <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
                </y:LabelModel>
 | 
			
		||||
                <y:ModelParameter>
 | 
			
		||||
                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="-8.326672684688674E-16" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
                </y:ModelParameter>
 | 
			
		||||
              </y:NodeLabel>
 | 
			
		||||
            </y:GenericNode>
 | 
			
		||||
          </data>
 | 
			
		||||
        </node>
 | 
			
		||||
      </graph>
 | 
			
		||||
    </node>
 | 
			
		||||
    <edge id="e0" source="n2" target="n1">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="45.22123893805309" tx="0.0" ty="-20.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="none"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e1" source="n1" target="n3">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="-40.0" sy="0.0" tx="0.0" ty="-28.0">
 | 
			
		||||
            <y:Point x="144.0" y="226.44247787610618"/>
 | 
			
		||||
          </y:Path>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:EdgeLabel alignment="right" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="46.3984375" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="56.98046875" x="-257.65322875976574" y="2.0000035108718635">Debian
 | 
			
		||||
Ubuntu
 | 
			
		||||
Raspbian<y:LabelModel>
 | 
			
		||||
              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="1.9999999999998863" distanceToCenter="false" position="left" ratio="0.8652035780364729" segment="0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
 | 
			
		||||
          </y:EdgeLabel>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e2" source="n3" target="n4">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="28.0" tx="0.0" ty="-25.554993678887485"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e3" source="n4" target="n5">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="25.554993678887485" tx="0.0" ty="-28.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e4" source="n5" target="n6">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="28.0" tx="0.0" ty="-25.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e5" source="n6" target="n7">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="68.5" sy="0.0" tx="0.0" ty="-28.0">
 | 
			
		||||
            <y:Point x="743.3698412698412" y="570.8409153761062"/>
 | 
			
		||||
          </y:Path>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e6" source="n1" target="n8">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="40.0" sy="0.0" tx="0.0" ty="-28.0">
 | 
			
		||||
            <y:Point x="743.3698412698412" y="226.44247787610618"/>
 | 
			
		||||
          </y:Path>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:EdgeLabel alignment="right" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="46.3984375" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="51.806640625" x="200.87829463898197" y="4.000003510871693">Amazon
 | 
			
		||||
RHEL
 | 
			
		||||
FreeBSD<y:LabelModel>
 | 
			
		||||
              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartEdgeLabelModelParameter angle="6.283185307179586" distance="6.999999999999886" distanceToCenter="false" position="right" ratio="0.8192728556300707" segment="-1"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
 | 
			
		||||
          </y:EdgeLabel>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e7" source="n0" target="n2">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="28.0" tx="0.0" ty="-45.22123893805309"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e8" source="n7" target="n9">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="28.0" tx="0.0" ty="-28.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e9" source="n1" target="n10">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="20.0" tx="0.0" ty="-28.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="46.708984375" x="-53.35447755843876" y="5.000003510871807">CentOS<y:LabelModel>
 | 
			
		||||
              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="right" ratio="0.0" segment="0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
 | 
			
		||||
          </y:EdgeLabel>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e10" source="n10" target="n11">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="28.0" tx="0.0" ty="-28.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e11" source="n11" target="n7">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="-24.34091537610618">
 | 
			
		||||
            <y:Point x="743.3698412698412" y="487.8409153761062"/>
 | 
			
		||||
          </y:Path>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e12" source="n8" target="n12">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e13" source="n12" target="n7">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e14" source="n9" target="n13">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="10.8330078125"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="none"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e15" source="n1" target="n7">
 | 
			
		||||
      <data key="d9"/>
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
 | 
			
		||||
            <y:Point x="999.0" y="226.44247787610618"/>
 | 
			
		||||
            <y:Point x="999.0" y="570.8409153761062"/>
 | 
			
		||||
            <y:Point x="743.3698412698412" y="570.8409153761062"/>
 | 
			
		||||
          </y:Path>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="none"/>
 | 
			
		||||
          <y:EdgeLabel alignment="right" configuration="AutoFlippingLabel" distance="2.0" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="32.265625" horizontalTextPosition="center" iconTextGap="4" modelName="custom" preferredPlacement="anywhere" ratio="0.5" textColor="#000000" verticalTextPosition="bottom" visible="true" width="76.8203125" x="422.923942251054" y="13.867191010871807">Alpine Linux
 | 
			
		||||
SUSE<y:LabelModel>
 | 
			
		||||
              <y:SmartEdgeLabelModel autoRotationEnabled="false" defaultAngle="0.0" defaultDistance="10.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartEdgeLabelModelParameter angle="0.0" distance="30.0" distanceToCenter="true" position="right" ratio="0.8856709076027529" segment="0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
            <y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
 | 
			
		||||
          </y:EdgeLabel>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
  </graph>
 | 
			
		||||
  <data key="d7">
 | 
			
		||||
    <y:Resources/>
 | 
			
		||||
  </data>
 | 
			
		||||
</graphml>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 90 KiB  | 
| 
		 Before Width: | Height: | Size: 179 KiB  | 
@@ -1,265 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
 | 
			
		||||
  <!--Created by yEd 3.14.2-->
 | 
			
		||||
  <key attr.name="Description" attr.type="string" for="graph" id="d0"/>
 | 
			
		||||
  <key for="port" id="d1" yfiles.type="portgraphics"/>
 | 
			
		||||
  <key for="port" id="d2" yfiles.type="portgeometry"/>
 | 
			
		||||
  <key for="port" id="d3" yfiles.type="portuserdata"/>
 | 
			
		||||
  <key attr.name="url" attr.type="string" for="node" id="d4"/>
 | 
			
		||||
  <key attr.name="description" attr.type="string" for="node" id="d5"/>
 | 
			
		||||
  <key for="node" id="d6" yfiles.type="nodegraphics"/>
 | 
			
		||||
  <key for="graphml" id="d7" yfiles.type="resources"/>
 | 
			
		||||
  <key attr.name="url" attr.type="string" for="edge" id="d8"/>
 | 
			
		||||
  <key attr.name="description" attr.type="string" for="edge" id="d9"/>
 | 
			
		||||
  <key for="edge" id="d10" yfiles.type="edgegraphics"/>
 | 
			
		||||
  <graph edgedefault="directed" id="G">
 | 
			
		||||
    <data key="d0"/>
 | 
			
		||||
    <node id="n0">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:ShapeNode>
 | 
			
		||||
          <y:Geometry height="50.0" width="73.25" x="478.6165008544913" y="1358.206868489578"/>
 | 
			
		||||
          <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="28.87890625" x="22.185546875" y="15.93359375">Vuls<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
          <y:Shape type="roundrectangle"/>
 | 
			
		||||
        </y:ShapeNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n1">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:ShapeNode>
 | 
			
		||||
          <y:Geometry height="50.0" width="73.25" x="711.9623756408686" y="1043.7241210937468"/>
 | 
			
		||||
          <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="38.623046875" x="17.3134765625" y="15.93359375">Nginx<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
          <y:Shape type="roundrectangle"/>
 | 
			
		||||
        </y:ShapeNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n2">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:ShapeNode>
 | 
			
		||||
          <y:Geometry height="50.0" width="73.25" x="711.9623756408686" y="1287.206868489578"/>
 | 
			
		||||
          <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="42.7890625" x="15.23046875" y="15.93359375">MySQL<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
          <y:Shape type="roundrectangle"/>
 | 
			
		||||
        </y:ShapeNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n3" yfiles.foldertype="group">
 | 
			
		||||
      <data key="d4"/>
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:ProxyAutoBoundsNode>
 | 
			
		||||
          <y:Realizers active="0">
 | 
			
		||||
            <y:GroupNode>
 | 
			
		||||
              <y:Geometry height="101.666015625" width="291.7208747863772" x="602.72693824768" y="1146.2994791666624"/>
 | 
			
		||||
              <y:Fill color="#F5F5F5" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="291.7208747863772" x="0.0" y="0.0">Web/App</y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
              <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
 | 
			
		||||
              <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
 | 
			
		||||
              <y:BorderInsets bottom="0" bottomF="0.0" left="23" leftF="23.0" right="0" rightF="0.0" top="0" topF="0.0"/>
 | 
			
		||||
            </y:GroupNode>
 | 
			
		||||
            <y:GroupNode>
 | 
			
		||||
              <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
 | 
			
		||||
              <y:Fill color="#F5F5F5" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="63.75830078125" x="-6.879150390625" y="0.0">Folder 5</y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
              <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
 | 
			
		||||
              <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
 | 
			
		||||
              <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
 | 
			
		||||
            </y:GroupNode>
 | 
			
		||||
          </y:Realizers>
 | 
			
		||||
        </y:ProxyAutoBoundsNode>
 | 
			
		||||
      </data>
 | 
			
		||||
      <graph edgedefault="directed" id="n3:">
 | 
			
		||||
        <node id="n3::n0">
 | 
			
		||||
          <data key="d6">
 | 
			
		||||
            <y:ShapeNode>
 | 
			
		||||
              <y:Geometry height="50.0" width="73.25" x="640.72693824768" y="1182.9654947916624"/>
 | 
			
		||||
              <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="31.26953125" x="20.990234375" y="15.93359375">Rails<y:LabelModel>
 | 
			
		||||
                  <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
                </y:LabelModel>
 | 
			
		||||
                <y:ModelParameter>
 | 
			
		||||
                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
                </y:ModelParameter>
 | 
			
		||||
              </y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
            </y:ShapeNode>
 | 
			
		||||
          </data>
 | 
			
		||||
        </node>
 | 
			
		||||
        <node id="n3::n1">
 | 
			
		||||
          <data key="d6">
 | 
			
		||||
            <y:ShapeNode>
 | 
			
		||||
              <y:Geometry height="50.0" width="73.25" x="723.4623756408686" y="1182.9654947916624"/>
 | 
			
		||||
              <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="31.26953125" x="20.990234375" y="15.93359375">Rails<y:LabelModel>
 | 
			
		||||
                  <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
                </y:LabelModel>
 | 
			
		||||
                <y:ModelParameter>
 | 
			
		||||
                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
                </y:ModelParameter>
 | 
			
		||||
              </y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
            </y:ShapeNode>
 | 
			
		||||
          </data>
 | 
			
		||||
        </node>
 | 
			
		||||
        <node id="n3::n2">
 | 
			
		||||
          <data key="d6">
 | 
			
		||||
            <y:ShapeNode>
 | 
			
		||||
              <y:Geometry height="50.0" width="73.25" x="806.1978130340572" y="1182.9654947916624"/>
 | 
			
		||||
              <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="31.26953125" x="20.990234375" y="15.93359375">Rails<y:LabelModel>
 | 
			
		||||
                  <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
                </y:LabelModel>
 | 
			
		||||
                <y:ModelParameter>
 | 
			
		||||
                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
                </y:ModelParameter>
 | 
			
		||||
              </y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
            </y:ShapeNode>
 | 
			
		||||
          </data>
 | 
			
		||||
        </node>
 | 
			
		||||
      </graph>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n4">
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:ShapeNode>
 | 
			
		||||
          <y:Geometry height="50.0" width="73.25" x="821.1978130340572" y="1287.206868489578"/>
 | 
			
		||||
          <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="35.412109375" x="18.9189453125" y="15.93359375">Redis<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
          <y:Shape type="roundrectangle"/>
 | 
			
		||||
        </y:ShapeNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <edge id="e0" source="n3" target="n1">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="none"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e1" source="n3" target="n2">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="none"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e2" source="n0" target="n3::n0">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e3" source="n0" target="n3::n1">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e4" source="n0" target="n3::n2">
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e5" source="n3" target="n4">
 | 
			
		||||
      <data key="d9"/>
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="none"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e6" source="n0" target="n4">
 | 
			
		||||
      <data key="d9"/>
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e7" source="n0" target="n1">
 | 
			
		||||
      <data key="d9"/>
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e8" source="n0" target="n2">
 | 
			
		||||
      <data key="d9"/>
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
  </graph>
 | 
			
		||||
  <data key="d7">
 | 
			
		||||
    <y:Resources/>
 | 
			
		||||
  </data>
 | 
			
		||||
</graphml>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 14 KiB  | 
@@ -1,194 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
 | 
			
		||||
  <!--Created by yEd 3.14.2-->
 | 
			
		||||
  <key attr.name="Description" attr.type="string" for="graph" id="d0"/>
 | 
			
		||||
  <key for="port" id="d1" yfiles.type="portgraphics"/>
 | 
			
		||||
  <key for="port" id="d2" yfiles.type="portgeometry"/>
 | 
			
		||||
  <key for="port" id="d3" yfiles.type="portuserdata"/>
 | 
			
		||||
  <key attr.name="url" attr.type="string" for="node" id="d4"/>
 | 
			
		||||
  <key attr.name="description" attr.type="string" for="node" id="d5"/>
 | 
			
		||||
  <key for="node" id="d6" yfiles.type="nodegraphics"/>
 | 
			
		||||
  <key for="graphml" id="d7" yfiles.type="resources"/>
 | 
			
		||||
  <key attr.name="url" attr.type="string" for="edge" id="d8"/>
 | 
			
		||||
  <key attr.name="description" attr.type="string" for="edge" id="d9"/>
 | 
			
		||||
  <key for="edge" id="d10" yfiles.type="edgegraphics"/>
 | 
			
		||||
  <graph edgedefault="directed" id="G">
 | 
			
		||||
    <data key="d0"/>
 | 
			
		||||
    <node id="n0">
 | 
			
		||||
      <data key="d5"/>
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:ShapeNode>
 | 
			
		||||
          <y:Geometry height="50.0" width="73.25" x="508.30825042724564" y="1132.4827473958312"/>
 | 
			
		||||
          <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="28.87890625" x="22.185546875" y="15.93359375">Vuls<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
          <y:Shape type="roundrectangle"/>
 | 
			
		||||
        </y:ShapeNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n1">
 | 
			
		||||
      <data key="d5"/>
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:ShapeNode>
 | 
			
		||||
          <y:Geometry height="50.0" width="73.25" x="749.6541252136229" y="993.2413736979156"/>
 | 
			
		||||
          <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="23.8046875" x="24.72265625" y="15.93359375">ELB<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
          <y:Shape type="roundrectangle"/>
 | 
			
		||||
        </y:ShapeNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n2">
 | 
			
		||||
      <data key="d5"/>
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:ShapeNode>
 | 
			
		||||
          <y:Geometry height="50.0" width="73.25" x="749.6541252136229" y="1236.7241210937468"/>
 | 
			
		||||
          <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="27.0390625" x="23.10546875" y="15.93359375">RDS<y:LabelModel>
 | 
			
		||||
              <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
            </y:LabelModel>
 | 
			
		||||
            <y:ModelParameter>
 | 
			
		||||
              <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
            </y:ModelParameter>
 | 
			
		||||
          </y:NodeLabel>
 | 
			
		||||
          <y:Shape type="roundrectangle"/>
 | 
			
		||||
        </y:ShapeNode>
 | 
			
		||||
      </data>
 | 
			
		||||
    </node>
 | 
			
		||||
    <node id="n3" yfiles.foldertype="group">
 | 
			
		||||
      <data key="d4"/>
 | 
			
		||||
      <data key="d5"/>
 | 
			
		||||
      <data key="d6">
 | 
			
		||||
        <y:ProxyAutoBoundsNode>
 | 
			
		||||
          <y:Realizers active="0">
 | 
			
		||||
            <y:GroupNode>
 | 
			
		||||
              <y:Geometry height="101.666015625" width="291.7208747863772" x="640.4186878204343" y="1095.8167317708312"/>
 | 
			
		||||
              <y:Fill color="#F5F5F5" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="291.7208747863772" x="0.0" y="0.0">Web/App</y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
              <y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
 | 
			
		||||
              <y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
 | 
			
		||||
              <y:BorderInsets bottom="0" bottomF="0.0" left="23" leftF="23.0" right="0" rightF="0.0" top="0" topF="0.0"/>
 | 
			
		||||
            </y:GroupNode>
 | 
			
		||||
            <y:GroupNode>
 | 
			
		||||
              <y:Geometry height="50.0" width="50.0" x="0.0" y="60.0"/>
 | 
			
		||||
              <y:Fill color="#F5F5F5" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="dashed" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.666015625" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="63.75830078125" x="-6.879150390625" y="0.0">Folder 5</y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
              <y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
 | 
			
		||||
              <y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
 | 
			
		||||
              <y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
 | 
			
		||||
            </y:GroupNode>
 | 
			
		||||
          </y:Realizers>
 | 
			
		||||
        </y:ProxyAutoBoundsNode>
 | 
			
		||||
      </data>
 | 
			
		||||
      <graph edgedefault="directed" id="n3:">
 | 
			
		||||
        <node id="n3::n0">
 | 
			
		||||
          <data key="d5"/>
 | 
			
		||||
          <data key="d6">
 | 
			
		||||
            <y:ShapeNode>
 | 
			
		||||
              <y:Geometry height="50.0" width="73.25" x="678.4186878204343" y="1132.4827473958312"/>
 | 
			
		||||
              <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="31.26953125" x="20.990234375" y="15.93359375">Rails<y:LabelModel>
 | 
			
		||||
                  <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
                </y:LabelModel>
 | 
			
		||||
                <y:ModelParameter>
 | 
			
		||||
                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
                </y:ModelParameter>
 | 
			
		||||
              </y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
            </y:ShapeNode>
 | 
			
		||||
          </data>
 | 
			
		||||
        </node>
 | 
			
		||||
        <node id="n3::n1">
 | 
			
		||||
          <data key="d5"/>
 | 
			
		||||
          <data key="d6">
 | 
			
		||||
            <y:ShapeNode>
 | 
			
		||||
              <y:Geometry height="50.0" width="73.25" x="761.1541252136229" y="1132.4827473958312"/>
 | 
			
		||||
              <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="31.26953125" x="20.990234375" y="15.93359375">Rails<y:LabelModel>
 | 
			
		||||
                  <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
                </y:LabelModel>
 | 
			
		||||
                <y:ModelParameter>
 | 
			
		||||
                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
                </y:ModelParameter>
 | 
			
		||||
              </y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
            </y:ShapeNode>
 | 
			
		||||
          </data>
 | 
			
		||||
        </node>
 | 
			
		||||
        <node id="n3::n2">
 | 
			
		||||
          <data key="d5"/>
 | 
			
		||||
          <data key="d6">
 | 
			
		||||
            <y:ShapeNode>
 | 
			
		||||
              <y:Geometry height="50.0" width="73.25" x="843.8895626068115" y="1132.4827473958312"/>
 | 
			
		||||
              <y:Fill color="#C0C0C0" transparent="false"/>
 | 
			
		||||
              <y:BorderStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
              <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="18.1328125" modelName="custom" textColor="#000000" visible="true" width="31.26953125" x="20.990234375" y="15.93359375">Rails<y:LabelModel>
 | 
			
		||||
                  <y:SmartNodeLabelModel distance="4.0"/>
 | 
			
		||||
                </y:LabelModel>
 | 
			
		||||
                <y:ModelParameter>
 | 
			
		||||
                  <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
 | 
			
		||||
                </y:ModelParameter>
 | 
			
		||||
              </y:NodeLabel>
 | 
			
		||||
              <y:Shape type="roundrectangle"/>
 | 
			
		||||
            </y:ShapeNode>
 | 
			
		||||
          </data>
 | 
			
		||||
        </node>
 | 
			
		||||
      </graph>
 | 
			
		||||
    </node>
 | 
			
		||||
    <edge id="e0" source="n3" target="n1">
 | 
			
		||||
      <data key="d9"/>
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="none"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e1" source="n3" target="n2">
 | 
			
		||||
      <data key="d9"/>
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="none"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
    <edge id="e2" source="n0" target="n3::n0">
 | 
			
		||||
      <data key="d9"/>
 | 
			
		||||
      <data key="d10">
 | 
			
		||||
        <y:PolyLineEdge>
 | 
			
		||||
          <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
 | 
			
		||||
          <y:LineStyle color="#000000" type="line" width="1.0"/>
 | 
			
		||||
          <y:Arrows source="none" target="standard"/>
 | 
			
		||||
          <y:BendStyle smoothed="false"/>
 | 
			
		||||
        </y:PolyLineEdge>
 | 
			
		||||
      </data>
 | 
			
		||||
    </edge>
 | 
			
		||||
  </graph>
 | 
			
		||||
  <data key="d7">
 | 
			
		||||
    <y:Resources/>
 | 
			
		||||
  </data>
 | 
			
		||||
</graphml>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 5.6 KiB  | 
							
								
								
									
										108
									
								
								libmanager/libManager.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,108 @@
 | 
			
		||||
package libmanager
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
 | 
			
		||||
	db2 "github.com/aquasecurity/trivy-db/pkg/db"
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/db"
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/github"
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/indicator"
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/log"
 | 
			
		||||
	"github.com/spf13/afero"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
	"k8s.io/utils/clock"
 | 
			
		||||
 | 
			
		||||
	"github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"github.com/future-architect/vuls/util"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// FillLibrary fills LibraryScanner information
 | 
			
		||||
func FillLibrary(r *models.ScanResult) (totalCnt int, err error) {
 | 
			
		||||
	if len(r.LibraryScanners) == 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// initialize trivy's logger and db
 | 
			
		||||
	err = log.InitLogger(false, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	util.Log.Info("Updating library db...")
 | 
			
		||||
	if err := downloadDB(config.Version, config.Conf.TrivyCacheDBDir, config.Conf.NoProgress, false, false); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := db2.Init(config.Conf.TrivyCacheDBDir); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	defer db2.Close()
 | 
			
		||||
 | 
			
		||||
	for _, lib := range r.LibraryScanners {
 | 
			
		||||
		vinfos, err := lib.Scan()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return 0, err
 | 
			
		||||
		}
 | 
			
		||||
		for _, vinfo := range vinfos {
 | 
			
		||||
			vinfo.Confidences.AppendIfMissing(models.TrivyMatch)
 | 
			
		||||
			if v, ok := r.ScannedCves[vinfo.CveID]; !ok {
 | 
			
		||||
				r.ScannedCves[vinfo.CveID] = vinfo
 | 
			
		||||
			} else {
 | 
			
		||||
				v.LibraryFixedIns = append(v.LibraryFixedIns, vinfo.LibraryFixedIns...)
 | 
			
		||||
				r.ScannedCves[vinfo.CveID] = v
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		totalCnt += len(vinfos)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return totalCnt, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func downloadDB(appVersion, cacheDir string, quiet, light, skipUpdate bool) error {
 | 
			
		||||
	client := initializeDBClient(cacheDir, quiet)
 | 
			
		||||
	ctx := context.Background()
 | 
			
		||||
	needsUpdate, err := client.NeedsUpdate(appVersion, light, skipUpdate)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return xerrors.Errorf("database error: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if needsUpdate {
 | 
			
		||||
		util.Log.Info("Need to update DB")
 | 
			
		||||
		util.Log.Info("Downloading DB...")
 | 
			
		||||
		if err := client.Download(ctx, cacheDir, light); err != nil {
 | 
			
		||||
			return xerrors.Errorf("failed to download vulnerability DB: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
		if err = client.UpdateMetadata(cacheDir); err != nil {
 | 
			
		||||
			return xerrors.Errorf("unable to update database metadata: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// for debug
 | 
			
		||||
	if err := showDBInfo(cacheDir); err != nil {
 | 
			
		||||
		return xerrors.Errorf("failed to show database info: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func initializeDBClient(cacheDir string, quiet bool) db.Client {
 | 
			
		||||
	config := db2.Config{}
 | 
			
		||||
	client := github.NewClient()
 | 
			
		||||
	progressBar := indicator.NewProgressBar(quiet)
 | 
			
		||||
	realClock := clock.RealClock{}
 | 
			
		||||
	fs := afero.NewOsFs()
 | 
			
		||||
	metadata := db.NewMetadata(fs, cacheDir)
 | 
			
		||||
	dbClient := db.NewClient(config, client, progressBar, realClock, metadata)
 | 
			
		||||
	return dbClient
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func showDBInfo(cacheDir string) error {
 | 
			
		||||
	m := db.NewMetadata(afero.NewOsFs(), cacheDir)
 | 
			
		||||
	metadata, err := m.Get()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return xerrors.Errorf("something wrong with DB: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	util.Log.Debugf("DB Schema: %d, Type: %d, UpdatedAt: %s, NextUpdate: %s",
 | 
			
		||||
		metadata.Version, metadata.Type, metadata.UpdatedAt, metadata.NextUpdate)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								main.go
									
									
									
									
									
								
							
							
						
						@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 
 | 
			
		||||
@@ -1,24 +1,9 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CveContents has CveContent
 | 
			
		||||
@@ -68,6 +53,9 @@ func (v CveContents) SourceLinks(lang, myFamily, cveID string) (values []CveCont
 | 
			
		||||
	order := CveContentTypes{Nvd, NvdXML, NewCveContentType(myFamily)}
 | 
			
		||||
	for _, ctype := range order {
 | 
			
		||||
		if cont, found := v[ctype]; found {
 | 
			
		||||
			if cont.SourceLink == "" {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			values = append(values, CveContentStr{ctype, cont.SourceLink})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -108,7 +96,7 @@ type CveContentCpes struct {
 | 
			
		||||
// Cpes returns affected CPEs of this Vulnerability
 | 
			
		||||
func (v CveContents) Cpes(myFamily string) (values []CveContentCpes) {
 | 
			
		||||
	order := CveContentTypes{NewCveContentType(myFamily)}
 | 
			
		||||
	order = append(order, AllCveContetTypes.Except(append(order)...)...)
 | 
			
		||||
	order = append(order, AllCveContetTypes.Except(order...)...)
 | 
			
		||||
 | 
			
		||||
	for _, ctype := range order {
 | 
			
		||||
		if cont, found := v[ctype]; found && 0 < len(cont.Cpes) {
 | 
			
		||||
@@ -130,7 +118,7 @@ type CveContentRefs struct {
 | 
			
		||||
// References returns References
 | 
			
		||||
func (v CveContents) References(myFamily string) (values []CveContentRefs) {
 | 
			
		||||
	order := CveContentTypes{NewCveContentType(myFamily)}
 | 
			
		||||
	order = append(order, AllCveContetTypes.Except(append(order)...)...)
 | 
			
		||||
	order = append(order, AllCveContetTypes.Except(order...)...)
 | 
			
		||||
 | 
			
		||||
	for _, ctype := range order {
 | 
			
		||||
		if cont, found := v[ctype]; found && 0 < len(cont.References) {
 | 
			
		||||
@@ -140,13 +128,14 @@ func (v CveContents) References(myFamily string) (values []CveContentRefs) {
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CweIDs returns related CweIDs of the vulnerability
 | 
			
		||||
func (v CveContents) CweIDs(myFamily string) (values []CveContentStr) {
 | 
			
		||||
	order := CveContentTypes{NewCveContentType(myFamily)}
 | 
			
		||||
	order = append(order, AllCveContetTypes.Except(append(order)...)...)
 | 
			
		||||
	order = append(order, AllCveContetTypes.Except(order...)...)
 | 
			
		||||
	for _, ctype := range order {
 | 
			
		||||
		if cont, found := v[ctype]; found && 0 < len(cont.CweIDs) {
 | 
			
		||||
			for _, cweID := range cont.CweIDs {
 | 
			
		||||
@@ -222,7 +211,7 @@ func NewCveContentType(name string) CveContentType {
 | 
			
		||||
		return Oracle
 | 
			
		||||
	case "ubuntu":
 | 
			
		||||
		return Ubuntu
 | 
			
		||||
	case "debian":
 | 
			
		||||
	case "debian", vulnerability.DebianOVAL:
 | 
			
		||||
		return Debian
 | 
			
		||||
	case "redhat_api":
 | 
			
		||||
		return RedHatAPI
 | 
			
		||||
@@ -230,6 +219,22 @@ func NewCveContentType(name string) CveContentType {
 | 
			
		||||
		return DebianSecurityTracker
 | 
			
		||||
	case "microsoft":
 | 
			
		||||
		return Microsoft
 | 
			
		||||
	case "wordpress":
 | 
			
		||||
		return WPVulnDB
 | 
			
		||||
	case "amazon":
 | 
			
		||||
		return Amazon
 | 
			
		||||
	case "trivy":
 | 
			
		||||
		return Trivy
 | 
			
		||||
	// case vulnerability.NodejsSecurityWg:
 | 
			
		||||
	// 	return NodeSec
 | 
			
		||||
	// case vulnerability.PythonSafetyDB:
 | 
			
		||||
	// 	return PythonSec
 | 
			
		||||
	// case vulnerability.RustSec:
 | 
			
		||||
	// 	return RustSec
 | 
			
		||||
	// case vulnerability.PhpSecurityAdvisories:
 | 
			
		||||
	// 	return PhpSec
 | 
			
		||||
	// case vulnerability.RubySec:
 | 
			
		||||
	// 	return RubySec
 | 
			
		||||
	default:
 | 
			
		||||
		return Unknown
 | 
			
		||||
	}
 | 
			
		||||
@@ -251,7 +256,7 @@ const (
 | 
			
		||||
	// RedHatAPI is RedHat
 | 
			
		||||
	RedHatAPI CveContentType = "redhat_api"
 | 
			
		||||
 | 
			
		||||
	// DebianSecurityTracker is Debian Secury tracker
 | 
			
		||||
	// DebianSecurityTracker is Debian Security tracker
 | 
			
		||||
	DebianSecurityTracker CveContentType = "debian_security_tracker"
 | 
			
		||||
 | 
			
		||||
	// Debian is Debian
 | 
			
		||||
@@ -263,12 +268,36 @@ const (
 | 
			
		||||
	// Oracle is Oracle Linux
 | 
			
		||||
	Oracle CveContentType = "oracle"
 | 
			
		||||
 | 
			
		||||
	// Amazon is Amazon Linux
 | 
			
		||||
	Amazon CveContentType = "amazon"
 | 
			
		||||
 | 
			
		||||
	// SUSE is SUSE Linux
 | 
			
		||||
	SUSE CveContentType = "suse"
 | 
			
		||||
 | 
			
		||||
	// Microsoft is Microsoft
 | 
			
		||||
	Microsoft CveContentType = "microsoft"
 | 
			
		||||
 | 
			
		||||
	// WPVulnDB is WordPress
 | 
			
		||||
	WPVulnDB CveContentType = "wpvulndb"
 | 
			
		||||
 | 
			
		||||
	// Trivy is Trivy
 | 
			
		||||
	Trivy CveContentType = "trivy"
 | 
			
		||||
 | 
			
		||||
	// NodeSec : for JS
 | 
			
		||||
	// NodeSec CveContentType = "node"
 | 
			
		||||
 | 
			
		||||
	// // PythonSec : for PHP
 | 
			
		||||
	// PythonSec CveContentType = "python"
 | 
			
		||||
 | 
			
		||||
	// // PhpSec : for PHP
 | 
			
		||||
	// PhpSec CveContentType = "php"
 | 
			
		||||
 | 
			
		||||
	// // RubySec : for Ruby
 | 
			
		||||
	// RubySec CveContentType = "ruby"
 | 
			
		||||
 | 
			
		||||
	// // RustSec : for Rust
 | 
			
		||||
	// RustSec CveContentType = "rust"
 | 
			
		||||
 | 
			
		||||
	// Unknown is Unknown
 | 
			
		||||
	Unknown CveContentType = "unknown"
 | 
			
		||||
)
 | 
			
		||||
@@ -282,10 +311,19 @@ var AllCveContetTypes = CveContentTypes{
 | 
			
		||||
	NvdXML,
 | 
			
		||||
	Jvn,
 | 
			
		||||
	RedHat,
 | 
			
		||||
	RedHatAPI,
 | 
			
		||||
	Debian,
 | 
			
		||||
	Ubuntu,
 | 
			
		||||
	RedHatAPI,
 | 
			
		||||
	Amazon,
 | 
			
		||||
	SUSE,
 | 
			
		||||
	DebianSecurityTracker,
 | 
			
		||||
	WPVulnDB,
 | 
			
		||||
	Trivy,
 | 
			
		||||
	// NodeSec,
 | 
			
		||||
	// PythonSec,
 | 
			
		||||
	// PhpSec,
 | 
			
		||||
	// RubySec,
 | 
			
		||||
	// RustSec,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Except returns CveContentTypes except for given args
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										145
									
								
								models/library.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,145 @@
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
 | 
			
		||||
	"github.com/aquasecurity/trivy-db/pkg/db"
 | 
			
		||||
	trivyDBTypes "github.com/aquasecurity/trivy-db/pkg/types"
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/detector/library"
 | 
			
		||||
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/types"
 | 
			
		||||
	"github.com/future-architect/vuls/util"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
 | 
			
		||||
	// "github.com/aquasecurity/go-dep-parser/pkg/types"
 | 
			
		||||
	"github.com/knqyf263/go-version"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// LibraryScanners is an array of LibraryScanner
 | 
			
		||||
type LibraryScanners []LibraryScanner
 | 
			
		||||
 | 
			
		||||
// Find : find by name
 | 
			
		||||
func (lss LibraryScanners) Find(path, name string) map[string]types.Library {
 | 
			
		||||
	filtered := map[string]types.Library{}
 | 
			
		||||
	for _, ls := range lss {
 | 
			
		||||
		for _, lib := range ls.Libs {
 | 
			
		||||
			if ls.Path == path && lib.Name == name {
 | 
			
		||||
				filtered[ls.Path] = lib
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return filtered
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LibraryScanner has libraries information
 | 
			
		||||
type LibraryScanner struct {
 | 
			
		||||
	Path string
 | 
			
		||||
	Libs []types.Library
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Scan : scan target library
 | 
			
		||||
func (s LibraryScanner) Scan() ([]VulnInfo, error) {
 | 
			
		||||
	scanner, err := library.DriverFactory{}.NewDriver(filepath.Base(string(s.Path)))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, xerrors.Errorf("Failed to new a library driver: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
	var vulnerabilities = []VulnInfo{}
 | 
			
		||||
	for _, pkg := range s.Libs {
 | 
			
		||||
		v, err := version.NewVersion(pkg.Version)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			util.Log.Debugf("new version cant detected %s@%s", pkg.Name, pkg.Version)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		tvulns, err := scanner.Detect(pkg.Name, v)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, xerrors.Errorf("failed to detect %s vulnerabilities: %w", scanner.Type(), err)
 | 
			
		||||
		}
 | 
			
		||||
		if len(tvulns) == 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		vulns := s.convertFanalToVuln(tvulns)
 | 
			
		||||
		vulnerabilities = append(vulnerabilities, vulns...)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return vulnerabilities, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s LibraryScanner) convertFanalToVuln(tvulns []types.DetectedVulnerability) (vulns []VulnInfo) {
 | 
			
		||||
	for _, tvuln := range tvulns {
 | 
			
		||||
		vinfo, err := s.getVulnDetail(tvuln)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			util.Log.Debugf("failed to getVulnDetail. err: %s, tvuln: %#v", err, tvuln)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		vulns = append(vulns, vinfo)
 | 
			
		||||
	}
 | 
			
		||||
	return vulns
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s LibraryScanner) getVulnDetail(tvuln types.DetectedVulnerability) (vinfo VulnInfo, err error) {
 | 
			
		||||
	vul, err := db.Config{}.GetVulnerability(tvuln.VulnerabilityID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return vinfo, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	vinfo.CveID = tvuln.VulnerabilityID
 | 
			
		||||
	vinfo.CveContents = getCveContents(tvuln.VulnerabilityID, vul)
 | 
			
		||||
	if tvuln.FixedVersion != "" {
 | 
			
		||||
		vinfo.LibraryFixedIns = []LibraryFixedIn{
 | 
			
		||||
			{
 | 
			
		||||
				Key:     s.GetLibraryKey(),
 | 
			
		||||
				Name:    tvuln.PkgName,
 | 
			
		||||
				FixedIn: tvuln.FixedVersion,
 | 
			
		||||
				Path:    s.Path,
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return vinfo, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getCveContents(cveID string, vul trivyDBTypes.Vulnerability) (contents map[CveContentType]CveContent) {
 | 
			
		||||
	contents = map[CveContentType]CveContent{}
 | 
			
		||||
	refs := []Reference{}
 | 
			
		||||
	for _, refURL := range vul.References {
 | 
			
		||||
		refs = append(refs, Reference{Source: "trivy", Link: refURL})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	content := CveContent{
 | 
			
		||||
		Type:          Trivy,
 | 
			
		||||
		CveID:         cveID,
 | 
			
		||||
		Title:         vul.Title,
 | 
			
		||||
		Summary:       vul.Description,
 | 
			
		||||
		Cvss3Severity: string(vul.Severity),
 | 
			
		||||
		References:    refs,
 | 
			
		||||
	}
 | 
			
		||||
	contents[Trivy] = content
 | 
			
		||||
	return contents
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LibraryMap is filename and library type
 | 
			
		||||
var LibraryMap = map[string]string{
 | 
			
		||||
	"package-lock.json": "node",
 | 
			
		||||
	"yarn.lock":         "node",
 | 
			
		||||
	"Gemfile.lock":      "ruby",
 | 
			
		||||
	"Cargo.lock":        "rust",
 | 
			
		||||
	"composer.lock":     "php",
 | 
			
		||||
	"Pipfile.lock":      "python",
 | 
			
		||||
	"poetry.lock":       "python",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetLibraryKey returns target library key
 | 
			
		||||
func (s LibraryScanner) GetLibraryKey() string {
 | 
			
		||||
	fileName := filepath.Base(s.Path)
 | 
			
		||||
	return LibraryMap[fileName]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LibraryFixedIn has library fixed information
 | 
			
		||||
type LibraryFixedIn struct {
 | 
			
		||||
	Key     string `json:"key,omitempty"`
 | 
			
		||||
	Name    string `json:"name,omitempty"`
 | 
			
		||||
	FixedIn string `json:"fixedIn,omitempty"`
 | 
			
		||||
	Path    string `json:"path,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										96
									
								
								models/library_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,96 @@
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/aquasecurity/trivy/pkg/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestLibraryScanners_Find(t *testing.T) {
 | 
			
		||||
	type args struct {
 | 
			
		||||
		path string
 | 
			
		||||
		name string
 | 
			
		||||
	}
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name string
 | 
			
		||||
		lss  LibraryScanners
 | 
			
		||||
		args args
 | 
			
		||||
		want map[string]types.Library
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "single file",
 | 
			
		||||
			lss: LibraryScanners{
 | 
			
		||||
				{
 | 
			
		||||
					Path: "/pathA",
 | 
			
		||||
					Libs: []types.Library{
 | 
			
		||||
						{
 | 
			
		||||
							Name:    "libA",
 | 
			
		||||
							Version: "1.0.0",
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			args: args{"/pathA", "libA"},
 | 
			
		||||
			want: map[string]types.Library{
 | 
			
		||||
				"/pathA": {
 | 
			
		||||
					Name:    "libA",
 | 
			
		||||
					Version: "1.0.0",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "multi file",
 | 
			
		||||
			lss: LibraryScanners{
 | 
			
		||||
				{
 | 
			
		||||
					Path: "/pathA",
 | 
			
		||||
					Libs: []types.Library{
 | 
			
		||||
						{
 | 
			
		||||
							Name:    "libA",
 | 
			
		||||
							Version: "1.0.0",
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					Path: "/pathB",
 | 
			
		||||
					Libs: []types.Library{
 | 
			
		||||
						{
 | 
			
		||||
							Name:    "libA",
 | 
			
		||||
							Version: "1.0.5",
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			args: args{"/pathA", "libA"},
 | 
			
		||||
			want: map[string]types.Library{
 | 
			
		||||
				"/pathA": {
 | 
			
		||||
					Name:    "libA",
 | 
			
		||||
					Version: "1.0.0",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "miss",
 | 
			
		||||
			lss: LibraryScanners{
 | 
			
		||||
				{
 | 
			
		||||
					Path: "/pathA",
 | 
			
		||||
					Libs: []types.Library{
 | 
			
		||||
						{
 | 
			
		||||
							Name:    "libA",
 | 
			
		||||
							Version: "1.0.0",
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			args: args{"/pathA", "libB"},
 | 
			
		||||
			want: map[string]types.Library{},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.name, func(t *testing.T) {
 | 
			
		||||
			if got := tt.lss.Find(tt.args.path, tt.args.name); !reflect.DeepEqual(got, tt.want) {
 | 
			
		||||
				t.Errorf("LibraryScanners.Find() = %v, want %v", got, tt.want)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
// JSONVersion is JSON Version
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package models
 | 
			
		||||
@@ -1,26 +1,12 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Packages is Map of Package
 | 
			
		||||
@@ -83,7 +69,7 @@ func (ps Packages) FindByFQPN(nameVerRelArc string) (*Package, error) {
 | 
			
		||||
			return &p, nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil, fmt.Errorf("Failed to find the package: %s", nameVerRelArc)
 | 
			
		||||
	return nil, xerrors.Errorf("Failed to find the package: %s", nameVerRelArc)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Package has installed binary packages.
 | 
			
		||||
@@ -135,18 +121,23 @@ func (p Package) FormatNewVer() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FormatVersionFromTo formats installed and new package version
 | 
			
		||||
func (p Package) FormatVersionFromTo(notFixedYet bool, status string) string {
 | 
			
		||||
func (p Package) FormatVersionFromTo(stat PackageFixStatus) string {
 | 
			
		||||
	to := p.FormatNewVer()
 | 
			
		||||
	if notFixedYet {
 | 
			
		||||
		if status != "" {
 | 
			
		||||
			to = status
 | 
			
		||||
	if stat.NotFixedYet {
 | 
			
		||||
		if stat.FixState != "" {
 | 
			
		||||
			to = stat.FixState
 | 
			
		||||
		} else {
 | 
			
		||||
			to = "Not Fixed Yet"
 | 
			
		||||
		}
 | 
			
		||||
	} else if p.NewVersion == "" {
 | 
			
		||||
		to = "Unknown"
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("%s-%s -> %s", p.Name, p.FormatVer(), to)
 | 
			
		||||
	var fixedIn string
 | 
			
		||||
	if stat.FixedIn != "" {
 | 
			
		||||
		fixedIn = fmt.Sprintf(" (FixedIn: %s)", stat.FixedIn)
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("%s-%s -> %s%s",
 | 
			
		||||
		p.Name, p.FormatVer(), to, fixedIn)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FormatChangelog formats the changelog
 | 
			
		||||
@@ -183,8 +174,29 @@ type Changelog struct {
 | 
			
		||||
 | 
			
		||||
// AffectedProcess keep a processes information affected by software update
 | 
			
		||||
type AffectedProcess struct {
 | 
			
		||||
	PID  string `json:"pid"`
 | 
			
		||||
	Name string `json:"name"`
 | 
			
		||||
	PID         string       `json:"pid,omitempty"`
 | 
			
		||||
	Name        string       `json:"name,omitempty"`
 | 
			
		||||
	ListenPorts []ListenPort `json:"listenPorts,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ListenPort has the result of parsing the port information to the address and port.
 | 
			
		||||
type ListenPort struct {
 | 
			
		||||
	Address           string   `json:"address"`
 | 
			
		||||
	Port              string   `json:"port"`
 | 
			
		||||
	PortScanSuccessOn []string `json:"portScanSuccessOn"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HasPortScanSuccessOn checks if Package.AffectedProcs has PortScanSuccessOn
 | 
			
		||||
func (p Package) HasPortScanSuccessOn() bool {
 | 
			
		||||
	for _, ap := range p.AffectedProcs {
 | 
			
		||||
		for _, lp := range ap.ListenPorts {
 | 
			
		||||
			if len(lp.PortScanSuccessOn) > 0 {
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NeedRestartProcess keep a processes information affected by software update
 | 
			
		||||
@@ -204,6 +216,7 @@ type NeedRestartProcess struct {
 | 
			
		||||
type SrcPackage struct {
 | 
			
		||||
	Name        string   `json:"name"`
 | 
			
		||||
	Version     string   `json:"version"`
 | 
			
		||||
	Arch        string   `json:"arch"`
 | 
			
		||||
	BinaryNames []string `json:"binaryNames"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -235,3 +248,28 @@ func (s SrcPackages) FindByBinName(name string) (*SrcPackage, bool) {
 | 
			
		||||
	}
 | 
			
		||||
	return nil, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// raspiPackNamePattern is a regular expression pattern to detect the Raspberry Pi specific package from the package name.
 | 
			
		||||
// e.g. libraspberrypi-dev, rpi-eeprom, python3-rpi.gpio, pi-bluetooth
 | 
			
		||||
var raspiPackNamePattern = regexp.MustCompile(`(.*raspberry.*|^rpi.*|.*-rpi.*|^pi-.*)`)
 | 
			
		||||
 | 
			
		||||
// raspiPackNamePattern is a regular expression pattern to detect the Raspberry Pi specific package from the version.
 | 
			
		||||
// e.g. ffmpeg 7:4.1.4-1+rpt7~deb10u1, vlc 3.0.10-0+deb10u1+rpt2
 | 
			
		||||
var raspiPackVersionPattern = regexp.MustCompile(`.+\+rp(t|i)\d+`)
 | 
			
		||||
 | 
			
		||||
// raspiPackNameList is a package name array of Raspberry Pi specific packages that are difficult to detect with regular expressions.
 | 
			
		||||
var raspiPackNameList = []string{"piclone", "pipanel", "pishutdown", "piwiz", "pixflat-icons"}
 | 
			
		||||
 | 
			
		||||
// IsRaspbianPackage judges whether it is a package related to Raspberry Pi from the package name and version
 | 
			
		||||
func IsRaspbianPackage(name, version string) bool {
 | 
			
		||||
	if raspiPackNamePattern.MatchString(name) || raspiPackVersionPattern.MatchString(version) {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	for _, n := range raspiPackNameList {
 | 
			
		||||
		if n == name {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -191,3 +175,209 @@ func TestFindByBinName(t *testing.T) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPackage_FormatVersionFromTo(t *testing.T) {
 | 
			
		||||
	type fields struct {
 | 
			
		||||
		Name             string
 | 
			
		||||
		Version          string
 | 
			
		||||
		Release          string
 | 
			
		||||
		NewVersion       string
 | 
			
		||||
		NewRelease       string
 | 
			
		||||
		Arch             string
 | 
			
		||||
		Repository       string
 | 
			
		||||
		Changelog        Changelog
 | 
			
		||||
		AffectedProcs    []AffectedProcess
 | 
			
		||||
		NeedRestartProcs []NeedRestartProcess
 | 
			
		||||
	}
 | 
			
		||||
	type args struct {
 | 
			
		||||
		stat PackageFixStatus
 | 
			
		||||
	}
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name   string
 | 
			
		||||
		fields fields
 | 
			
		||||
		args   args
 | 
			
		||||
		want   string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "fixed",
 | 
			
		||||
			fields: fields{
 | 
			
		||||
				Name:       "packA",
 | 
			
		||||
				Version:    "1.0.0",
 | 
			
		||||
				Release:    "a",
 | 
			
		||||
				NewVersion: "1.0.1",
 | 
			
		||||
				NewRelease: "b",
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				stat: PackageFixStatus{
 | 
			
		||||
					NotFixedYet: false,
 | 
			
		||||
					FixedIn:     "1.0.1-b",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			want: "packA-1.0.0-a -> 1.0.1-b (FixedIn: 1.0.1-b)",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "nfy",
 | 
			
		||||
			fields: fields{
 | 
			
		||||
				Name:    "packA",
 | 
			
		||||
				Version: "1.0.0",
 | 
			
		||||
				Release: "a",
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				stat: PackageFixStatus{
 | 
			
		||||
					NotFixedYet: true,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			want: "packA-1.0.0-a -> Not Fixed Yet",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "nfy",
 | 
			
		||||
			fields: fields{
 | 
			
		||||
				Name:    "packA",
 | 
			
		||||
				Version: "1.0.0",
 | 
			
		||||
				Release: "a",
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				stat: PackageFixStatus{
 | 
			
		||||
					NotFixedYet: false,
 | 
			
		||||
					FixedIn:     "1.0.1-b",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			want: "packA-1.0.0-a -> Unknown (FixedIn: 1.0.1-b)",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "nfy2",
 | 
			
		||||
			fields: fields{
 | 
			
		||||
				Name:    "packA",
 | 
			
		||||
				Version: "1.0.0",
 | 
			
		||||
				Release: "a",
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				stat: PackageFixStatus{
 | 
			
		||||
					NotFixedYet: true,
 | 
			
		||||
					FixedIn:     "1.0.1-b",
 | 
			
		||||
					FixState:    "open",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			want: "packA-1.0.0-a -> open (FixedIn: 1.0.1-b)",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "nfy3",
 | 
			
		||||
			fields: fields{
 | 
			
		||||
				Name:    "packA",
 | 
			
		||||
				Version: "1.0.0",
 | 
			
		||||
				Release: "a",
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				stat: PackageFixStatus{
 | 
			
		||||
					NotFixedYet: true,
 | 
			
		||||
					FixedIn:     "1.0.1-b",
 | 
			
		||||
					FixState:    "open",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			want: "packA-1.0.0-a -> open (FixedIn: 1.0.1-b)",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.name, func(t *testing.T) {
 | 
			
		||||
			p := Package{
 | 
			
		||||
				Name:             tt.fields.Name,
 | 
			
		||||
				Version:          tt.fields.Version,
 | 
			
		||||
				Release:          tt.fields.Release,
 | 
			
		||||
				NewVersion:       tt.fields.NewVersion,
 | 
			
		||||
				NewRelease:       tt.fields.NewRelease,
 | 
			
		||||
				Arch:             tt.fields.Arch,
 | 
			
		||||
				Repository:       tt.fields.Repository,
 | 
			
		||||
				Changelog:        tt.fields.Changelog,
 | 
			
		||||
				AffectedProcs:    tt.fields.AffectedProcs,
 | 
			
		||||
				NeedRestartProcs: tt.fields.NeedRestartProcs,
 | 
			
		||||
			}
 | 
			
		||||
			if got := p.FormatVersionFromTo(tt.args.stat); got != tt.want {
 | 
			
		||||
				t.Errorf("Package.FormatVersionFromTo() = %v, want %v", got, tt.want)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Test_IsRaspbianPackage(t *testing.T) {
 | 
			
		||||
	type args struct {
 | 
			
		||||
		name string
 | 
			
		||||
		ver  string
 | 
			
		||||
	}
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name   string
 | 
			
		||||
		in     []args
 | 
			
		||||
		expect []bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "nameRegExp",
 | 
			
		||||
			in: []args{
 | 
			
		||||
				{
 | 
			
		||||
					name: "libraspberrypi-dev",
 | 
			
		||||
					ver:  "1.20200811-1",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					name: "rpi-eeprom",
 | 
			
		||||
					ver:  "7.10-1",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					name: "python3-rpi.gpio",
 | 
			
		||||
					ver:  "0.7.0-0.1~bpo10+1",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					name: "arping",
 | 
			
		||||
					ver:  "2.19-6",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					name: "pi-bluetooth",
 | 
			
		||||
					ver:  "0.1.14",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expect: []bool{true, true, true, false, true, false},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "verRegExp",
 | 
			
		||||
			in: []args{
 | 
			
		||||
				{
 | 
			
		||||
					name: "ffmpeg",
 | 
			
		||||
					ver:  "7:4.1.6-1~deb10u1+rpt1",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					name: "gcc",
 | 
			
		||||
					ver:  "4:8.3.0-1+rpi2",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expect: []bool{true, true},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "nameList",
 | 
			
		||||
			in: []args{
 | 
			
		||||
				{
 | 
			
		||||
					name: "piclone",
 | 
			
		||||
					ver:  "0.16",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expect: []bool{true},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "debianPackage",
 | 
			
		||||
			in: []args{
 | 
			
		||||
				{
 | 
			
		||||
					name: "apt",
 | 
			
		||||
					ver:  "1.8.2.1",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			expect: []bool{false},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.name, func(t *testing.T) {
 | 
			
		||||
			for i, p := range tt.in {
 | 
			
		||||
				ret := IsRaspbianPackage(p.name, p.ver)
 | 
			
		||||
				if !reflect.DeepEqual(ret, tt.expect[i]) {
 | 
			
		||||
					t.Errorf("[%s->%s] expected: %t, actual: %t, in: %#v", tt.name, tt.in[i].name, tt.expect[i], ret, tt.in[i])
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -24,8 +7,6 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/future-architect/vuls/alert"
 | 
			
		||||
 | 
			
		||||
	"github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/cwe"
 | 
			
		||||
	"github.com/future-architect/vuls/util"
 | 
			
		||||
@@ -36,35 +17,41 @@ type ScanResults []ScanResult
 | 
			
		||||
 | 
			
		||||
// ScanResult has the result of scanned CVE information.
 | 
			
		||||
type ScanResult struct {
 | 
			
		||||
	JSONVersion      int                    `json:"jsonVersion"`
 | 
			
		||||
	Lang             string                 `json:"lang"`
 | 
			
		||||
	ServerUUID       string                 `json:"serverUUID"`
 | 
			
		||||
	ServerName       string                 `json:"serverName"` // TOML Section key
 | 
			
		||||
	Family           string                 `json:"family"`
 | 
			
		||||
	Release          string                 `json:"release"`
 | 
			
		||||
	Container        Container              `json:"container"`
 | 
			
		||||
	Platform         Platform               `json:"platform"`
 | 
			
		||||
	IPv4Addrs        []string               `json:"ipv4Addrs,omitempty"` // only global unicast address (https://golang.org/pkg/net/#IP.IsGlobalUnicast)
 | 
			
		||||
	IPv6Addrs        []string               `json:"ipv6Addrs,omitempty"` // only global unicast address (https://golang.org/pkg/net/#IP.IsGlobalUnicast)
 | 
			
		||||
	ScannedAt        time.Time              `json:"scannedAt"`
 | 
			
		||||
	ScanMode         string                 `json:"scanMode"`
 | 
			
		||||
	ScannedVersion   string                 `json:"scannedVersion"`
 | 
			
		||||
	ScannedRevision  string                 `json:"scannedRevision"`
 | 
			
		||||
	ScannedBy        string                 `json:"scannedBy"`
 | 
			
		||||
	ScannedIPv4Addrs []string               `json:"scannedIpv4Addrs"`
 | 
			
		||||
	ScannedIPv6Addrs []string               `json:"scannedIpv6Addrs"`
 | 
			
		||||
	ReportedAt       time.Time              `json:"reportedAt"`
 | 
			
		||||
	ReportedVersion  string                 `json:"reportedVersion"`
 | 
			
		||||
	ReportedRevision string                 `json:"reportedRevision"`
 | 
			
		||||
	ReportedBy       string                 `json:"reportedBy"`
 | 
			
		||||
	ScannedCves      VulnInfos              `json:"scannedCves"`
 | 
			
		||||
	RunningKernel    Kernel                 `json:"runningKernel"`
 | 
			
		||||
	Packages         Packages               `json:"packages"`
 | 
			
		||||
	CweDict          CweDict                `json:"cweDict"`
 | 
			
		||||
	Optional         map[string]interface{} `json:",omitempty"`
 | 
			
		||||
	SrcPackages      SrcPackages            `json:",omitempty"`
 | 
			
		||||
	Errors           []string               `json:"errors"`
 | 
			
		||||
	Config           struct {
 | 
			
		||||
	JSONVersion      int                   `json:"jsonVersion"`
 | 
			
		||||
	Lang             string                `json:"lang"`
 | 
			
		||||
	ServerUUID       string                `json:"serverUUID"`
 | 
			
		||||
	ServerName       string                `json:"serverName"` // TOML Section key
 | 
			
		||||
	Family           string                `json:"family"`
 | 
			
		||||
	Release          string                `json:"release"`
 | 
			
		||||
	Container        Container             `json:"container"`
 | 
			
		||||
	Platform         Platform              `json:"platform"`
 | 
			
		||||
	IPv4Addrs        []string              `json:"ipv4Addrs,omitempty"` // only global unicast address (https://golang.org/pkg/net/#IP.IsGlobalUnicast)
 | 
			
		||||
	IPv6Addrs        []string              `json:"ipv6Addrs,omitempty"` // only global unicast address (https://golang.org/pkg/net/#IP.IsGlobalUnicast)
 | 
			
		||||
	IPSIdentifiers   map[config.IPS]string `json:"ipsIdentifiers,omitempty"`
 | 
			
		||||
	ScannedAt        time.Time             `json:"scannedAt"`
 | 
			
		||||
	ScanMode         string                `json:"scanMode"`
 | 
			
		||||
	ScannedVersion   string                `json:"scannedVersion"`
 | 
			
		||||
	ScannedRevision  string                `json:"scannedRevision"`
 | 
			
		||||
	ScannedBy        string                `json:"scannedBy"`
 | 
			
		||||
	ScannedVia       string                `json:"scannedVia"`
 | 
			
		||||
	ScannedIPv4Addrs []string              `json:"scannedIpv4Addrs,omitempty"`
 | 
			
		||||
	ScannedIPv6Addrs []string              `json:"scannedIpv6Addrs,omitempty"`
 | 
			
		||||
	ReportedAt       time.Time             `json:"reportedAt"`
 | 
			
		||||
	ReportedVersion  string                `json:"reportedVersion"`
 | 
			
		||||
	ReportedRevision string                `json:"reportedRevision"`
 | 
			
		||||
	ReportedBy       string                `json:"reportedBy"`
 | 
			
		||||
	Errors           []string              `json:"errors"`
 | 
			
		||||
	Warnings         []string              `json:"warnings"`
 | 
			
		||||
 | 
			
		||||
	ScannedCves       VulnInfos              `json:"scannedCves"`
 | 
			
		||||
	RunningKernel     Kernel                 `json:"runningKernel"`
 | 
			
		||||
	Packages          Packages               `json:"packages"`
 | 
			
		||||
	SrcPackages       SrcPackages            `json:",omitempty"`
 | 
			
		||||
	WordPressPackages *WordPressPackages     `json:",omitempty"`
 | 
			
		||||
	LibraryScanners   LibraryScanners        `json:"libraries,omitempty"`
 | 
			
		||||
	CweDict           CweDict                `json:"cweDict,omitempty"`
 | 
			
		||||
	Optional          map[string]interface{} `json:",omitempty"`
 | 
			
		||||
	Config            struct {
 | 
			
		||||
		Scan   config.Config `json:"scan"`
 | 
			
		||||
		Report config.Config `json:"report"`
 | 
			
		||||
	} `json:"config"`
 | 
			
		||||
@@ -74,7 +61,7 @@ type ScanResult struct {
 | 
			
		||||
type CweDict map[string]CweDictEntry
 | 
			
		||||
 | 
			
		||||
// Get the name, url, top10URL for the specified cweID, lang
 | 
			
		||||
func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL string) {
 | 
			
		||||
func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL, cweTop25Rank, cweTop25URL, sansTop25Rank, sansTop25URL string) {
 | 
			
		||||
	cweNum := strings.TrimPrefix(cweID, "CWE-")
 | 
			
		||||
	switch config.Conf.Lang {
 | 
			
		||||
	case "ja":
 | 
			
		||||
@@ -82,6 +69,14 @@ func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL string)
 | 
			
		||||
			top10Rank = dict.OwaspTopTen2017
 | 
			
		||||
			top10URL = cwe.OwaspTopTen2017GitHubURLJa[dict.OwaspTopTen2017]
 | 
			
		||||
		}
 | 
			
		||||
		if dict, ok := c[cweNum]; ok && dict.CweTopTwentyfive2019 != "" {
 | 
			
		||||
			cweTop25Rank = dict.CweTopTwentyfive2019
 | 
			
		||||
			cweTop25URL = cwe.CweTopTwentyfive2019URL
 | 
			
		||||
		}
 | 
			
		||||
		if dict, ok := c[cweNum]; ok && dict.SansTopTwentyfive != "" {
 | 
			
		||||
			sansTop25Rank = dict.SansTopTwentyfive
 | 
			
		||||
			sansTop25URL = cwe.SansTopTwentyfiveURL
 | 
			
		||||
		}
 | 
			
		||||
		if dict, ok := cwe.CweDictJa[cweNum]; ok {
 | 
			
		||||
			name = dict.Name
 | 
			
		||||
			url = fmt.Sprintf("http://jvndb.jvn.jp/ja/cwe/%s.html", cweID)
 | 
			
		||||
@@ -96,6 +91,14 @@ func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL string)
 | 
			
		||||
			top10Rank = dict.OwaspTopTen2017
 | 
			
		||||
			top10URL = cwe.OwaspTopTen2017GitHubURLEn[dict.OwaspTopTen2017]
 | 
			
		||||
		}
 | 
			
		||||
		if dict, ok := c[cweNum]; ok && dict.CweTopTwentyfive2019 != "" {
 | 
			
		||||
			cweTop25Rank = dict.CweTopTwentyfive2019
 | 
			
		||||
			cweTop25URL = cwe.CweTopTwentyfive2019URL
 | 
			
		||||
		}
 | 
			
		||||
		if dict, ok := c[cweNum]; ok && dict.SansTopTwentyfive != "" {
 | 
			
		||||
			sansTop25Rank = dict.SansTopTwentyfive
 | 
			
		||||
			sansTop25URL = cwe.SansTopTwentyfiveURL
 | 
			
		||||
		}
 | 
			
		||||
		url = fmt.Sprintf("https://cwe.mitre.org/data/definitions/%s.html", cweID)
 | 
			
		||||
		if dict, ok := cwe.CweDictEn[cweNum]; ok {
 | 
			
		||||
			name = dict.Name
 | 
			
		||||
@@ -106,15 +109,11 @@ func (c CweDict) Get(cweID, lang string) (name, url, top10Rank, top10URL string)
 | 
			
		||||
 | 
			
		||||
// CweDictEntry is a entry of CWE
 | 
			
		||||
type CweDictEntry struct {
 | 
			
		||||
	En              *cwe.Cwe `json:"en,omitempty"`
 | 
			
		||||
	Ja              *cwe.Cwe `json:"ja,omitempty"`
 | 
			
		||||
	OwaspTopTen2017 string   `json:"owaspTopTen2017"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetAlertsByCveID return alerts fetched by cveID
 | 
			
		||||
func GetAlertsByCveID(cveID string, lang string) (alerts []alert.Alert) {
 | 
			
		||||
	alerts = alert.GenerateAlertDict(cveID, lang)
 | 
			
		||||
	return alerts
 | 
			
		||||
	En                   *cwe.Cwe `json:"en,omitempty"`
 | 
			
		||||
	Ja                   *cwe.Cwe `json:"ja,omitempty"`
 | 
			
		||||
	OwaspTopTen2017      string   `json:"owaspTopTen2017"`
 | 
			
		||||
	CweTopTwentyfive2019 string   `json:"cweTopTwentyfive2019"`
 | 
			
		||||
	SansTopTwentyfive    string   `json:"sansTopTwentyfive"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Kernel has the Release, version and whether need restart
 | 
			
		||||
@@ -153,8 +152,6 @@ func (r ScanResult) FilterIgnoreCves() ScanResult {
 | 
			
		||||
			if con, ok := s.Containers[r.Container.Name]; ok {
 | 
			
		||||
				ignoreCves = con.IgnoreCves
 | 
			
		||||
			} else {
 | 
			
		||||
				util.Log.Errorf("%s is not found in config.toml",
 | 
			
		||||
					r.Container.Name)
 | 
			
		||||
				return r
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
@@ -182,6 +179,7 @@ func (r ScanResult) FilterUnfixed() ScanResult {
 | 
			
		||||
		return r
 | 
			
		||||
	}
 | 
			
		||||
	filtered := r.ScannedCves.Find(func(v VulnInfo) bool {
 | 
			
		||||
		// Report cves detected by CPE because Vuls can't know 'fixed' or 'unfixed'
 | 
			
		||||
		if len(v.CpeURIs) != 0 {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
@@ -197,7 +195,7 @@ func (r ScanResult) FilterUnfixed() ScanResult {
 | 
			
		||||
 | 
			
		||||
// FilterIgnorePkgs is filter function.
 | 
			
		||||
func (r ScanResult) FilterIgnorePkgs() ScanResult {
 | 
			
		||||
	ignorePkgsRegexps := []string{}
 | 
			
		||||
	var ignorePkgsRegexps []string
 | 
			
		||||
	if len(r.Container.Name) == 0 {
 | 
			
		||||
		ignorePkgsRegexps = config.Conf.Servers[r.ServerName].IgnorePkgsRegexp
 | 
			
		||||
	} else {
 | 
			
		||||
@@ -205,8 +203,6 @@ func (r ScanResult) FilterIgnorePkgs() ScanResult {
 | 
			
		||||
			if con, ok := s.Containers[r.Container.Name]; ok {
 | 
			
		||||
				ignorePkgsRegexps = con.IgnorePkgsRegexp
 | 
			
		||||
			} else {
 | 
			
		||||
				util.Log.Errorf("%s is not found in config.toml",
 | 
			
		||||
					r.Container.Name)
 | 
			
		||||
				return r
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
@@ -220,7 +216,7 @@ func (r ScanResult) FilterIgnorePkgs() ScanResult {
 | 
			
		||||
	for _, pkgRegexp := range ignorePkgsRegexps {
 | 
			
		||||
		re, err := regexp.Compile(pkgRegexp)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			util.Log.Errorf("Faild to parse %s, %s", pkgRegexp, err)
 | 
			
		||||
			util.Log.Errorf("Failed to parse %s. err: %+v", pkgRegexp, err)
 | 
			
		||||
			continue
 | 
			
		||||
		} else {
 | 
			
		||||
			regexps = append(regexps, re)
 | 
			
		||||
@@ -252,7 +248,31 @@ func (r ScanResult) FilterIgnorePkgs() ScanResult {
 | 
			
		||||
	return r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ReportFileName returns the filename on localhost without extention
 | 
			
		||||
// FilterInactiveWordPressLibs is filter function.
 | 
			
		||||
func (r ScanResult) FilterInactiveWordPressLibs() ScanResult {
 | 
			
		||||
	if !config.Conf.Servers[r.ServerName].WordPress.IgnoreInactive {
 | 
			
		||||
		return r
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	filtered := r.ScannedCves.Find(func(v VulnInfo) bool {
 | 
			
		||||
		if len(v.WpPackageFixStats) == 0 {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
		// Ignore if all libs in this vulnInfo inactive
 | 
			
		||||
		for _, wp := range v.WpPackageFixStats {
 | 
			
		||||
			if p, ok := r.WordPressPackages.Find(wp.Name); ok {
 | 
			
		||||
				if p.Status != Inactive {
 | 
			
		||||
					return true
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return false
 | 
			
		||||
	})
 | 
			
		||||
	r.ScannedCves = filtered
 | 
			
		||||
	return r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ReportFileName returns the filename on localhost without extension
 | 
			
		||||
func (r ScanResult) ReportFileName() (name string) {
 | 
			
		||||
	if len(r.Container.ContainerID) == 0 {
 | 
			
		||||
		return fmt.Sprintf("%s", r.ServerName)
 | 
			
		||||
@@ -260,7 +280,7 @@ func (r ScanResult) ReportFileName() (name string) {
 | 
			
		||||
	return fmt.Sprintf("%s@%s", r.Container.Name, r.ServerName)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ReportKeyName returns the name of key on S3, Azure-Blob without extention
 | 
			
		||||
// ReportKeyName returns the name of key on S3, Azure-Blob without extension
 | 
			
		||||
func (r ScanResult) ReportKeyName() (name string) {
 | 
			
		||||
	timestr := r.ScannedAt.Format(time.RFC3339)
 | 
			
		||||
	if len(r.Container.ContainerID) == 0 {
 | 
			
		||||
@@ -289,6 +309,9 @@ func (r ScanResult) ServerInfoTui() string {
 | 
			
		||||
	if len(r.Container.ContainerID) == 0 {
 | 
			
		||||
		line := fmt.Sprintf("%s (%s%s)",
 | 
			
		||||
			r.ServerName, r.Family, r.Release)
 | 
			
		||||
		if len(r.Warnings) != 0 {
 | 
			
		||||
			line = "[Warn] " + line
 | 
			
		||||
		}
 | 
			
		||||
		if r.RunningKernel.RebootRequired {
 | 
			
		||||
			return "[Reboot] " + line
 | 
			
		||||
		}
 | 
			
		||||
@@ -316,20 +339,21 @@ func (r ScanResult) FormatServerName() (name string) {
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FormatTextReportHeadedr returns header of text report
 | 
			
		||||
func (r ScanResult) FormatTextReportHeadedr() string {
 | 
			
		||||
// FormatTextReportHeader returns header of text report
 | 
			
		||||
func (r ScanResult) FormatTextReportHeader() string {
 | 
			
		||||
	var buf bytes.Buffer
 | 
			
		||||
	for i := 0; i < len(r.ServerInfo()); i++ {
 | 
			
		||||
		buf.WriteString("=")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return fmt.Sprintf("%s\n%s\n%s, %s, %s, %s, %s\n",
 | 
			
		||||
	return fmt.Sprintf("%s\n%s\n%s, %s, %s, %s, %s, %s\n",
 | 
			
		||||
		r.ServerInfo(),
 | 
			
		||||
		buf.String(),
 | 
			
		||||
		r.ScannedCves.FormatCveSummary(),
 | 
			
		||||
		r.ScannedCves.FormatFixedStatus(r.Packages),
 | 
			
		||||
		r.FormatUpdatablePacksSummary(),
 | 
			
		||||
		r.FormatExploitCveSummary(),
 | 
			
		||||
		r.FormatMetasploitCveSummary(),
 | 
			
		||||
		r.FormatAlertSummary(),
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
@@ -365,7 +389,18 @@ func (r ScanResult) FormatExploitCveSummary() string {
 | 
			
		||||
	return fmt.Sprintf("%d exploits", nExploitCve)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FormatAlertSummary returns a summary of XCERT alerts
 | 
			
		||||
// FormatMetasploitCveSummary returns a summary of exploit cve
 | 
			
		||||
func (r ScanResult) FormatMetasploitCveSummary() string {
 | 
			
		||||
	nMetasploitCve := 0
 | 
			
		||||
	for _, vuln := range r.ScannedCves {
 | 
			
		||||
		if 0 < len(vuln.Metasploits) {
 | 
			
		||||
			nMetasploitCve++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("%d modules", nMetasploitCve)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FormatAlertSummary returns a summary of CERT alerts
 | 
			
		||||
func (r ScanResult) FormatAlertSummary() string {
 | 
			
		||||
	jaCnt := 0
 | 
			
		||||
	enCnt := 0
 | 
			
		||||
@@ -381,6 +416,10 @@ func (r ScanResult) FormatAlertSummary() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r ScanResult) isDisplayUpdatableNum() bool {
 | 
			
		||||
	if r.Family == config.FreeBSD {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var mode config.ScanMode
 | 
			
		||||
	s, _ := config.Conf.Servers[r.ServerName]
 | 
			
		||||
	mode = s.Mode
 | 
			
		||||
@@ -437,3 +476,30 @@ type Platform struct {
 | 
			
		||||
	Name       string `json:"name"` // aws or azure or gcp or other...
 | 
			
		||||
	InstanceID string `json:"instanceID"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RemoveRaspbianPackFromResult is for Raspberry Pi and removes the Raspberry Pi dedicated package from ScanResult.
 | 
			
		||||
func (r ScanResult) RemoveRaspbianPackFromResult() ScanResult {
 | 
			
		||||
	if r.Family != config.Raspbian {
 | 
			
		||||
		return r
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result := r
 | 
			
		||||
	packs := make(Packages)
 | 
			
		||||
	for _, pack := range r.Packages {
 | 
			
		||||
		if !IsRaspbianPackage(pack.Name, pack.Version) {
 | 
			
		||||
			packs[pack.Name] = pack
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	srcPacks := make(SrcPackages)
 | 
			
		||||
	for _, pack := range r.SrcPackages {
 | 
			
		||||
		if !IsRaspbianPackage(pack.Name, pack.Version) {
 | 
			
		||||
			srcPacks[pack.Name] = pack
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result.Packages = packs
 | 
			
		||||
	result.SrcPackages = srcPacks
 | 
			
		||||
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -348,7 +332,7 @@ func TestFilterUnfixed(t *testing.T) {
 | 
			
		||||
				ScannedCves: VulnInfos{
 | 
			
		||||
					"CVE-2017-0001": {
 | 
			
		||||
						CveID: "CVE-2017-0001",
 | 
			
		||||
						AffectedPackages: PackageStatuses{
 | 
			
		||||
						AffectedPackages: PackageFixStatuses{
 | 
			
		||||
							{
 | 
			
		||||
								Name:        "a",
 | 
			
		||||
								NotFixedYet: true,
 | 
			
		||||
@@ -357,7 +341,7 @@ func TestFilterUnfixed(t *testing.T) {
 | 
			
		||||
					},
 | 
			
		||||
					"CVE-2017-0002": {
 | 
			
		||||
						CveID: "CVE-2017-0002",
 | 
			
		||||
						AffectedPackages: PackageStatuses{
 | 
			
		||||
						AffectedPackages: PackageFixStatuses{
 | 
			
		||||
							{
 | 
			
		||||
								Name:        "b",
 | 
			
		||||
								NotFixedYet: false,
 | 
			
		||||
@@ -366,7 +350,7 @@ func TestFilterUnfixed(t *testing.T) {
 | 
			
		||||
					},
 | 
			
		||||
					"CVE-2017-0003": {
 | 
			
		||||
						CveID: "CVE-2017-0003",
 | 
			
		||||
						AffectedPackages: PackageStatuses{
 | 
			
		||||
						AffectedPackages: PackageFixStatuses{
 | 
			
		||||
							{
 | 
			
		||||
								Name:        "c",
 | 
			
		||||
								NotFixedYet: true,
 | 
			
		||||
@@ -383,7 +367,7 @@ func TestFilterUnfixed(t *testing.T) {
 | 
			
		||||
				ScannedCves: VulnInfos{
 | 
			
		||||
					"CVE-2017-0002": {
 | 
			
		||||
						CveID: "CVE-2017-0002",
 | 
			
		||||
						AffectedPackages: PackageStatuses{
 | 
			
		||||
						AffectedPackages: PackageFixStatuses{
 | 
			
		||||
							{
 | 
			
		||||
								Name:        "b",
 | 
			
		||||
								NotFixedYet: false,
 | 
			
		||||
@@ -392,7 +376,7 @@ func TestFilterUnfixed(t *testing.T) {
 | 
			
		||||
					},
 | 
			
		||||
					"CVE-2017-0003": {
 | 
			
		||||
						CveID: "CVE-2017-0003",
 | 
			
		||||
						AffectedPackages: PackageStatuses{
 | 
			
		||||
						AffectedPackages: PackageFixStatuses{
 | 
			
		||||
							{
 | 
			
		||||
								Name:        "c",
 | 
			
		||||
								NotFixedYet: true,
 | 
			
		||||
@@ -435,7 +419,7 @@ func TestFilterIgnorePkgs(t *testing.T) {
 | 
			
		||||
					ScannedCves: VulnInfos{
 | 
			
		||||
						"CVE-2017-0001": {
 | 
			
		||||
							CveID: "CVE-2017-0001",
 | 
			
		||||
							AffectedPackages: PackageStatuses{
 | 
			
		||||
							AffectedPackages: PackageFixStatuses{
 | 
			
		||||
								{Name: "kernel"},
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
@@ -462,7 +446,7 @@ func TestFilterIgnorePkgs(t *testing.T) {
 | 
			
		||||
					ScannedCves: VulnInfos{
 | 
			
		||||
						"CVE-2017-0001": {
 | 
			
		||||
							CveID: "CVE-2017-0001",
 | 
			
		||||
							AffectedPackages: PackageStatuses{
 | 
			
		||||
							AffectedPackages: PackageFixStatuses{
 | 
			
		||||
								{Name: "kernel"},
 | 
			
		||||
								{Name: "vim"},
 | 
			
		||||
							},
 | 
			
		||||
@@ -475,7 +459,7 @@ func TestFilterIgnorePkgs(t *testing.T) {
 | 
			
		||||
				ScannedCves: VulnInfos{
 | 
			
		||||
					"CVE-2017-0001": {
 | 
			
		||||
						CveID: "CVE-2017-0001",
 | 
			
		||||
						AffectedPackages: PackageStatuses{
 | 
			
		||||
						AffectedPackages: PackageFixStatuses{
 | 
			
		||||
							{Name: "kernel"},
 | 
			
		||||
							{Name: "vim"},
 | 
			
		||||
						},
 | 
			
		||||
@@ -491,7 +475,7 @@ func TestFilterIgnorePkgs(t *testing.T) {
 | 
			
		||||
					ScannedCves: VulnInfos{
 | 
			
		||||
						"CVE-2017-0001": {
 | 
			
		||||
							CveID: "CVE-2017-0001",
 | 
			
		||||
							AffectedPackages: PackageStatuses{
 | 
			
		||||
							AffectedPackages: PackageFixStatuses{
 | 
			
		||||
								{Name: "kernel"},
 | 
			
		||||
								{Name: "vim"},
 | 
			
		||||
							},
 | 
			
		||||
@@ -545,7 +529,7 @@ func TestFilterIgnorePkgsContainer(t *testing.T) {
 | 
			
		||||
					ScannedCves: VulnInfos{
 | 
			
		||||
						"CVE-2017-0001": {
 | 
			
		||||
							CveID: "CVE-2017-0001",
 | 
			
		||||
							AffectedPackages: PackageStatuses{
 | 
			
		||||
							AffectedPackages: PackageFixStatuses{
 | 
			
		||||
								{Name: "kernel"},
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
@@ -574,7 +558,7 @@ func TestFilterIgnorePkgsContainer(t *testing.T) {
 | 
			
		||||
					ScannedCves: VulnInfos{
 | 
			
		||||
						"CVE-2017-0001": {
 | 
			
		||||
							CveID: "CVE-2017-0001",
 | 
			
		||||
							AffectedPackages: PackageStatuses{
 | 
			
		||||
							AffectedPackages: PackageFixStatuses{
 | 
			
		||||
								{Name: "kernel"},
 | 
			
		||||
								{Name: "vim"},
 | 
			
		||||
							},
 | 
			
		||||
@@ -588,7 +572,7 @@ func TestFilterIgnorePkgsContainer(t *testing.T) {
 | 
			
		||||
				ScannedCves: VulnInfos{
 | 
			
		||||
					"CVE-2017-0001": {
 | 
			
		||||
						CveID: "CVE-2017-0001",
 | 
			
		||||
						AffectedPackages: PackageStatuses{
 | 
			
		||||
						AffectedPackages: PackageFixStatuses{
 | 
			
		||||
							{Name: "kernel"},
 | 
			
		||||
							{Name: "vim"},
 | 
			
		||||
						},
 | 
			
		||||
@@ -605,7 +589,7 @@ func TestFilterIgnorePkgsContainer(t *testing.T) {
 | 
			
		||||
					ScannedCves: VulnInfos{
 | 
			
		||||
						"CVE-2017-0001": {
 | 
			
		||||
							CveID: "CVE-2017-0001",
 | 
			
		||||
							AffectedPackages: PackageStatuses{
 | 
			
		||||
							AffectedPackages: PackageFixStatuses{
 | 
			
		||||
								{Name: "kernel"},
 | 
			
		||||
								{Name: "vim"},
 | 
			
		||||
							},
 | 
			
		||||
@@ -704,7 +688,7 @@ func TestIsDisplayUpdatableNum(t *testing.T) {
 | 
			
		||||
		{
 | 
			
		||||
			mode:     []byte{config.Fast},
 | 
			
		||||
			family:   config.FreeBSD,
 | 
			
		||||
			expected: true,
 | 
			
		||||
			expected: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			mode:     []byte{config.Fast},
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -23,60 +6,18 @@ import (
 | 
			
		||||
	cvedict "github.com/kotakanbe/go-cve-dictionary/models"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ConvertNvdXMLToModel convert NVD to CveContent
 | 
			
		||||
func ConvertNvdXMLToModel(cveID string, nvd *cvedict.NvdXML) *CveContent {
 | 
			
		||||
	if nvd == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	var cpes []Cpe
 | 
			
		||||
	for _, c := range nvd.Cpes {
 | 
			
		||||
		cpes = append(cpes, Cpe{
 | 
			
		||||
			FormattedString: c.FormattedString,
 | 
			
		||||
			URI:             c.URI,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var refs []Reference
 | 
			
		||||
	for _, r := range nvd.References {
 | 
			
		||||
		refs = append(refs, Reference{
 | 
			
		||||
			Link:   r.Link,
 | 
			
		||||
			Source: r.Source,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cweIDs := []string{}
 | 
			
		||||
	for _, cid := range nvd.Cwes {
 | 
			
		||||
		cweIDs = append(cweIDs, cid.CweID)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &CveContent{
 | 
			
		||||
		Type:          Nvd,
 | 
			
		||||
		CveID:         cveID,
 | 
			
		||||
		Summary:       nvd.Summary,
 | 
			
		||||
		Cvss2Score:    nvd.Cvss2.BaseScore,
 | 
			
		||||
		Cvss2Vector:   nvd.Cvss2.VectorString,
 | 
			
		||||
		Cvss2Severity: nvd.Cvss2.Severity,
 | 
			
		||||
		SourceLink:    "https://nvd.nist.gov/vuln/detail/" + cveID,
 | 
			
		||||
		// Cpes:          cpes,
 | 
			
		||||
		CweIDs:       cweIDs,
 | 
			
		||||
		References:   refs,
 | 
			
		||||
		Published:    nvd.PublishedDate,
 | 
			
		||||
		LastModified: nvd.LastModifiedDate,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ConvertJvnToModel convert JVN to CveContent
 | 
			
		||||
func ConvertJvnToModel(cveID string, jvn *cvedict.Jvn) *CveContent {
 | 
			
		||||
	if jvn == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	var cpes []Cpe
 | 
			
		||||
	for _, c := range jvn.Cpes {
 | 
			
		||||
		cpes = append(cpes, Cpe{
 | 
			
		||||
			FormattedString: c.FormattedString,
 | 
			
		||||
			URI:             c.URI,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	// var cpes = []Cpe{}
 | 
			
		||||
	// for _, c := range jvn.Cpes {
 | 
			
		||||
	// 	cpes = append(cpes, Cpe{
 | 
			
		||||
	// 		FormattedString: c.FormattedString,
 | 
			
		||||
	// 		URI:             c.URI,
 | 
			
		||||
	// 	})
 | 
			
		||||
	// }
 | 
			
		||||
 | 
			
		||||
	refs := []Reference{}
 | 
			
		||||
	for _, r := range jvn.References {
 | 
			
		||||
@@ -110,15 +51,15 @@ func ConvertNvdJSONToModel(cveID string, nvd *cvedict.NvdJSON) *CveContent {
 | 
			
		||||
	if nvd == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	var cpes []Cpe
 | 
			
		||||
	for _, c := range nvd.Cpes {
 | 
			
		||||
		cpes = append(cpes, Cpe{
 | 
			
		||||
			FormattedString: c.FormattedString,
 | 
			
		||||
			URI:             c.URI,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	// var cpes = []Cpe{}
 | 
			
		||||
	// for _, c := range nvd.Cpes {
 | 
			
		||||
	// 	cpes = append(cpes, Cpe{
 | 
			
		||||
	// 		FormattedString: c.FormattedString,
 | 
			
		||||
	// 		URI:             c.URI,
 | 
			
		||||
	// 	})
 | 
			
		||||
	// }
 | 
			
		||||
 | 
			
		||||
	var refs []Reference
 | 
			
		||||
	var refs = []Reference{}
 | 
			
		||||
	for _, r := range nvd.References {
 | 
			
		||||
		refs = append(refs, Reference{
 | 
			
		||||
			Link:   r.Link,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -24,8 +7,6 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/future-architect/vuls/alert"
 | 
			
		||||
 | 
			
		||||
	"github.com/future-architect/vuls/config"
 | 
			
		||||
	exploitmodels "github.com/mozqnet/go-exploitdb/models"
 | 
			
		||||
)
 | 
			
		||||
@@ -115,27 +96,26 @@ func (v VulnInfos) FormatFixedStatus(packs Packages) string {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		total++
 | 
			
		||||
		if vInfo.PatchStatus(packs) == "Fixed" {
 | 
			
		||||
		if vInfo.PatchStatus(packs) == "fixed" {
 | 
			
		||||
			fixed++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("%d/%d Fixed", fixed, total)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PackageStatuses is a list of PackageStatus
 | 
			
		||||
type PackageStatuses []PackageStatus
 | 
			
		||||
// PackageFixStatuses is a list of PackageStatus
 | 
			
		||||
type PackageFixStatuses []PackageFixStatus
 | 
			
		||||
 | 
			
		||||
// FormatTuiSummary format packname to show TUI summary
 | 
			
		||||
func (ps PackageStatuses) FormatTuiSummary() string {
 | 
			
		||||
	names := []string{}
 | 
			
		||||
// Names return a slice of package names
 | 
			
		||||
func (ps PackageFixStatuses) Names() (names []string) {
 | 
			
		||||
	for _, p := range ps {
 | 
			
		||||
		names = append(names, p.Name)
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(names, ", ")
 | 
			
		||||
	return names
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Store insert given pkg if missing, update pkg if exists
 | 
			
		||||
func (ps PackageStatuses) Store(pkg PackageStatus) PackageStatuses {
 | 
			
		||||
func (ps PackageFixStatuses) Store(pkg PackageFixStatus) PackageFixStatuses {
 | 
			
		||||
	for i, p := range ps {
 | 
			
		||||
		if p.Name == pkg.Name {
 | 
			
		||||
			ps[i] = pkg
 | 
			
		||||
@@ -147,38 +127,50 @@ func (ps PackageStatuses) Store(pkg PackageStatus) PackageStatuses {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sort by Name
 | 
			
		||||
func (ps PackageStatuses) Sort() {
 | 
			
		||||
func (ps PackageFixStatuses) Sort() {
 | 
			
		||||
	sort.Slice(ps, func(i, j int) bool {
 | 
			
		||||
		return ps[i].Name < ps[j].Name
 | 
			
		||||
	})
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PackageStatus has name and other status abount the package
 | 
			
		||||
type PackageStatus struct {
 | 
			
		||||
	Name        string `json:"name"`
 | 
			
		||||
	NotFixedYet bool   `json:"notFixedYet"`
 | 
			
		||||
	FixState    string `json:"fixState"`
 | 
			
		||||
// PackageFixStatus has name and other status abount the package
 | 
			
		||||
type PackageFixStatus struct {
 | 
			
		||||
	Name        string `json:"name,omitempty"`
 | 
			
		||||
	NotFixedYet bool   `json:"notFixedYet,omitempty"`
 | 
			
		||||
	FixState    string `json:"fixState,omitempty"`
 | 
			
		||||
	FixedIn     string `json:"fixedIn,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// VulnInfo has a vulnerability information and unsecure packages
 | 
			
		||||
type VulnInfo struct {
 | 
			
		||||
	CveID            string           `json:"cveID,omitempty"`
 | 
			
		||||
	Confidences      Confidences      `json:"confidences,omitempty"`
 | 
			
		||||
	AffectedPackages PackageStatuses  `json:"affectedPackages,omitempty"`
 | 
			
		||||
	DistroAdvisories []DistroAdvisory `json:"distroAdvisories,omitempty"` // for Aamazon, RHEL, FreeBSD
 | 
			
		||||
	CveContents      CveContents      `json:"cveContents,omitempty"`
 | 
			
		||||
	Exploits         []Exploit        `json:"exploits,omitempty"`
 | 
			
		||||
	AlertDict        AlertDict        `json:"alertDict,omitempty"`
 | 
			
		||||
 | 
			
		||||
	CveID                string               `json:"cveID,omitempty"`
 | 
			
		||||
	Confidences          Confidences          `json:"confidences,omitempty"`
 | 
			
		||||
	AffectedPackages     PackageFixStatuses   `json:"affectedPackages,omitempty"`
 | 
			
		||||
	DistroAdvisories     DistroAdvisories     `json:"distroAdvisories,omitempty"` // for Aamazon, RHEL, FreeBSD
 | 
			
		||||
	CveContents          CveContents          `json:"cveContents,omitempty"`
 | 
			
		||||
	Exploits             []Exploit            `json:"exploits,omitempty"`
 | 
			
		||||
	Metasploits          []Metasploit         `json:"metasploits,omitempty"`
 | 
			
		||||
	AlertDict            AlertDict            `json:"alertDict,omitempty"`
 | 
			
		||||
	CpeURIs              []string             `json:"cpeURIs,omitempty"` // CpeURIs related to this CVE defined in config.toml
 | 
			
		||||
	GitHubSecurityAlerts GitHubSecurityAlerts `json:"gitHubSecurityAlerts,omitempty"`
 | 
			
		||||
	WpPackageFixStats    WpPackageFixStats    `json:"wpPackageFixStats,omitempty"`
 | 
			
		||||
	LibraryFixedIns      LibraryFixedIns      `json:"libraryFixedIns,omitempty"`
 | 
			
		||||
 | 
			
		||||
	VulnType string `json:"vulnType,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Alert has XCERT alert information
 | 
			
		||||
type Alert struct {
 | 
			
		||||
	URL   string `json:"url,omitempty"`
 | 
			
		||||
	Title string `json:"title,omitempty"`
 | 
			
		||||
	Team  string `json:"team,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GitHubSecurityAlerts is a list of GitHubSecurityAlert
 | 
			
		||||
type GitHubSecurityAlerts []GitHubSecurityAlert
 | 
			
		||||
 | 
			
		||||
// Add adds given arg to the slice and return the slice (imutable)
 | 
			
		||||
// Add adds given arg to the slice and return the slice (immutable)
 | 
			
		||||
func (g GitHubSecurityAlerts) Add(alert GitHubSecurityAlert) GitHubSecurityAlerts {
 | 
			
		||||
	for _, a := range g {
 | 
			
		||||
		if a.PackageName == alert.PackageName {
 | 
			
		||||
@@ -188,12 +180,12 @@ func (g GitHubSecurityAlerts) Add(alert GitHubSecurityAlert) GitHubSecurityAlert
 | 
			
		||||
	return append(g, alert)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g GitHubSecurityAlerts) String() string {
 | 
			
		||||
	ss := []string{}
 | 
			
		||||
// Names return a slice of lib names
 | 
			
		||||
func (g GitHubSecurityAlerts) Names() (names []string) {
 | 
			
		||||
	for _, a := range g {
 | 
			
		||||
		ss = append(ss, a.PackageName)
 | 
			
		||||
		names = append(names, a.PackageName)
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(ss, ", ")
 | 
			
		||||
	return names
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GitHubSecurityAlert has detected CVE-ID, PackageName, Status fetched via GitHub API
 | 
			
		||||
@@ -206,6 +198,41 @@ type GitHubSecurityAlert struct {
 | 
			
		||||
	DismissReason string    `json:"dismissReason"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LibraryFixedIns is a list of Library's FixedIn
 | 
			
		||||
type LibraryFixedIns []LibraryFixedIn
 | 
			
		||||
 | 
			
		||||
// Names return a slice of names
 | 
			
		||||
func (lfs LibraryFixedIns) Names() (names []string) {
 | 
			
		||||
	for _, lf := range lfs {
 | 
			
		||||
		names = append(names, lf.Name)
 | 
			
		||||
	}
 | 
			
		||||
	return names
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WpPackageFixStats is a list of WpPackageFixStatus
 | 
			
		||||
type WpPackageFixStats []WpPackageFixStatus
 | 
			
		||||
 | 
			
		||||
// Names return a slice of names
 | 
			
		||||
func (ws WpPackageFixStats) Names() (names []string) {
 | 
			
		||||
	for _, w := range ws {
 | 
			
		||||
		names = append(names, w.Name)
 | 
			
		||||
	}
 | 
			
		||||
	return names
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WpPackages has a list of WpPackage
 | 
			
		||||
type WpPackages []WpPackage
 | 
			
		||||
 | 
			
		||||
// Add adds given arg to the slice and return the slice (immutable)
 | 
			
		||||
func (g WpPackages) Add(pkg WpPackage) WpPackages {
 | 
			
		||||
	for _, a := range g {
 | 
			
		||||
		if a.Name == pkg.Name {
 | 
			
		||||
			return g
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return append(g, pkg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Titles returns tilte (TUI)
 | 
			
		||||
func (v VulnInfo) Titles(lang, myFamily string) (values []CveContentStr) {
 | 
			
		||||
	if lang == "ja" {
 | 
			
		||||
@@ -219,7 +246,7 @@ func (v VulnInfo) Titles(lang, myFamily string) (values []CveContentStr) {
 | 
			
		||||
		values = append(values, CveContentStr{RedHatAPI, cont.Title})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	order := CveContentTypes{Nvd, NvdXML, NewCveContentType(myFamily)}
 | 
			
		||||
	order := CveContentTypes{Trivy, Nvd, NvdXML, NewCveContentType(myFamily)}
 | 
			
		||||
	order = append(order, AllCveContetTypes.Except(append(order, Jvn)...)...)
 | 
			
		||||
	for _, ctype := range order {
 | 
			
		||||
		// Only JVN has meaningful title. so return first 100 char of summary
 | 
			
		||||
@@ -259,7 +286,7 @@ func (v VulnInfo) Summaries(lang, myFamily string) (values []CveContentStr) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	order := CveContentTypes{Nvd, NvdXML, NewCveContentType(myFamily)}
 | 
			
		||||
	order := CveContentTypes{Trivy, NewCveContentType(myFamily), Nvd, NvdXML}
 | 
			
		||||
	order = append(order, AllCveContetTypes.Except(append(order, Jvn)...)...)
 | 
			
		||||
	for _, ctype := range order {
 | 
			
		||||
		if cont, found := v.CveContents[ctype]; found && 0 < len(cont.Summary) {
 | 
			
		||||
@@ -278,6 +305,13 @@ func (v VulnInfo) Summaries(lang, myFamily string) (values []CveContentStr) {
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if v, ok := v.CveContents[WPVulnDB]; ok {
 | 
			
		||||
		values = append(values, CveContentStr{
 | 
			
		||||
			Type:  "WPVDB",
 | 
			
		||||
			Value: v.Title,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(values) == 0 {
 | 
			
		||||
		return []CveContentStr{{
 | 
			
		||||
			Type:  Unknown,
 | 
			
		||||
@@ -317,7 +351,7 @@ func (v VulnInfo) Cvss2Scores(myFamily string) (values []CveContentCvss) {
 | 
			
		||||
	}
 | 
			
		||||
	for _, ctype := range order {
 | 
			
		||||
		if cont, found := v.CveContents[ctype]; found {
 | 
			
		||||
			if cont.Cvss2Score == 0 && cont.Cvss2Severity == "" {
 | 
			
		||||
			if cont.Cvss2Score == 0 || cont.Cvss2Severity == "" {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			// https://nvd.nist.gov/vuln-metrics/cvss
 | 
			
		||||
@@ -390,6 +424,18 @@ func (v VulnInfo) Cvss3Scores() (values []CveContentCvss) {
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if cont, found := v.CveContents[Trivy]; found && cont.Cvss3Severity != "" {
 | 
			
		||||
		values = append(values, CveContentCvss{
 | 
			
		||||
			Type: Trivy,
 | 
			
		||||
			Value: Cvss{
 | 
			
		||||
				Type:     CVSS3,
 | 
			
		||||
				Score:    severityToV2ScoreRoughly(cont.Cvss3Severity),
 | 
			
		||||
				Severity: strings.ToUpper(cont.Cvss3Severity),
 | 
			
		||||
			},
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -510,16 +556,17 @@ func (v VulnInfo) MaxCvss2Score() CveContentCvss {
 | 
			
		||||
func (v VulnInfo) AttackVector() string {
 | 
			
		||||
	for _, cnt := range v.CveContents {
 | 
			
		||||
		if strings.HasPrefix(cnt.Cvss2Vector, "AV:N") ||
 | 
			
		||||
			strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:N") {
 | 
			
		||||
			return "Network"
 | 
			
		||||
			strings.Contains(cnt.Cvss3Vector, "AV:N") {
 | 
			
		||||
			return "AV:N"
 | 
			
		||||
		} else if strings.HasPrefix(cnt.Cvss2Vector, "AV:A") ||
 | 
			
		||||
			strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:A") {
 | 
			
		||||
			return "Adjacent"
 | 
			
		||||
			strings.Contains(cnt.Cvss3Vector, "AV:A") {
 | 
			
		||||
			return "AV:A"
 | 
			
		||||
		} else if strings.HasPrefix(cnt.Cvss2Vector, "AV:L") ||
 | 
			
		||||
			strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:L") {
 | 
			
		||||
			return "Local"
 | 
			
		||||
		} else if strings.HasPrefix(cnt.Cvss3Vector, "CVSS:3.0/AV:P") {
 | 
			
		||||
			return "Physical"
 | 
			
		||||
			strings.Contains(cnt.Cvss3Vector, "AV:L") {
 | 
			
		||||
			return "AV:L"
 | 
			
		||||
		} else if strings.Contains(cnt.Cvss3Vector, "AV:P") {
 | 
			
		||||
			// no AV:P in CVSS v2
 | 
			
		||||
			return "AV:P"
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if cont, found := v.CveContents[DebianSecurityTracker]; found {
 | 
			
		||||
@@ -530,7 +577,7 @@ func (v VulnInfo) AttackVector() string {
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PatchStatus returns attack vector string
 | 
			
		||||
// PatchStatus returns fixed or unfixed string
 | 
			
		||||
func (v VulnInfo) PatchStatus(packs Packages) string {
 | 
			
		||||
	// Vuls don't know patch status of the CPE
 | 
			
		||||
	if len(v.CpeURIs) != 0 {
 | 
			
		||||
@@ -538,17 +585,24 @@ func (v VulnInfo) PatchStatus(packs Packages) string {
 | 
			
		||||
	}
 | 
			
		||||
	for _, p := range v.AffectedPackages {
 | 
			
		||||
		if p.NotFixedYet {
 | 
			
		||||
			return "Unfixed"
 | 
			
		||||
			return "unfixed"
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Fast and offline mode can not get the candidate version.
 | 
			
		||||
		// Vuls can be considered as 'fixed' if not-fixed-yet==true and
 | 
			
		||||
		// the fixed-in-version (information in the oval) is not an empty.
 | 
			
		||||
		if p.FixedIn != "" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// fast, offline mode doesn't have new version
 | 
			
		||||
		if pack, ok := packs[p.Name]; ok {
 | 
			
		||||
			if pack.NewVersion == "" {
 | 
			
		||||
				return "Unknown"
 | 
			
		||||
				return "unknown"
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return "Fixed"
 | 
			
		||||
	return "fixed"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CveContentCvss has CVSS information
 | 
			
		||||
@@ -591,15 +645,6 @@ func (c Cvss) Format() string {
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func cvss2ScoreToSeverity(score float64) string {
 | 
			
		||||
	if 7.0 <= score {
 | 
			
		||||
		return "HIGH"
 | 
			
		||||
	} else if 4.0 <= score {
 | 
			
		||||
		return "MEDIUM"
 | 
			
		||||
	}
 | 
			
		||||
	return "LOW"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Amazon Linux Security Advisory
 | 
			
		||||
// Critical, Important, Medium, Low
 | 
			
		||||
// https://alas.aws.amazon.com/
 | 
			
		||||
@@ -648,6 +693,12 @@ func (v VulnInfo) Cvss3CalcURL() string {
 | 
			
		||||
// VendorLinks returns links of vendor support's URL
 | 
			
		||||
func (v VulnInfo) VendorLinks(family string) map[string]string {
 | 
			
		||||
	links := map[string]string{}
 | 
			
		||||
	if strings.HasPrefix(v.CveID, "WPVDBID") {
 | 
			
		||||
		links["WPVulnDB"] = fmt.Sprintf("https://wpvulndb.com/vulnerabilities/%s",
 | 
			
		||||
			strings.TrimPrefix(v.CveID, "WPVDBID-"))
 | 
			
		||||
		return links
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch family {
 | 
			
		||||
	case config.RedHat, config.CentOS:
 | 
			
		||||
		links["RHEL-CVE"] = "https://access.redhat.com/security/cve/" + v.CveID
 | 
			
		||||
@@ -666,8 +717,14 @@ func (v VulnInfo) VendorLinks(family string) map[string]string {
 | 
			
		||||
	case config.Amazon:
 | 
			
		||||
		links["RHEL-CVE"] = "https://access.redhat.com/security/cve/" + v.CveID
 | 
			
		||||
		for _, advisory := range v.DistroAdvisories {
 | 
			
		||||
			links[advisory.AdvisoryID] =
 | 
			
		||||
				fmt.Sprintf("https://alas.aws.amazon.com/%s.html", advisory.AdvisoryID)
 | 
			
		||||
			if strings.HasPrefix(advisory.AdvisoryID, "ALAS2") {
 | 
			
		||||
				links[advisory.AdvisoryID] =
 | 
			
		||||
					fmt.Sprintf("https://alas.aws.amazon.com/AL2/%s.html",
 | 
			
		||||
						strings.Replace(advisory.AdvisoryID, "ALAS2", "ALAS", -1))
 | 
			
		||||
			} else {
 | 
			
		||||
				links[advisory.AdvisoryID] =
 | 
			
		||||
					fmt.Sprintf("https://alas.aws.amazon.com/%s.html", advisory.AdvisoryID)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return links
 | 
			
		||||
	case config.Ubuntu:
 | 
			
		||||
@@ -687,6 +744,20 @@ func (v VulnInfo) VendorLinks(family string) map[string]string {
 | 
			
		||||
	return links
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DistroAdvisories is a list of DistroAdvisory
 | 
			
		||||
type DistroAdvisories []DistroAdvisory
 | 
			
		||||
 | 
			
		||||
// AppendIfMissing appends if missing
 | 
			
		||||
func (advs *DistroAdvisories) AppendIfMissing(adv *DistroAdvisory) bool {
 | 
			
		||||
	for _, a := range *advs {
 | 
			
		||||
		if a.AdvisoryID == adv.AdvisoryID {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	*advs = append(*advs, *adv)
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DistroAdvisory has Amazon Linux, RHEL, FreeBSD Security Advisory information.
 | 
			
		||||
type DistroAdvisory struct {
 | 
			
		||||
	AdvisoryID  string    `json:"advisoryID"`
 | 
			
		||||
@@ -721,15 +792,18 @@ type Exploit struct {
 | 
			
		||||
	BinaryURL    *string                   `json:"binaryURL,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AlertDict has target cve's JPCERT and USCERT alert data
 | 
			
		||||
type AlertDict struct {
 | 
			
		||||
	Ja []alert.Alert `json:"ja"`
 | 
			
		||||
	En []alert.Alert `json:"en"`
 | 
			
		||||
// Metasploit :
 | 
			
		||||
type Metasploit struct {
 | 
			
		||||
	Name        string   `json:"name"`
 | 
			
		||||
	Title       string   `json:"title"`
 | 
			
		||||
	Description string   `json:"description,omitempty"`
 | 
			
		||||
	URLs        []string `json:",omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HasAlert returns whether or not it has En or Ja entries.
 | 
			
		||||
func (a AlertDict) HasAlert() bool {
 | 
			
		||||
	return len(a.En) != 0 || len(a.Ja) != 0
 | 
			
		||||
// AlertDict has target cve's JPCERT and USCERT alert data
 | 
			
		||||
type AlertDict struct {
 | 
			
		||||
	Ja []Alert `json:"ja"`
 | 
			
		||||
	En []Alert `json:"en"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FormatSource returns which source has this alert
 | 
			
		||||
@@ -801,6 +875,9 @@ const (
 | 
			
		||||
	// DebianSecurityTrackerMatchStr is a String representation of DebianSecurityTrackerMatch
 | 
			
		||||
	DebianSecurityTrackerMatchStr = "DebianSecurityTrackerMatch"
 | 
			
		||||
 | 
			
		||||
	// TrivyMatchStr is a String representation of Trivy
 | 
			
		||||
	TrivyMatchStr = "TrivyMatch"
 | 
			
		||||
 | 
			
		||||
	// ChangelogExactMatchStr is a String representation of ChangelogExactMatch
 | 
			
		||||
	ChangelogExactMatchStr = "ChangelogExactMatch"
 | 
			
		||||
 | 
			
		||||
@@ -810,6 +887,9 @@ const (
 | 
			
		||||
	// GitHubMatchStr is a String representation of GitHubMatch
 | 
			
		||||
	GitHubMatchStr = "GitHubMatch"
 | 
			
		||||
 | 
			
		||||
	// WPVulnDBMatchStr is a String representation of WordPress VulnDB scanning
 | 
			
		||||
	WPVulnDBMatchStr = "WPVulnDBMatch"
 | 
			
		||||
 | 
			
		||||
	// FailedToGetChangelog is a String representation of FailedToGetChangelog
 | 
			
		||||
	FailedToGetChangelog = "FailedToGetChangelog"
 | 
			
		||||
 | 
			
		||||
@@ -836,6 +916,9 @@ var (
 | 
			
		||||
	// DebianSecurityTrackerMatch ranking how confident the CVE-ID was deteted correctly
 | 
			
		||||
	DebianSecurityTrackerMatch = Confidence{100, DebianSecurityTrackerMatchStr, 0}
 | 
			
		||||
 | 
			
		||||
	// TrivyMatch ranking how confident the CVE-ID was deteted correctly
 | 
			
		||||
	TrivyMatch = Confidence{100, TrivyMatchStr, 0}
 | 
			
		||||
 | 
			
		||||
	// ChangelogExactMatch is a ranking how confident the CVE-ID was deteted correctly
 | 
			
		||||
	ChangelogExactMatch = Confidence{95, ChangelogExactMatchStr, 3}
 | 
			
		||||
 | 
			
		||||
@@ -844,4 +927,7 @@ var (
 | 
			
		||||
 | 
			
		||||
	// GitHubMatch is a ranking how confident the CVE-ID was deteted correctly
 | 
			
		||||
	GitHubMatch = Confidence{97, GitHubMatchStr, 2}
 | 
			
		||||
 | 
			
		||||
	// WPVulnDBMatch is a ranking how confident the CVE-ID was deteted correctly
 | 
			
		||||
	WPVulnDBMatch = Confidence{100, WPVulnDBMatchStr, 0}
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,3 @@
 | 
			
		||||
/* Vuls - Vulnerability Scanner
 | 
			
		||||
Copyright (C) 2016  Future Corporation , Japan.
 | 
			
		||||
 | 
			
		||||
This program is free software: you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License
 | 
			
		||||
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
@@ -159,14 +143,14 @@ func TestSummaries(t *testing.T) {
 | 
			
		||||
					Type:  Jvn,
 | 
			
		||||
					Value: "Title JVN\nSummary JVN",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					Type:  NvdXML,
 | 
			
		||||
					Value: "Summary NVD",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					Type:  RedHat,
 | 
			
		||||
					Value: "Summary RedHat",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					Type:  NvdXML,
 | 
			
		||||
					Value: "Summary NVD",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		// lang: en
 | 
			
		||||
@@ -193,14 +177,14 @@ func TestSummaries(t *testing.T) {
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			out: []CveContentStr{
 | 
			
		||||
				{
 | 
			
		||||
					Type:  NvdXML,
 | 
			
		||||
					Value: "Summary NVD",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					Type:  RedHat,
 | 
			
		||||
					Value: "Summary RedHat",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					Type:  NvdXML,
 | 
			
		||||
					Value: "Summary NVD",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		// lang: empty
 | 
			
		||||
@@ -916,15 +900,15 @@ func TestFormatMaxCvssScore(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
func TestSortPackageStatues(t *testing.T) {
 | 
			
		||||
	var tests = []struct {
 | 
			
		||||
		in  PackageStatuses
 | 
			
		||||
		out PackageStatuses
 | 
			
		||||
		in  PackageFixStatuses
 | 
			
		||||
		out PackageFixStatuses
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			in: PackageStatuses{
 | 
			
		||||
			in: PackageFixStatuses{
 | 
			
		||||
				{Name: "b"},
 | 
			
		||||
				{Name: "a"},
 | 
			
		||||
			},
 | 
			
		||||
			out: PackageStatuses{
 | 
			
		||||
			out: PackageFixStatuses{
 | 
			
		||||
				{Name: "a"},
 | 
			
		||||
				{Name: "b"},
 | 
			
		||||
			},
 | 
			
		||||
@@ -940,19 +924,19 @@ func TestSortPackageStatues(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
func TestStorePackageStatueses(t *testing.T) {
 | 
			
		||||
	var tests = []struct {
 | 
			
		||||
		pkgstats PackageStatuses
 | 
			
		||||
		in       PackageStatus
 | 
			
		||||
		out      PackageStatuses
 | 
			
		||||
		pkgstats PackageFixStatuses
 | 
			
		||||
		in       PackageFixStatus
 | 
			
		||||
		out      PackageFixStatuses
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			pkgstats: PackageStatuses{
 | 
			
		||||
			pkgstats: PackageFixStatuses{
 | 
			
		||||
				{Name: "a"},
 | 
			
		||||
				{Name: "b"},
 | 
			
		||||
			},
 | 
			
		||||
			in: PackageStatus{
 | 
			
		||||
			in: PackageFixStatus{
 | 
			
		||||
				Name: "c",
 | 
			
		||||
			},
 | 
			
		||||
			out: PackageStatuses{
 | 
			
		||||
			out: PackageFixStatuses{
 | 
			
		||||
				{Name: "a"},
 | 
			
		||||
				{Name: "b"},
 | 
			
		||||
				{Name: "c"},
 | 
			
		||||
@@ -1034,3 +1018,148 @@ func TestSortByConfiden(t *testing.T) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestDistroAdvisories_AppendIfMissing(t *testing.T) {
 | 
			
		||||
	type args struct {
 | 
			
		||||
		adv *DistroAdvisory
 | 
			
		||||
	}
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name  string
 | 
			
		||||
		advs  DistroAdvisories
 | 
			
		||||
		args  args
 | 
			
		||||
		want  bool
 | 
			
		||||
		after DistroAdvisories
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "duplicate no append",
 | 
			
		||||
			advs: DistroAdvisories{
 | 
			
		||||
				DistroAdvisory{
 | 
			
		||||
					AdvisoryID: "ALASs-2019-1214",
 | 
			
		||||
				}},
 | 
			
		||||
			args: args{
 | 
			
		||||
				adv: &DistroAdvisory{
 | 
			
		||||
					AdvisoryID: "ALASs-2019-1214",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			want: false,
 | 
			
		||||
			after: DistroAdvisories{
 | 
			
		||||
				DistroAdvisory{
 | 
			
		||||
					AdvisoryID: "ALASs-2019-1214",
 | 
			
		||||
				}},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "append",
 | 
			
		||||
			advs: DistroAdvisories{
 | 
			
		||||
				DistroAdvisory{
 | 
			
		||||
					AdvisoryID: "ALASs-2019-1214",
 | 
			
		||||
				}},
 | 
			
		||||
			args: args{
 | 
			
		||||
				adv: &DistroAdvisory{
 | 
			
		||||
					AdvisoryID: "ALASs-2019-1215",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			want: true,
 | 
			
		||||
			after: DistroAdvisories{
 | 
			
		||||
				{
 | 
			
		||||
					AdvisoryID: "ALASs-2019-1214",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					AdvisoryID: "ALASs-2019-1215",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.name, func(t *testing.T) {
 | 
			
		||||
			if got := tt.advs.AppendIfMissing(tt.args.adv); got != tt.want {
 | 
			
		||||
				t.Errorf("DistroAdvisories.AppendIfMissing() = %v, want %v", got, tt.want)
 | 
			
		||||
			}
 | 
			
		||||
			if !reflect.DeepEqual(tt.advs, tt.after) {
 | 
			
		||||
				t.Errorf("\nexpected: %v\n  actual: %v\n", tt.after, tt.advs)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestVulnInfo_AttackVector(t *testing.T) {
 | 
			
		||||
	type fields struct {
 | 
			
		||||
		CveContents CveContents
 | 
			
		||||
	}
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name   string
 | 
			
		||||
		fields fields
 | 
			
		||||
		want   string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "2.0:N",
 | 
			
		||||
			fields: fields{
 | 
			
		||||
				CveContents: NewCveContents(
 | 
			
		||||
					CveContent{
 | 
			
		||||
						Type:        "foo",
 | 
			
		||||
						Cvss2Vector: "AV:N/AC:L/Au:N/C:C/I:C/A:C",
 | 
			
		||||
					},
 | 
			
		||||
				),
 | 
			
		||||
			},
 | 
			
		||||
			want: "AV:N",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "2.0:A",
 | 
			
		||||
			fields: fields{
 | 
			
		||||
				CveContents: NewCveContents(
 | 
			
		||||
					CveContent{
 | 
			
		||||
						Type:        "foo",
 | 
			
		||||
						Cvss2Vector: "AV:A/AC:L/Au:N/C:C/I:C/A:C",
 | 
			
		||||
					},
 | 
			
		||||
				),
 | 
			
		||||
			},
 | 
			
		||||
			want: "AV:A",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "2.0:L",
 | 
			
		||||
			fields: fields{
 | 
			
		||||
				CveContents: NewCveContents(
 | 
			
		||||
					CveContent{
 | 
			
		||||
						Type:        "foo",
 | 
			
		||||
						Cvss2Vector: "AV:L/AC:L/Au:N/C:C/I:C/A:C",
 | 
			
		||||
					},
 | 
			
		||||
				),
 | 
			
		||||
			},
 | 
			
		||||
			want: "AV:L",
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		{
 | 
			
		||||
			name: "3.0:N",
 | 
			
		||||
			fields: fields{
 | 
			
		||||
				CveContents: NewCveContents(
 | 
			
		||||
					CveContent{
 | 
			
		||||
						Type:        "foo",
 | 
			
		||||
						Cvss3Vector: "CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
 | 
			
		||||
					},
 | 
			
		||||
				),
 | 
			
		||||
			},
 | 
			
		||||
			want: "AV:N",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "3.1:N",
 | 
			
		||||
			fields: fields{
 | 
			
		||||
				CveContents: NewCveContents(
 | 
			
		||||
					CveContent{
 | 
			
		||||
						Type:        "foo",
 | 
			
		||||
						Cvss3Vector: "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
 | 
			
		||||
					},
 | 
			
		||||
				),
 | 
			
		||||
			},
 | 
			
		||||
			want: "AV:N",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.name, func(t *testing.T) {
 | 
			
		||||
			v := VulnInfo{
 | 
			
		||||
				CveContents: tt.fields.CveContents,
 | 
			
		||||
			}
 | 
			
		||||
			if got := v.AttackVector(); got != tt.want {
 | 
			
		||||
				t.Errorf("VulnInfo.AttackVector() = %v, want %v", got, tt.want)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										71
									
								
								models/wordpress.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,71 @@
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
// WordPressPackages has Core version, plugins and themes.
 | 
			
		||||
type WordPressPackages []WpPackage
 | 
			
		||||
 | 
			
		||||
// CoreVersion returns the core version of the installed WordPress
 | 
			
		||||
func (w WordPressPackages) CoreVersion() string {
 | 
			
		||||
	for _, p := range w {
 | 
			
		||||
		if p.Type == WPCore {
 | 
			
		||||
			return p.Version
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Plugins returns a slice of plugins of the installed WordPress
 | 
			
		||||
func (w WordPressPackages) Plugins() (ps []WpPackage) {
 | 
			
		||||
	for _, p := range w {
 | 
			
		||||
		if p.Type == WPPlugin {
 | 
			
		||||
			ps = append(ps, p)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Themes returns a slice of themes of the installed WordPress
 | 
			
		||||
func (w WordPressPackages) Themes() (ps []WpPackage) {
 | 
			
		||||
	for _, p := range w {
 | 
			
		||||
		if p.Type == WPTheme {
 | 
			
		||||
			ps = append(ps, p)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Find searches by specified name
 | 
			
		||||
func (w WordPressPackages) Find(name string) (ps *WpPackage, found bool) {
 | 
			
		||||
	for _, p := range w {
 | 
			
		||||
		if p.Name == name {
 | 
			
		||||
			return &p, true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// WPCore is a type `core` in WPPackage struct
 | 
			
		||||
	WPCore = "core"
 | 
			
		||||
	// WPPlugin is a type `plugin` in WPPackage struct
 | 
			
		||||
	WPPlugin = "plugin"
 | 
			
		||||
	// WPTheme is a type `theme` in WPPackage struct
 | 
			
		||||
	WPTheme = "theme"
 | 
			
		||||
 | 
			
		||||
	// Inactive is a inactive status in WPPackage struct
 | 
			
		||||
	Inactive = "inactive"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// WpPackage has a details of plugin and theme
 | 
			
		||||
type WpPackage struct {
 | 
			
		||||
	Name    string `json:"name,omitempty"`
 | 
			
		||||
	Status  string `json:"status,omitempty"` // active, inactive or must-use
 | 
			
		||||
	Update  string `json:"update,omitempty"` // available or none
 | 
			
		||||
	Version string `json:"version,omitempty"`
 | 
			
		||||
	Type    string `json:"type,omitempty"` // core, plugin, theme
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WpPackageFixStatus is used in Vulninfo.WordPress
 | 
			
		||||
type WpPackageFixStatus struct {
 | 
			
		||||
	Name    string `json:"name,omitempty"`
 | 
			
		||||
	FixedIn string `json:"fixedIn,omitempty"`
 | 
			
		||||
}
 | 
			
		||||