Repository: Zjackky/CodeScan
Branch: main
Commit: 17aed7009fb7
Files: 55
Total size: 44.2 KB
Directory structure:
gitextract_srw2u1fm/
├── .idea/
│ ├── .gitignore
│ ├── CodeScan-master.iml
│ └── modules.xml
├── CommonVul/
│ ├── Rce/
│ │ └── Rce.go
│ ├── Rule/
│ │ ├── MatchFileNameRule.go
│ │ ├── MatchFileReadRule.go
│ │ ├── MatchLineRule.go
│ │ ├── MatchPathRule.go
│ │ ├── MatchRceRule.go
│ │ ├── MatchUploadRule.go
│ │ ├── MtachSqlRule.go
│ │ ├── ReStaticVar.go
│ │ └── Utils.go
│ └── Upload/
│ └── Upload_check.go
├── EvilJarList.txt
├── Filter/
│ └── FilterFile.go
├── FilterResult.txt
├── FindFile/
│ ├── Common.go
│ ├── FindFile_Java.go
│ └── FindFile_PHP.go
├── Java-Code/
│ ├── AMF/
│ │ └── AmfCheck.go
│ ├── Auth_Bypass/
│ │ └── Authcheck.go
│ ├── El/
│ │ └── Elcheck.go
│ ├── Fastjson/
│ │ └── parsecheck.go
│ ├── Frame_Analysis/
│ │ └── Frame_Analysiser.go
│ ├── JDBC/
│ │ └── FindJDBC.go
│ ├── JNDI/
│ │ └── Jndi.go
│ ├── JS/
│ │ └── Jseval.go
│ ├── JarStatic/
│ │ └── Jarstaticer.go
│ ├── JavaSrciptShell/
│ │ └── FindJavaSrciptShell.go
│ ├── Log4j/
│ │ └── Log4j2.go
│ ├── ReadObject/
│ │ └── readobject.go
│ ├── Reflect/
│ │ └── Reflect.go
│ ├── SSTI/
│ │ └── FreeMarker/
│ │ └── FreeSsti.go
│ ├── Sql/
│ │ ├── FindSqlByCode.go
│ │ ├── FindSqlByXml.go
│ │ └── Sql.go
│ └── Zip/
│ └── Zipsilp.go
├── PHP-Code/
│ ├── FileRead/
│ │ └── Read.go
│ ├── FileWrite/
│ │ └── Write.go
│ ├── Include/
│ │ └── Include.go
│ ├── PHPSql/
│ │ ├── FindSqlByCode.go
│ │ └── Sql.go
│ ├── SSRF/
│ │ └── SSRF.go
│ └── Unserialize/
│ └── ser.go
├── README.md
├── Utils/
│ ├── JavaScanUtil.go
│ ├── PHPScanUtil.go
│ ├── common.go
│ └── flag.go
├── build.sh
├── go.mod
├── go.sum
├── jarFiles.txt
└── main.go
================================================
FILE CONTENTS
================================================
================================================
FILE: .idea/.gitignore
================================================
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
================================================
FILE: .idea/CodeScan-master.iml
================================================
================================================
FILE: .idea/modules.xml
================================================
================================================
FILE: CommonVul/Rce/Rce.go
================================================
package Rce
import (
"CodeScan/CommonVul/Rule"
"CodeScan/FindFile"
"fmt"
)
func JavaRce(dir string) {
FindFile.FindFileByJava(dir, "rce.txt", Rule.JavaRceRuleList)
fmt.Println("RCE分析完成")
}
func PHPRce(dir string) {
FindFile.FindFileByPHP(dir, "rce.txt", Rule.PHPRceRuleList)
fmt.Println("RCE分析完成")
}
================================================
FILE: CommonVul/Rule/MatchFileNameRule.go
================================================
package Rule
================================================
FILE: CommonVul/Rule/MatchFileReadRule.go
================================================
package Rule
var PHPFileReadList = []string{
"file_get_contents(", "file(", "readfile(", "fopen(",
}
================================================
FILE: CommonVul/Rule/MatchLineRule.go
================================================
package Rule
var LineBlack = []string{
"import ",
"log.",
"loaded from",
"//",
"document.write(",
"getWriter().write(",
"writer.write(",
".write()",
}
================================================
FILE: CommonVul/Rule/MatchPathRule.go
================================================
package Rule
var PathBlackJava = []string{
"apache", "lombok", "microsoft", "solr",
"amazonaws", "c3p0", "jodd", "afterturn", "hutool",
"javassist", "alibaba", "aliyuncs", "javax", "jackson",
"bytebuddy", "baomidou", "google", "netty", "redis", "mysql",
"logback", "ognl", "oracle", "sun", "junit", "reactor", "github",
"mchange", "taobao", "nimbusds", "opensymphony", "freemarker", "java", "apiguardian", "hibernate", "javassist", "jboss", "junit", "mybatis",
"springframework", "slf4j", "aspectj",
}
var PathBlackPhp = []string{
"think", "vendor",
}
================================================
FILE: CommonVul/Rule/MatchRceRule.go
================================================
package Rule
var JavaRceRuleList = []string{
"Runtime.getRuntime().exec", "ProcessBuilder.start",
"RuntimeUtil.exec(", "RuntimeUtil.execForStr(",
}
var PHPRceRuleList = []string{
"System(", "shell_exec(", "exec(", "eval(", "passthru(", "proc_open(", "popen(",
"assert(", "call_user_func(", "call_user_func_array(", "create_function(",
}
================================================
FILE: CommonVul/Rule/MatchUploadRule.go
================================================
package Rule
var JavaUploadRuleList = []string{
"Streams.copy(",
".getOriginalFilename(", ".transferTo(",
"UploadedFile(", "FileUtils.copyFile(", "MultipartHttpServletRequest", ".getFileName(", ".saveAs(", ".getFileSuffix(", ".getFile", "MultipartFile file",
}
var PHPUploadRuleList = []string{
"move_uploaded_file(", "file_put_contents(", "$_FILE[", "copy(", "->move(", "request()->file(",
}
================================================
FILE: CommonVul/Rule/MtachSqlRule.go
================================================
package Rule
var XmlSqlBlack = []string{
"", "id=\"dataSource\"", "", "",
" 0 {
writeToFile("sql.txt", selectList)
}
}
================================================
FILE: Java-Code/Sql/FindSqlByXml.go
================================================
package Sql
import (
Rule2 "CodeScan/CommonVul/Rule"
"bufio"
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
)
// findKeywordsInXMLFiles 函数用于检查 XML 文件中的关键字
func findSqlByXml(dir string) {
xmlList := []string{}
var lastFile string // 记录上一次输出的文件,用于控制输出格式
// 使用 Walk 函数遍历目录,查找所有的 .xml 文件
err := filepath.Walk(dir, func(path string, f fs.FileInfo, err error) error {
if !f.IsDir() && strings.HasSuffix(f.Name(), ".xml") {
// xml黑名单匹配
if Rule2.MatchRule(f.Name(), Rule2.XmlBlack) {
return nil
}
xmlList = append(xmlList, path)
}
return nil
})
check(err)
// 定义需要搜索的关键字
keywords := []string{"${", "like '%${", "order by ${"} // 这里可以添加更多关键字
// 遍历 XML 文件列表
for _, file := range xmlList {
foundKeywords := []string{}
lineNumber := 1
// 打开 XML 文件
f, err := os.Open(file)
check(err)
defer f.Close()
// 逐行扫描文件内容
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
// 检查每一行是否包含关键字,并且不包含黑名单中的关键字
if Rule2.MatchRule(line, Rule2.XmlSqlBlack) {
continue
}
// 检查每一行是否包含需要搜索的关键字
for _, keyword := range keywords {
if strings.Contains(line, keyword) {
if lastFile != f.Name() {
foundKeywords = append(foundKeywords, fmt.Sprintf("====================================================================\n"))
foundKeywords = append(foundKeywords, fmt.Sprintf("file [%s]\n%d: %s", f.Name(), lineNumber, line))
lastFile = f.Name()
} else {
foundKeywords = append(foundKeywords, fmt.Sprintf("====================================================================\n"))
foundKeywords = append(foundKeywords, fmt.Sprintf("%d : %s", lineNumber, line))
}
}
}
lineNumber++
}
// 如果找到关键字,则将相关信息写入到 sql.txt 文件中
if len(foundKeywords) > 0 {
writeToFile("sql.txt", foundKeywords)
}
}
}
================================================
FILE: Java-Code/Sql/Sql.go
================================================
package Sql
import (
"fmt"
"os"
)
// check 函数用于检查错误,如果错误不为 nil 则触发 panic
func check(e error) {
if e != nil {
panic(e)
}
}
// Sqlcheck 函数是我们的主函数,负责执行 SQL 检查的逻辑
func Sqlcheck(dir string) {
// 检查是否存在 @Select 注解
findSqlByCode(dir)
// 检查 XML 文件中的关键字
findSqlByXml(dir)
fmt.Println("sql分析完成")
}
// writeToFile 函数用于将信息写入文件
func writeToFile(filename string, lines []string) {
// 创建或打开输出文件,以追加模式写入
basedir := "./results/"
// 检查目录是否存在
if _, err := os.Stat(basedir); os.IsNotExist(err) {
// 如果目录不存在,则创建
err := os.MkdirAll(basedir, os.ModePerm)
if err != nil {
fmt.Println("Error creating directory:", err)
return
}
}
outputfile := basedir + filename // 打开文件,如果文件不存在则创建,如果存在则追加写入
outputFile, err := os.OpenFile(outputfile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
check(err)
defer outputFile.Close()
// 将每一行信息写入文件
for _, line := range lines {
_, err = outputFile.WriteString(fmt.Sprintf("%s\n", line))
check(err)
}
}
================================================
FILE: Java-Code/Zip/Zipsilp.go
================================================
package Zip
import (
"CodeScan/FindFile"
"fmt"
)
func Zipsilp(dir string) {
FindFile.FindFileByJava(dir, "zip.txt", []string{"zipEntry.getName(", "ZipUtil.unpack(", "ZipUtil.unzip(", "entry.getName()", "AntZipUtils.unzip(", "zip.getEntries()"})
fmt.Println("Zipsilp分析完成")
}
================================================
FILE: PHP-Code/FileRead/Read.go
================================================
package FileRead
import (
"CodeScan/CommonVul/Rule"
"CodeScan/FindFile"
"fmt"
)
func Read(dir string) {
FindFile.FindFileByPHP(dir, "FileRead_Phar.txt", Rule.PHPFileReadList)
fmt.Println("PHP文件读取分析完成")
}
================================================
FILE: PHP-Code/FileWrite/Write.go
================================================
package FileWrite
import (
"CodeScan/FindFile"
"fmt"
)
func Write(dir string) {
FindFile.FindFileByPHP(dir, "FileWrite.txt", []string{
"file_put_contents(",
})
fmt.Println("PHP文件写入分析完成")
}
================================================
FILE: PHP-Code/Include/Include.go
================================================
package Include
import (
"CodeScan/FindFile"
"fmt"
)
func Include(dir string) {
FindFile.FindFileByPHP(dir, "Include.txt", []string{
"include(",
})
fmt.Println("PHP文件包含分析完成")
}
================================================
FILE: PHP-Code/PHPSql/FindSqlByCode.go
================================================
package PHPSql
import (
"bufio"
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
)
// 函数用于检查是否存在java代码内容,并将相关信息写入 sql.txt
func findSqlByCode(dir string) {
selectList := []string{}
var lastFile string // 记录上一次输出的文件,用于控制输出格式
keywords := []string{"like '%\" +", "mysql_query(", "->where(", "->order(", "mysqli_query("}
err := filepath.Walk(dir, func(path string, f fs.FileInfo, err error) error {
if !f.IsDir() && strings.HasSuffix(f.Name(), ".php") {
// 打开文件
lineNumber := 1 // 行号,用于标识匹配行的位置
file, err := os.Open(path)
check(err)
defer file.Close()
// 逐行扫描文件内容
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
// 如果行中包含 @Select 注解,则将相关信息添加到 selectList 中
for _, keyword := range keywords {
if strings.Contains(line, keyword) {
if lastFile != file.Name() {
selectList = append(selectList, fmt.Sprintf("====================================================================\n"))
selectList = append(selectList, fmt.Sprintf("file [%s]\n%d: %s", file.Name(), lineNumber, line))
lastFile = file.Name()
} else {
selectList = append(selectList, fmt.Sprintf("====================================================================\n"))
selectList = append(selectList, fmt.Sprintf("%d : %s", lineNumber, line))
}
}
}
lineNumber++
}
}
return nil
})
check(err)
// 如果存在 @Select 注解,则将相关信息写入到 sql.txt 文件中
if len(selectList) > 0 {
writeToFile("sql.txt", selectList)
}
}
================================================
FILE: PHP-Code/PHPSql/Sql.go
================================================
package PHPSql
import (
"fmt"
"os"
)
// check 函数用于检查错误,如果错误不为 nil 则触发 panic
func check(e error) {
if e != nil {
panic(e)
}
}
// Sqlcheck 函数是我们的主函数,负责执行 SQL 检查的逻辑
func Sqlcheck(dir string) {
// 检查是否存在 @Select 注解
findSqlByCode(dir)
fmt.Println("sql分析完成")
}
// writeToFile 函数用于将信息写入文件
func writeToFile(filename string, lines []string) {
// 打开文件,如果文件不存在则创建,如果存在则追加写入
outputFile, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
check(err)
defer outputFile.Close()
// 将每一行信息写入文件
for _, line := range lines {
_, err = outputFile.WriteString(fmt.Sprintf("%s\n", line))
check(err)
}
}
================================================
FILE: PHP-Code/SSRF/SSRF.go
================================================
package SSRF
import (
"CodeScan/FindFile"
"fmt"
)
func PHP_SSRF(dir string) {
FindFile.FindFileByPHP(dir, "SSRF.txt", []string{
"curl_exec(",
})
fmt.Println("PHPSSRF分析完成")
}
================================================
FILE: PHP-Code/Unserialize/ser.go
================================================
package Unserialize
import (
"CodeScan/FindFile"
"fmt"
)
func Unserialize(dir string) {
FindFile.FindFileByPHP(dir, "Unserialize.txt", []string{
"__destruct(",
})
fmt.Println("PHP反序列化分析完成")
}
================================================
FILE: README.md
================================================
# CodeScan

## 工具概述
该工具目的为对大多数不完整的代码以及依赖快速进行Sink点匹配来帮助红队完成快速代码审计,开发该工具的初衷是以`Sink`到`Source`的思路来开发,为了将所有可疑的Sink点匹配出来并且凭借第六感进行快速漏洞挖掘,并且该工具开发可扩展性强,成本极低,目前工具支持的语言有PHP,Java(JSP)
## 编译
```bash
./build.sh
# 会生成所有版本在releases下
```
## 功能
1. 框架识别
2. 涵盖大部分漏洞的Sink点的匹配(如图)

3. 可自定义定制化修改黑白名单内容
4. 多模块化多语言化代码审计
5. 进行融于鉴权代码的快速匹配抓取
6. 根据Jar进行静态分析(默认分析)
* mysqlconnect-->jdbc
* Xstream --> xml/json
## 使用
```bash
Usage of ./CodeScan_darwin_arm64:
-L string
审计语言
-d string
要扫描的目录
-h string
使用帮助
-lb string
行黑名单
-m string
过滤的字符串
-pb string
路径黑名单
-r string
RCE规则
-u string
文件上传规则
Example:
CodeScan_windows_amd64.exe -L java -d ./net
CodeScan_windows_amd64.exe -L php -d ./net
CodeScan_windows_amd64.exe -d ./net -m "CheckSession.jsp"
```
## 高级用法+案例分析
### 高级用法
`以下均以Java作为示例`
#### 高扩展性
很简单的自定义,如果需要自定义一些匹配规则,首先可以在这里加入

其次如果需要新增漏洞类型,只需要三步(这里以Sql为例)
1. 新建SQL目录
2. 定义一个方法叫 SqlCheck
3. 写一个sqlcheck.txt(生成的文件名) + 你自定义的规则
4. 最后在这里加入包名+方法名即可

```go
package SqlTest
import (
"CodeScan/FindFile"
"fmt"
)
func SqlCheck(dir string) {
FindFile.FindFileByJava(dir, "fastjson.txt", []string{".parseObject("})
fmt.Println("SqlCheck分析完成")
}
```
#### 扫描位置
在打一些闭源代码的时候经常就一个Jar或者Class,反编译的时候会把依赖进行一起反编译,所以为了避免扫描一些依赖的误报,在工具中自带的黑名单中会过滤掉如下黑名单的包名,需要自定义的时候可自行修改,位置在`CommonVul/Rule/MatchPathRule.go`
```go
var PathBlackJava = []string{
"apache", "lombok", "microsoft", "solr",
"amazonaws", "c3p0", "jodd", "afterturn", "hutool",
"javassist", "alibaba", "aliyuncs", "javax", "jackson",
"bytebuddy", "baomidou", "google", "netty", "redis", "mysql",
"logback", "ognl", "oracle", "sun", "junit", "reactor", "github",
"mchange", "taobao", "nimbusds", "opensymphony", "freemarker", "java", "apiguardian", "hibernate", "javassist", "jboss", "junit", "mybatis",
"springframework", "slf4j",
}
```
所以这也导致了一个问题,不能从顶层上直接扫描

`请把CodeScan放在Net同级目录下扫描(否则会忽略掉直接一个Java目录)`
请`-d`后面的参数尽量在`/src/main/java`之后,比如这里就需要把CodeScan放到`net`目录下开始扫描
```bash
CodeScan_windows_amd64.exe -L java -d ./net
```
#### 过滤字符串(只写了JSP + PHP)
比如现在有一个代码百分百为鉴权代码在JSP中
```java
<%@ include file="../../common/js/CheckSession.jsp"%>
```
此时可以用一下功能来进行快速获取未鉴权代码
```bash
CodeScan_windows_amd64.exe -d ./yuan -m "CheckSession.jsp"
```
此时会将不存在这个代码的文件都放到`NoAuthDir`目录中,然后可以再扫一遍就可以立刻定位到存在未鉴权并且存在Sink点的函数文件了
```bash
CodeScan_windows_amd64.exe -L java -d ./NoAuthDir
```
#### 静态分析依赖情况
只需要在CodeScan的目录下放入EvilJarList.txt即可匹配出来
`EvilJarList.txt` 内容为存在可打漏洞的`Jar`,模版如下
```bash
fastjson-1.2.47.jar
resin-4.0.63.jar
jackson-core-2.13.3.jar
c3p0-0.9.5.2.jar
commons-beanutils-1.9.4.jar
commons-beanutils-1.9.3.jar
commons-beanutils-1.9.2.jar
commons-collections-3.2.1.jar
mysql-connector-java-8.0.17.jar
commons-collections4-4.0.jar
shiro-core-1.10.1.jar
aspectjweaver-1.9.5.jar
rome-1.0.jar
xstream-1.4.11.1.jar
sqlite-jdbc-3.8.9.jar
vaadin-server-7.7.14.jar
hessian-4.0.63.jar
```
#### 案例
案例请参考我的博客
```bash
https://zjackky.github.io/post/develop-codescan-zwcz53.html
```
## TODO
* [ ] 将结果从TXT转为Excel
* [ ] Sink点继续完善
* [ ] ASP
## 支持项目
* 如果有师傅发现Bug或者有更好的建议请提issue感谢
* 要是各位师傅通过本人的小工具挖到一些好洞记得回头点点Stars诶
## 免责申明
* 如果您下载、安装、使用、修改本工具及相关代码,即表明您信任本工具
* 在使用本工具时造成对您自己或他人任何形式的损失和伤害,我们不承担任何责任
* 如您在使用本工具的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任
* 请您务必审慎阅读、充分理解各条款内容,特别是免除或者限制责任的条款,并选择接受或不接受
* 除非您已阅读并接受本协议所有条款,否则您无权下载、安装或使用本工具
* 您的下载、安装、使用等行为即视为您已阅读并同意上述协议的约束
## 更新日志
**2024/09/29**
* 开源
**2024/10/7**
* 将扫描结果写入result目录中
## 鸣谢
[xiaoqiuxx(github.com)](https://github.com/xiaoqiuxx)
================================================
FILE: Utils/JavaScanUtil.go
================================================
package Utils
import (
"CodeScan/CommonVul/Rce"
"CodeScan/CommonVul/Upload"
"CodeScan/Java-Code/AMF"
"CodeScan/Java-Code/Auth_Bypass"
"CodeScan/Java-Code/El"
"CodeScan/Java-Code/Fastjson"
"CodeScan/Java-Code/Frame_Analysis"
"CodeScan/Java-Code/JDBC"
"CodeScan/Java-Code/JNDI"
"CodeScan/Java-Code/JS"
"CodeScan/Java-Code/JarStatic"
"CodeScan/Java-Code/JavaSrciptShell"
"CodeScan/Java-Code/Log4j"
"CodeScan/Java-Code/ReadObject"
"CodeScan/Java-Code/Reflect"
"CodeScan/Java-Code/SSTI/FreeMarker"
"CodeScan/Java-Code/Sql"
"CodeScan/Java-Code/Zip"
"github.com/cheggaaa/pb/v3"
"os"
"path/filepath"
"strings"
"sync"
"time"
)
func Java_Codeing() {
StartTime = time.Now()
// 所有要执行的扫描函数
scanFuncs := []func(string){
Frame_Analysis.FrameAnalysiser,
Auth_Bypass.Auth,
Zip.Zipsilp,
JNDI.Jndi,
Sql.Sqlcheck,
Rce.JavaRce,
Upload.JavaUpload_check,
ReadObject.Readobjectcheck,
El.Elcheck,
Fastjson.Parsecheck,
Reflect.ReflectCheck,
Log4j.Log4j,
AMF.AmfCheck,
FreeMarker.FreeSsti,
JDBC.FindJDBC,
JavaSrciptShell.FindJavaSrciptShell,
JarStatic.Jarstaticer,
JS.Eval,
}
var wg sync.WaitGroup
wg.Add(len(scanFuncs)) // 根据方法数量动态调整 goroutine 数量
progressBar = pb.New(len(scanFuncs)).SetRefreshRate(time.Millisecond * 100).Start()
// 启动 goroutine 来执行扫描任务
for _, scanFunc := range scanFuncs {
go scanDirectory(scanFunc, *Dir, &wg)
}
wg.Wait()
progressBar.Finish()
// 处理web.xml
Frame_Analysis.WebXmlScan(*Dir, []string{"*.htm", "*.do", "*.action", "exclude"})
// 清理空文件
root := "./" // 设置要检查的目录
filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && strings.HasSuffix(info.Name(), ".txt") {
if info.Size() == 0 {
os.Remove(path)
}
}
return nil
})
}
================================================
FILE: Utils/PHPScanUtil.go
================================================
package Utils
import (
"CodeScan/CommonVul/Rce"
"CodeScan/CommonVul/Upload"
"CodeScan/PHP-Code/FileRead"
"CodeScan/PHP-Code/Include"
"CodeScan/PHP-Code/PHPSql"
"CodeScan/PHP-Code/SSRF"
"CodeScan/PHP-Code/Unserialize"
"github.com/cheggaaa/pb/v3"
"os"
"path/filepath"
"strings"
"sync"
"time"
)
func PHP_Codeing() {
StartTime = time.Now()
// 所有要执行的扫描函数
scanFuncs := []func(string){
Upload.PHPUpload_check,
Rce.PHPRce,
PHPSql.Sqlcheck,
FileRead.Read,
Unserialize.Unserialize,
SSRF.PHP_SSRF,
Include.Include,
}
var wg sync.WaitGroup
wg.Add(len(scanFuncs)) // 根据方法数量动态调整 goroutine 数量
progressBar = pb.New(len(scanFuncs)).SetRefreshRate(time.Millisecond * 100).Start()
// 启动 goroutine 来执行扫描任务
for _, scanFunc := range scanFuncs {
go scanDirectory(scanFunc, *Dir, &wg)
}
wg.Wait()
progressBar.Finish()
// 清理空文件
root := "./" // 设置要检查的目录
filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && strings.HasSuffix(info.Name(), ".txt") {
if info.Size() == 0 {
os.Remove(path)
}
}
return nil
})
}
================================================
FILE: Utils/common.go
================================================
package Utils
import (
"github.com/cheggaaa/pb/v3"
"strings"
"sync"
"time"
)
var (
progressBar *pb.ProgressBar
StartTime time.Time
)
// scanDirectory 函数用于启动一个 goroutine 来扫描指定目录
func scanDirectory(scanFunc func(string), dir string, wg *sync.WaitGroup) {
scanFunc(dir)
progressBar.Increment()
wg.Done()
}
func ClearDir(dir string) string {
// 将 \ 转换为 /
dir = strings.ReplaceAll(dir, `\\`, "/")
dir = strings.ReplaceAll(dir, `\`, "/")
return dir
}
================================================
FILE: Utils/flag.go
================================================
package Utils
import (
Rule2 "CodeScan/CommonVul/Rule"
"CodeScan/Filter"
"flag"
"fmt"
"github.com/fatih/color"
"strings"
)
var (
Dir *string
language *string
help *string
)
func Start() {
// 开始审计
parseFlag()
*language = strings.ToLower(*language)
if *language == "java" {
Java_Codeing()
}
if *language == "php" {
PHP_Codeing()
}
}
func parseFlag() {
// 高级命令行解析
help = flag.String("h", "", "使用帮助")
Dir = flag.String("d", "", "要扫描的目录")
language = flag.String("L", "", "审计语言")
pathBlackRule := flag.String("pb", "", "路径黑名单")
lineBlackRule := flag.String("lb", "", "行黑名单")
uploadRule := flag.String("u", "", "文件上传规则")
rceRule := flag.String("r", "", "RCE规则")
filterfile := flag.String("m", "", "过滤的字符串")
//outdir := flag.String("o", "", "输出结果")
flag.Parse()
if *language == "" && *filterfile == "" {
color.Red("请使用 -L 选项提供扫描语言")
return
}
if *language != "" {
if *Dir != "" {
*Dir = ClearDir(*Dir)
if *pathBlackRule != "" {
// 读取路径黑名单
Rule2.PathBlackJava = append(Rule2.PathBlackJava, *pathBlackRule)
fmt.Println("路径黑名单:", Rule2.PathBlackJava)
} // 所有要执行的扫描函数
if *lineBlackRule != "" {
Rule2.LineBlack = append(Rule2.LineBlack, *lineBlackRule)
}
if *uploadRule != "" {
if *language == "java" {
Rule2.JavaUploadRuleList = append(Rule2.JavaUploadRuleList, *uploadRule)
} else if *language == "php" {
Rule2.PHPUploadRuleList = append(Rule2.PHPUploadRuleList, *uploadRule)
}
}
if *rceRule != "" {
Rule2.JavaRceRuleList = append(Rule2.JavaRceRuleList, *rceRule)
}
}
}
if *filterfile != "" {
if *Dir != "" {
Filter.FilterFile(*filterfile, *Dir)
} else {
color.Red("请使用 -d 选项提供目录")
return
}
}
}
================================================
FILE: build.sh
================================================
#!/bin/bash
# Define the list of target operating systems and architectures
os_archs=("darwin:amd64" "darwin:arm64" "linux:amd64" "windows:amd64")
# Define the Go compiler flags
LDFLAGS="-s -w"
# Loop through each OS/architecture pair and build JodeScanner
for pair in "${os_archs[@]}"; do
os=$(echo "$pair" | cut -d ":" -f 1)
arch=$(echo "$pair" | cut -d ":" -f 2)
output="./releases/CodeScan_${os}_${arch}"
# For Windows, add .exe extension to the output file
if [[ "$os" == "windows" ]]; then
output="$output.exe"
fi
# Build JodeScanner for the current OS/architecture pair
echo "Building $output..."
GOOS="$os" GOARCH="$arch" go build -trimpath -ldflags "$LDFLAGS" -o "$output" main.go
echo "Build $output done"
done
================================================
FILE: go.mod
================================================
module CodeScan
go 1.22.1
require (
github.com/cheggaaa/pb/v3 v3.1.5
github.com/fatih/color v1.16.0
)
require (
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/sys v0.14.0 // indirect
)
================================================
FILE: go.sum
================================================
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
github.com/cheggaaa/pb/v3 v3.1.5 h1:QuuUzeM2WsAqG2gMqtzaWithDJv0i+i6UlnwSCI4QLk=
github.com/cheggaaa/pb/v3 v3.1.5/go.mod h1:CrxkeghYTXi1lQBEI7jSn+3svI3cuc19haAj6jM60XI=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
================================================
FILE: jarFiles.txt
================================================
HikariCP-2.7.8.jar
aliyun-java-sdk-core-3.4.0.jar
aliyun-java-sdk-ecs-4.2.0.jar
aliyun-java-sdk-kms-2.7.0.jar
aliyun-java-sdk-ram-3.0.0.jar
aliyun-java-sdk-sts-3.0.0.jar
aliyun-sdk-oss-3.10.1.jar
byte-buddy-1.7.10.jar
classmate-1.3.4.jar
commons-codec-1.11.jar
commons-pool2-2.5.0.jar
fastjson-1.2.83.jar
gson-2.8.2.jar
guava-18.0.jar
hibernate-validator-6.0.7.Final.jar
httpclient-4.5.2.jar
httpcore-4.4.9.jar
jackson-annotations-2.9.0.jar
jackson-core-2.9.4.jar
jackson-databind-2.9.4.jar
jackson-dataformat-yaml-2.9.4.jar
jackson-datatype-jdk8-2.9.4.jar
jackson-datatype-jsr310-2.9.4.jar
jackson-module-parameter-names-2.9.4.jar
java-semver-0.9.0.jar
javassist-3.21.0-GA.jar
javax.annotation-api-1.3.2.jar
jboss-logging-3.3.2.Final.jar
jdom-1.1.jar
jedis-2.9.0.jar
jettison-1.1.jar
jsqlparser-1.3.jar
jul-to-slf4j-1.7.25.jar
jxl-2.6.12.jar
log4j-1.2.14.jar
log4j-api-2.10.0.jar
log4j-to-slf4j-2.15.0.jar
logback-classic-1.2.3.jar
logback-core-1.2.3.jar
lombok-1.18.12.jar
mapstruct-1.1.0.Final.jar
mybatis-3.4.6.jar
mybatis-plus-3.0.7.1.jar
mybatis-plus-annotation-3.0.7.1.jar
mybatis-plus-boot-starter-3.0.7.1.jar
mybatis-plus-core-3.0.7.1.jar
mybatis-plus-extension-3.0.7.1.jar
mybatis-spring-1.3.2.jar
mysql-connector-java-8.0.11.jar
pf4j-3.1.0.jar
protobuf-java-2.6.0.jar
reflections-0.9.11.jar
slf4j-api-1.7.25.jar
snakeyaml-1.19.jar
spring-aop-5.0.4.RELEASE.jar
spring-beans-5.0.4.RELEASE.jar
spring-boot-2.0.0.RELEASE.jar
spring-boot-autoconfigure-2.0.0.RELEASE.jar
spring-boot-starter-2.0.0.RELEASE.jar
spring-boot-starter-jdbc-2.0.0.RELEASE.jar
spring-boot-starter-json-2.0.0.RELEASE.jar
spring-boot-starter-logging-2.0.0.RELEASE.jar
spring-boot-starter-redis-1.4.1.RELEASE.jar
spring-boot-starter-tomcat-2.0.0.RELEASE.jar
spring-boot-starter-web-2.0.0.RELEASE.jar
spring-context-5.0.4.RELEASE.jar
spring-context-support-5.0.4.RELEASE.jar
spring-core-5.0.4.RELEASE.jar
spring-data-commons-2.0.5.RELEASE.jar
spring-data-keyvalue-2.0.5.RELEASE.jar
spring-data-redis-2.0.5.RELEASE.jar
spring-expression-5.0.4.RELEASE.jar
spring-jcl-5.0.4.RELEASE.jar
spring-jdbc-5.0.4.RELEASE.jar
spring-oxm-5.0.4.RELEASE.jar
spring-plugin-core-1.2.0.RELEASE.jar
spring-plugin-metadata-1.2.0.RELEASE.jar
spring-tx-5.0.4.RELEASE.jar
spring-web-5.0.4.RELEASE.jar
spring-webmvc-5.0.4.RELEASE.jar
springboot-plugin-framework-2.2.1-RELEASE.jar
springboot-plugin-framework-extension-mybatis-2.2.1-RELEASE.jar
springfox-core-2.7.0.jar
springfox-schema-2.7.0.jar
springfox-spi-2.7.0.jar
springfox-spring-web-2.7.0.jar
springfox-swagger-common-2.7.0.jar
springfox-swagger2-2.7.0.jar
stax-api-1.0.1.jar
swagger-annotations-1.5.13.jar
swagger-bootstrap-ui-1.6.jar
swagger-models-1.5.13.jar
tomcat-embed-core-8.5.28.jar
tomcat-embed-el-8.5.28.jar
tomcat-embed-websocket-8.5.28.jar
validation-api-2.0.1.Final.jar
================================================
FILE: main.go
================================================
package main
import (
"CodeScan/Utils"
"fmt"
"github.com/fatih/color"
"time"
)
func main() {
fmt.Println(`
' ██████╗ ██████╗ ██████╗ ███████╗███████╗ ██████╗ █████╗ ███╗ ██╗
' ██╔════╝██╔═══██╗██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗████╗ ██║
' ██║ ██║ ██║██║ ██║█████╗ ███████╗██║ ███████║██╔██╗ ██║
' ██║ ██║ ██║██║ ██║██╔══╝ ╚════██║██║ ██╔══██║██║╚██╗██║
' ╚██████╗╚██████╔╝██████╔╝███████╗███/.████║╚██████╗██║ ██║██║ ╚████║
' ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═══╝
' -- by zjacky,xiaoqiuxx
`)
Utils.Start()
elapsed := time.Since(Utils.StartTime) // 计
color.Green("[+] 扫描完成! 花费时长:%s\n", elapsed) // 算经过的时间
}