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 ![image](https://socialify.git.ci/Zjackky/CodeScan/image?description=1&font=Inter&forks=1&issues=1&language=1&logo=https%3A%2F%2Fzjacky-blog.oss-cn-beijing.aliyuncs.com%2Fblog%2F202401021003754.jpg&name=1&owner=1&pattern=Circuit%20Board&pulls=1&stargazers=1&theme=Light) ## 工具概述 该工具目的为对大多数不完整的代码以及依赖快速进行Sink点匹配来帮助红队完成快速代码审计,开发该工具的初衷是以`Sink`​到`Source`​的思路来开发,为了将所有可疑的Sink点匹配出来并且凭借第六感进行快速漏洞挖掘,并且该工具开发可扩展性强,成本极低,目前工具支持的语言有PHP,Java(JSP) ## 编译 ```bash ./build.sh # 会生成所有版本在releases下 ``` ## 功能 1. 框架识别 2. 涵盖大部分漏洞的Sink点的匹配(如图) ![image](https://zjacky-blog.oss-cn-beijing.aliyuncs.com/image-20240928235812-5wlbnbb.png) 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作为示例`​ #### 高扩展性 很简单的自定义,如果需要自定义一些匹配规则,首先可以在这里加入 ![image](https://zjacky-blog.oss-cn-beijing.aliyuncs.com/image-20240929002903-ypqa197.png)​ 其次如果需要新增漏洞类型,只需要三步(这里以Sql为例) 1. 新建SQL目录 2. 定义一个方法叫 SqlCheck 3. 写一个sqlcheck.txt(生成的文件名) + 你自定义的规则 4. 最后在这里加入包名+方法名即可 ![image](https://zjacky-blog.oss-cn-beijing.aliyuncs.com/image-20240929003143-7v37o9w.png)​ ```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", } ``` 所以这也导致了一个问题,不能从顶层上直接扫描 ![image](https://zjacky-blog.oss-cn-beijing.aliyuncs.com/image-20240929124102-qjfancc.png) `请把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) // 算经过的时间 }