├── .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 /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # 基于编辑器的 HTTP 客户端请求 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/CodeScan-master.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CommonVul/Rce/Rce.go: -------------------------------------------------------------------------------- 1 | package Rce 2 | 3 | import ( 4 | "CodeScan/CommonVul/Rule" 5 | "CodeScan/FindFile" 6 | "fmt" 7 | ) 8 | 9 | func JavaRce(dir string) { 10 | FindFile.FindFileByJava(dir, "rce.txt", Rule.JavaRceRuleList) 11 | fmt.Println("RCE分析完成") 12 | } 13 | 14 | func PHPRce(dir string) { 15 | FindFile.FindFileByPHP(dir, "rce.txt", Rule.PHPRceRuleList) 16 | fmt.Println("RCE分析完成") 17 | } 18 | -------------------------------------------------------------------------------- /CommonVul/Rule/MatchFileNameRule.go: -------------------------------------------------------------------------------- 1 | package Rule 2 | -------------------------------------------------------------------------------- /CommonVul/Rule/MatchFileReadRule.go: -------------------------------------------------------------------------------- 1 | package Rule 2 | 3 | var PHPFileReadList = []string{ 4 | "file_get_contents(", "file(", "readfile(", "fopen(", 5 | } 6 | -------------------------------------------------------------------------------- /CommonVul/Rule/MatchLineRule.go: -------------------------------------------------------------------------------- 1 | package Rule 2 | 3 | var LineBlack = []string{ 4 | "import ", 5 | "log.", 6 | "loaded from", 7 | "//", 8 | "document.write(", 9 | "getWriter().write(", 10 | "writer.write(", 11 | ".write()", 12 | } 13 | -------------------------------------------------------------------------------- /CommonVul/Rule/MatchPathRule.go: -------------------------------------------------------------------------------- 1 | package Rule 2 | 3 | var PathBlackJava = []string{ 4 | "apache", "lombok", "microsoft", "solr", 5 | "amazonaws", "c3p0", "jodd", "afterturn", "hutool", 6 | "javassist", "alibaba", "aliyuncs", "javax", "jackson", 7 | "bytebuddy", "baomidou", "google", "netty", "redis", "mysql", 8 | "logback", "ognl", "oracle", "sun", "junit", "reactor", "github", 9 | "mchange", "taobao", "nimbusds", "opensymphony", "freemarker", "java", "apiguardian", "hibernate", "javassist", "jboss", "junit", "mybatis", 10 | "springframework", "slf4j", "aspectj", 11 | } 12 | 13 | var PathBlackPhp = []string{ 14 | "think", "vendor", 15 | } 16 | -------------------------------------------------------------------------------- /CommonVul/Rule/MatchRceRule.go: -------------------------------------------------------------------------------- 1 | package Rule 2 | 3 | var JavaRceRuleList = []string{ 4 | "Runtime.getRuntime().exec", "ProcessBuilder.start", 5 | "RuntimeUtil.exec(", "RuntimeUtil.execForStr(", 6 | } 7 | 8 | var PHPRceRuleList = []string{ 9 | "System(", "shell_exec(", "exec(", "eval(", "passthru(", "proc_open(", "popen(", 10 | "assert(", "call_user_func(", "call_user_func_array(", "create_function(", 11 | } 12 | -------------------------------------------------------------------------------- /CommonVul/Rule/MatchUploadRule.go: -------------------------------------------------------------------------------- 1 | package Rule 2 | 3 | var JavaUploadRuleList = []string{ 4 | "Streams.copy(", 5 | ".getOriginalFilename(", ".transferTo(", 6 | "UploadedFile(", "FileUtils.copyFile(", "MultipartHttpServletRequest", ".getFileName(", ".saveAs(", ".getFileSuffix(", ".getFile", "MultipartFile file", 7 | } 8 | 9 | var PHPUploadRuleList = []string{ 10 | "move_uploaded_file(", "file_put_contents(", "$_FILE[", "copy(", "->move(", "request()->file(", 11 | } 12 | -------------------------------------------------------------------------------- /CommonVul/Rule/MtachSqlRule.go: -------------------------------------------------------------------------------- 1 | package Rule 2 | 3 | var XmlSqlBlack = []string{ 4 | "", "id=\"dataSource\"", "", "", 7 | " 0 { 56 | writeToFile("sql.txt", selectList) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Java-Code/Sql/FindSqlByXml.go: -------------------------------------------------------------------------------- 1 | package Sql 2 | 3 | import ( 4 | Rule2 "CodeScan/CommonVul/Rule" 5 | "bufio" 6 | "fmt" 7 | "io/fs" 8 | "os" 9 | "path/filepath" 10 | "strings" 11 | ) 12 | 13 | // findKeywordsInXMLFiles 函数用于检查 XML 文件中的关键字 14 | func findSqlByXml(dir string) { 15 | xmlList := []string{} 16 | var lastFile string // 记录上一次输出的文件,用于控制输出格式 17 | 18 | // 使用 Walk 函数遍历目录,查找所有的 .xml 文件 19 | err := filepath.Walk(dir, func(path string, f fs.FileInfo, err error) error { 20 | if !f.IsDir() && strings.HasSuffix(f.Name(), ".xml") { 21 | // xml黑名单匹配 22 | if Rule2.MatchRule(f.Name(), Rule2.XmlBlack) { 23 | return nil 24 | } 25 | xmlList = append(xmlList, path) 26 | } 27 | return nil 28 | }) 29 | check(err) 30 | 31 | // 定义需要搜索的关键字 32 | keywords := []string{"${", "like '%${", "order by ${"} // 这里可以添加更多关键字 33 | 34 | // 遍历 XML 文件列表 35 | for _, file := range xmlList { 36 | foundKeywords := []string{} 37 | 38 | lineNumber := 1 39 | // 打开 XML 文件 40 | f, err := os.Open(file) 41 | check(err) 42 | defer f.Close() 43 | 44 | // 逐行扫描文件内容 45 | scanner := bufio.NewScanner(f) 46 | for scanner.Scan() { 47 | line := strings.TrimSpace(scanner.Text()) 48 | // 检查每一行是否包含关键字,并且不包含黑名单中的关键字 49 | if Rule2.MatchRule(line, Rule2.XmlSqlBlack) { 50 | continue 51 | } 52 | // 检查每一行是否包含需要搜索的关键字 53 | for _, keyword := range keywords { 54 | if strings.Contains(line, keyword) { 55 | if lastFile != f.Name() { 56 | foundKeywords = append(foundKeywords, fmt.Sprintf("====================================================================\n")) 57 | foundKeywords = append(foundKeywords, fmt.Sprintf("file [%s]\n%d: %s", f.Name(), lineNumber, line)) 58 | lastFile = f.Name() 59 | } else { 60 | foundKeywords = append(foundKeywords, fmt.Sprintf("====================================================================\n")) 61 | foundKeywords = append(foundKeywords, fmt.Sprintf("%d : %s", lineNumber, line)) 62 | } 63 | } 64 | } 65 | lineNumber++ 66 | } 67 | 68 | // 如果找到关键字,则将相关信息写入到 sql.txt 文件中 69 | if len(foundKeywords) > 0 { 70 | writeToFile("sql.txt", foundKeywords) 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Java-Code/Sql/Sql.go: -------------------------------------------------------------------------------- 1 | package Sql 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | // check 函数用于检查错误,如果错误不为 nil 则触发 panic 9 | func check(e error) { 10 | if e != nil { 11 | panic(e) 12 | } 13 | } 14 | 15 | // Sqlcheck 函数是我们的主函数,负责执行 SQL 检查的逻辑 16 | func Sqlcheck(dir string) { 17 | // 检查是否存在 @Select 注解 18 | findSqlByCode(dir) 19 | 20 | // 检查 XML 文件中的关键字 21 | findSqlByXml(dir) 22 | 23 | fmt.Println("sql分析完成") 24 | } 25 | 26 | // writeToFile 函数用于将信息写入文件 27 | func writeToFile(filename string, lines []string) { 28 | 29 | // 创建或打开输出文件,以追加模式写入 30 | basedir := "./results/" 31 | 32 | // 检查目录是否存在 33 | if _, err := os.Stat(basedir); os.IsNotExist(err) { 34 | // 如果目录不存在,则创建 35 | err := os.MkdirAll(basedir, os.ModePerm) 36 | if err != nil { 37 | fmt.Println("Error creating directory:", err) 38 | return 39 | } 40 | } 41 | 42 | outputfile := basedir + filename // 打开文件,如果文件不存在则创建,如果存在则追加写入 43 | outputFile, err := os.OpenFile(outputfile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 44 | check(err) 45 | defer outputFile.Close() 46 | 47 | // 将每一行信息写入文件 48 | for _, line := range lines { 49 | _, err = outputFile.WriteString(fmt.Sprintf("%s\n", line)) 50 | check(err) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Java-Code/Zip/Zipsilp.go: -------------------------------------------------------------------------------- 1 | package Zip 2 | 3 | import ( 4 | "CodeScan/FindFile" 5 | "fmt" 6 | ) 7 | 8 | func Zipsilp(dir string) { 9 | FindFile.FindFileByJava(dir, "zip.txt", []string{"zipEntry.getName(", "ZipUtil.unpack(", "ZipUtil.unzip(", "entry.getName()", "AntZipUtils.unzip(", "zip.getEntries()"}) 10 | fmt.Println("Zipsilp分析完成") 11 | } 12 | -------------------------------------------------------------------------------- /PHP-Code/FileRead/Read.go: -------------------------------------------------------------------------------- 1 | package FileRead 2 | 3 | import ( 4 | "CodeScan/CommonVul/Rule" 5 | "CodeScan/FindFile" 6 | "fmt" 7 | ) 8 | 9 | func Read(dir string) { 10 | FindFile.FindFileByPHP(dir, "FileRead_Phar.txt", Rule.PHPFileReadList) 11 | fmt.Println("PHP文件读取分析完成") 12 | 13 | } 14 | -------------------------------------------------------------------------------- /PHP-Code/FileWrite/Write.go: -------------------------------------------------------------------------------- 1 | package FileWrite 2 | 3 | import ( 4 | "CodeScan/FindFile" 5 | "fmt" 6 | ) 7 | 8 | func Write(dir string) { 9 | FindFile.FindFileByPHP(dir, "FileWrite.txt", []string{ 10 | "file_put_contents(", 11 | }) 12 | fmt.Println("PHP文件写入分析完成") 13 | 14 | } 15 | -------------------------------------------------------------------------------- /PHP-Code/Include/Include.go: -------------------------------------------------------------------------------- 1 | package Include 2 | 3 | import ( 4 | "CodeScan/FindFile" 5 | "fmt" 6 | ) 7 | 8 | func Include(dir string) { 9 | FindFile.FindFileByPHP(dir, "Include.txt", []string{ 10 | "include(", 11 | }) 12 | fmt.Println("PHP文件包含分析完成") 13 | } 14 | -------------------------------------------------------------------------------- /PHP-Code/PHPSql/FindSqlByCode.go: -------------------------------------------------------------------------------- 1 | package PHPSql 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io/fs" 7 | "os" 8 | "path/filepath" 9 | "strings" 10 | ) 11 | 12 | // 函数用于检查是否存在java代码内容,并将相关信息写入 sql.txt 13 | func findSqlByCode(dir string) { 14 | selectList := []string{} 15 | var lastFile string // 记录上一次输出的文件,用于控制输出格式 16 | 17 | keywords := []string{"like '%\" +", "mysql_query(", "->where(", "->order(", "mysqli_query("} 18 | 19 | err := filepath.Walk(dir, func(path string, f fs.FileInfo, err error) error { 20 | if !f.IsDir() && strings.HasSuffix(f.Name(), ".php") { 21 | // 打开文件 22 | lineNumber := 1 // 行号,用于标识匹配行的位置 23 | file, err := os.Open(path) 24 | check(err) 25 | defer file.Close() 26 | 27 | // 逐行扫描文件内容 28 | scanner := bufio.NewScanner(file) 29 | for scanner.Scan() { 30 | line := strings.TrimSpace(scanner.Text()) 31 | // 如果行中包含 @Select 注解,则将相关信息添加到 selectList 中 32 | for _, keyword := range keywords { 33 | if strings.Contains(line, keyword) { 34 | if lastFile != file.Name() { 35 | selectList = append(selectList, fmt.Sprintf("====================================================================\n")) 36 | selectList = append(selectList, fmt.Sprintf("file [%s]\n%d: %s", file.Name(), lineNumber, line)) 37 | lastFile = file.Name() 38 | } else { 39 | selectList = append(selectList, fmt.Sprintf("====================================================================\n")) 40 | selectList = append(selectList, fmt.Sprintf("%d : %s", lineNumber, line)) 41 | } 42 | } 43 | 44 | } 45 | lineNumber++ 46 | } 47 | 48 | } 49 | return nil 50 | }) 51 | check(err) 52 | 53 | // 如果存在 @Select 注解,则将相关信息写入到 sql.txt 文件中 54 | if len(selectList) > 0 { 55 | writeToFile("sql.txt", selectList) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /PHP-Code/PHPSql/Sql.go: -------------------------------------------------------------------------------- 1 | package PHPSql 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | ) 7 | 8 | // check 函数用于检查错误,如果错误不为 nil 则触发 panic 9 | func check(e error) { 10 | if e != nil { 11 | panic(e) 12 | } 13 | } 14 | 15 | // Sqlcheck 函数是我们的主函数,负责执行 SQL 检查的逻辑 16 | func Sqlcheck(dir string) { 17 | // 检查是否存在 @Select 注解 18 | findSqlByCode(dir) 19 | 20 | fmt.Println("sql分析完成") 21 | } 22 | 23 | // writeToFile 函数用于将信息写入文件 24 | func writeToFile(filename string, lines []string) { 25 | // 打开文件,如果文件不存在则创建,如果存在则追加写入 26 | outputFile, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 27 | check(err) 28 | defer outputFile.Close() 29 | 30 | // 将每一行信息写入文件 31 | for _, line := range lines { 32 | _, err = outputFile.WriteString(fmt.Sprintf("%s\n", line)) 33 | check(err) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /PHP-Code/SSRF/SSRF.go: -------------------------------------------------------------------------------- 1 | package SSRF 2 | 3 | import ( 4 | "CodeScan/FindFile" 5 | "fmt" 6 | ) 7 | 8 | func PHP_SSRF(dir string) { 9 | FindFile.FindFileByPHP(dir, "SSRF.txt", []string{ 10 | "curl_exec(", 11 | }) 12 | fmt.Println("PHPSSRF分析完成") 13 | } 14 | -------------------------------------------------------------------------------- /PHP-Code/Unserialize/ser.go: -------------------------------------------------------------------------------- 1 | package Unserialize 2 | 3 | import ( 4 | "CodeScan/FindFile" 5 | "fmt" 6 | ) 7 | 8 | func Unserialize(dir string) { 9 | 10 | FindFile.FindFileByPHP(dir, "Unserialize.txt", []string{ 11 | "__destruct(", 12 | }) 13 | fmt.Println("PHP反序列化分析完成") 14 | 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeScan 2 | ![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) 3 | ## 工具概述 4 | 5 | 该工具目的为对大多数不完整的代码以及依赖快速进行Sink点匹配来帮助红队完成快速代码审计,开发该工具的初衷是以`Sink`​到`Source`​的思路来开发,为了将所有可疑的Sink点匹配出来并且凭借第六感进行快速漏洞挖掘,并且该工具开发可扩展性强,成本极低,目前工具支持的语言有PHP,Java(JSP) 6 | 7 | ## 编译 8 | 9 | ```bash 10 | ./build.sh 11 | 12 | # 会生成所有版本在releases下 13 | ``` 14 | 15 | ## 功能 16 | 17 | 1. 框架识别 18 | 2. 涵盖大部分漏洞的Sink点的匹配(如图) 19 | ![image](https://zjacky-blog.oss-cn-beijing.aliyuncs.com/image-20240928235812-5wlbnbb.png) 20 | 3. 可自定义定制化修改黑白名单内容 21 | 4. 多模块化多语言化代码审计 22 | 5. 进行融于鉴权代码的快速匹配抓取 23 | 6. 根据Jar进行静态分析(默认分析) 24 | 25 | * mysqlconnect-->jdbc 26 | * Xstream --> xml/json 27 | 28 | ## 使用 29 | 30 | ```bash 31 | Usage of ./CodeScan_darwin_arm64: 32 | -L string 33 | 审计语言 34 | -d string 35 | 要扫描的目录 36 | -h string 37 | 使用帮助 38 | -lb string 39 | 行黑名单 40 | -m string 41 | 过滤的字符串 42 | -pb string 43 | 路径黑名单 44 | -r string 45 | RCE规则 46 | -u string 47 | 文件上传规则 48 | 49 | 50 | Example: 51 | CodeScan_windows_amd64.exe -L java -d ./net 52 | CodeScan_windows_amd64.exe -L php -d ./net 53 | CodeScan_windows_amd64.exe -d ./net -m "CheckSession.jsp" 54 | ``` 55 | 56 | ## 高级用法+案例分析 57 | 58 | ### 高级用法 59 | 60 | `以下均以Java作为示例`​ 61 | 62 | #### 高扩展性 63 | 64 | 很简单的自定义,如果需要自定义一些匹配规则,首先可以在这里加入 65 | 66 | ![image](https://zjacky-blog.oss-cn-beijing.aliyuncs.com/image-20240929002903-ypqa197.png)​ 67 | 68 | 69 | 其次如果需要新增漏洞类型,只需要三步(这里以Sql为例) 70 | 71 | 1. 新建SQL目录 72 | 2. 定义一个方法叫 SqlCheck 73 | 3. 写一个sqlcheck.txt(生成的文件名) + 你自定义的规则 74 | 4. 最后在这里加入包名+方法名即可 75 | 76 | ![image](https://zjacky-blog.oss-cn-beijing.aliyuncs.com/image-20240929003143-7v37o9w.png)​ 77 | 78 | ```go 79 | package SqlTest 80 | 81 | import ( 82 | "CodeScan/FindFile" 83 | "fmt" 84 | ) 85 | 86 | func SqlCheck(dir string) { 87 | FindFile.FindFileByJava(dir, "fastjson.txt", []string{".parseObject("}) 88 | fmt.Println("SqlCheck分析完成") 89 | 90 | } 91 | 92 | ``` 93 | 94 | #### 扫描位置 95 | 96 | 在打一些闭源代码的时候经常就一个Jar或者Class,反编译的时候会把依赖进行一起反编译,所以为了避免扫描一些依赖的误报,在工具中自带的黑名单中会过滤掉如下黑名单的包名,需要自定义的时候可自行修改,位置在`CommonVul/Rule/MatchPathRule.go`​ 97 | 98 | ```go 99 | var PathBlackJava = []string{ 100 | "apache", "lombok", "microsoft", "solr", 101 | "amazonaws", "c3p0", "jodd", "afterturn", "hutool", 102 | "javassist", "alibaba", "aliyuncs", "javax", "jackson", 103 | "bytebuddy", "baomidou", "google", "netty", "redis", "mysql", 104 | "logback", "ognl", "oracle", "sun", "junit", "reactor", "github", 105 | "mchange", "taobao", "nimbusds", "opensymphony", "freemarker", "java", "apiguardian", "hibernate", "javassist", "jboss", "junit", "mybatis", 106 | "springframework", "slf4j", 107 | } 108 | ``` 109 | 110 | 所以这也导致了一个问题,不能从顶层上直接扫描 111 | 112 | ![image](https://zjacky-blog.oss-cn-beijing.aliyuncs.com/image-20240929124102-qjfancc.png) 113 | 114 | `请把CodeScan放在Net同级目录下扫描(否则会忽略掉直接一个Java目录)`​ 115 | 116 | 请`-d`​后面的参数尽量在`/src/main/java`​之后,比如这里就需要把CodeScan放到`net`​目录下开始扫描 117 | 118 | ```bash 119 | CodeScan_windows_amd64.exe -L java -d ./net 120 | ``` 121 | 122 | #### 过滤字符串(只写了JSP + PHP) 123 | 124 | 比如现在有一个代码百分百为鉴权代码在JSP中 125 | 126 | ```java 127 | <%@ include file="../../common/js/CheckSession.jsp"%> 128 | ``` 129 | 130 | 此时可以用一下功能来进行快速获取未鉴权代码 131 | 132 | ```bash 133 | CodeScan_windows_amd64.exe -d ./yuan -m "CheckSession.jsp" 134 | ``` 135 | 136 | 此时会将不存在这个代码的文件都放到`NoAuthDir`​目录中,然后可以再扫一遍就可以立刻定位到存在未鉴权并且存在Sink点的函数文件了 137 | 138 | ```bash 139 | CodeScan_windows_amd64.exe -L java -d ./NoAuthDir 140 | ``` 141 | 142 | #### 静态分析依赖情况 143 | 144 | 只需要在CodeScan的目录下放入EvilJarList.txt即可匹配出来 145 | 146 | `EvilJarList.txt` 内容为存在可打漏洞的`Jar`,模版如下 147 | 148 | ```bash 149 | fastjson-1.2.47.jar 150 | resin-4.0.63.jar 151 | jackson-core-2.13.3.jar 152 | c3p0-0.9.5.2.jar 153 | commons-beanutils-1.9.4.jar 154 | commons-beanutils-1.9.3.jar 155 | commons-beanutils-1.9.2.jar 156 | commons-collections-3.2.1.jar 157 | mysql-connector-java-8.0.17.jar 158 | commons-collections4-4.0.jar 159 | shiro-core-1.10.1.jar 160 | aspectjweaver-1.9.5.jar 161 | rome-1.0.jar 162 | xstream-1.4.11.1.jar 163 | sqlite-jdbc-3.8.9.jar 164 | vaadin-server-7.7.14.jar 165 | hessian-4.0.63.jar 166 | ``` 167 | 168 | #### 案例 169 | 案例请参考我的博客 170 | ```bash 171 | https://zjackky.github.io/post/develop-codescan-zwcz53.html 172 | ``` 173 | 174 | ## TODO 175 | 176 | * [ ] 将结果从TXT转为Excel 177 | * [ ] Sink点继续完善 178 | * [ ] ASP 179 | 180 | ## 支持项目 181 | 182 | * 如果有师傅发现Bug或者有更好的建议请提issue感谢 183 | * 要是各位师傅通过本人的小工具挖到一些好洞记得回头点点Stars诶 184 | 185 | ## 免责申明 186 | 187 | * 如果您下载、安装、使用、修改本工具及相关代码,即表明您信任本工具 188 | * 在使用本工具时造成对您自己或他人任何形式的损失和伤害,我们不承担任何责任 189 | * 如您在使用本工具的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任 190 | * 请您务必审慎阅读、充分理解各条款内容,特别是免除或者限制责任的条款,并选择接受或不接受 191 | * 除非您已阅读并接受本协议所有条款,否则您无权下载、安装或使用本工具 192 | * 您的下载、安装、使用等行为即视为您已阅读并同意上述协议的约束 193 | 194 | ## 更新日志 195 | 196 | **2024/09/29** 197 | 198 | * 开源 199 | 200 | **2024/10/7** 201 | 202 | * 将扫描结果写入result目录中 203 | 204 | ## 鸣谢 205 | 206 | [xiaoqiuxx(github.com)](https://github.com/xiaoqiuxx) 207 | -------------------------------------------------------------------------------- /Utils/JavaScanUtil.go: -------------------------------------------------------------------------------- 1 | package Utils 2 | 3 | import ( 4 | "CodeScan/CommonVul/Rce" 5 | "CodeScan/CommonVul/Upload" 6 | "CodeScan/Java-Code/AMF" 7 | "CodeScan/Java-Code/Auth_Bypass" 8 | "CodeScan/Java-Code/El" 9 | "CodeScan/Java-Code/Fastjson" 10 | "CodeScan/Java-Code/Frame_Analysis" 11 | "CodeScan/Java-Code/JDBC" 12 | "CodeScan/Java-Code/JNDI" 13 | "CodeScan/Java-Code/JS" 14 | "CodeScan/Java-Code/JarStatic" 15 | "CodeScan/Java-Code/JavaSrciptShell" 16 | "CodeScan/Java-Code/Log4j" 17 | "CodeScan/Java-Code/ReadObject" 18 | "CodeScan/Java-Code/Reflect" 19 | "CodeScan/Java-Code/SSTI/FreeMarker" 20 | "CodeScan/Java-Code/Sql" 21 | "CodeScan/Java-Code/Zip" 22 | "github.com/cheggaaa/pb/v3" 23 | "os" 24 | "path/filepath" 25 | "strings" 26 | "sync" 27 | "time" 28 | ) 29 | 30 | func Java_Codeing() { 31 | StartTime = time.Now() 32 | // 所有要执行的扫描函数 33 | scanFuncs := []func(string){ 34 | Frame_Analysis.FrameAnalysiser, 35 | Auth_Bypass.Auth, 36 | Zip.Zipsilp, 37 | JNDI.Jndi, 38 | Sql.Sqlcheck, 39 | Rce.JavaRce, 40 | Upload.JavaUpload_check, 41 | ReadObject.Readobjectcheck, 42 | El.Elcheck, 43 | Fastjson.Parsecheck, 44 | Reflect.ReflectCheck, 45 | Log4j.Log4j, 46 | AMF.AmfCheck, 47 | FreeMarker.FreeSsti, 48 | JDBC.FindJDBC, 49 | JavaSrciptShell.FindJavaSrciptShell, 50 | JarStatic.Jarstaticer, 51 | JS.Eval, 52 | } 53 | 54 | var wg sync.WaitGroup 55 | wg.Add(len(scanFuncs)) // 根据方法数量动态调整 goroutine 数量 56 | progressBar = pb.New(len(scanFuncs)).SetRefreshRate(time.Millisecond * 100).Start() 57 | // 启动 goroutine 来执行扫描任务 58 | for _, scanFunc := range scanFuncs { 59 | go scanDirectory(scanFunc, *Dir, &wg) 60 | } 61 | 62 | wg.Wait() 63 | progressBar.Finish() 64 | 65 | // 处理web.xml 66 | Frame_Analysis.WebXmlScan(*Dir, []string{"*.htm", "*.do", "*.action", "exclude"}) 67 | 68 | // 清理空文件 69 | root := "./" // 设置要检查的目录 70 | filepath.Walk(root, func(path string, info os.FileInfo, err error) error { 71 | if err != nil { 72 | return err 73 | } 74 | if !info.IsDir() && strings.HasSuffix(info.Name(), ".txt") { 75 | if info.Size() == 0 { 76 | os.Remove(path) 77 | } 78 | } 79 | return nil 80 | }) 81 | } 82 | -------------------------------------------------------------------------------- /Utils/PHPScanUtil.go: -------------------------------------------------------------------------------- 1 | package Utils 2 | 3 | import ( 4 | "CodeScan/CommonVul/Rce" 5 | "CodeScan/CommonVul/Upload" 6 | "CodeScan/PHP-Code/FileRead" 7 | "CodeScan/PHP-Code/Include" 8 | "CodeScan/PHP-Code/PHPSql" 9 | "CodeScan/PHP-Code/SSRF" 10 | "CodeScan/PHP-Code/Unserialize" 11 | "github.com/cheggaaa/pb/v3" 12 | "os" 13 | "path/filepath" 14 | "strings" 15 | "sync" 16 | "time" 17 | ) 18 | 19 | func PHP_Codeing() { 20 | StartTime = time.Now() 21 | 22 | // 所有要执行的扫描函数 23 | scanFuncs := []func(string){ 24 | Upload.PHPUpload_check, 25 | Rce.PHPRce, 26 | PHPSql.Sqlcheck, 27 | FileRead.Read, 28 | Unserialize.Unserialize, 29 | SSRF.PHP_SSRF, 30 | Include.Include, 31 | } 32 | 33 | var wg sync.WaitGroup 34 | wg.Add(len(scanFuncs)) // 根据方法数量动态调整 goroutine 数量 35 | progressBar = pb.New(len(scanFuncs)).SetRefreshRate(time.Millisecond * 100).Start() 36 | // 启动 goroutine 来执行扫描任务 37 | for _, scanFunc := range scanFuncs { 38 | go scanDirectory(scanFunc, *Dir, &wg) 39 | } 40 | 41 | wg.Wait() 42 | progressBar.Finish() 43 | // 清理空文件 44 | root := "./" // 设置要检查的目录 45 | filepath.Walk(root, func(path string, info os.FileInfo, err error) error { 46 | if err != nil { 47 | return err 48 | } 49 | if !info.IsDir() && strings.HasSuffix(info.Name(), ".txt") { 50 | if info.Size() == 0 { 51 | os.Remove(path) 52 | } 53 | } 54 | return nil 55 | }) 56 | } 57 | -------------------------------------------------------------------------------- /Utils/common.go: -------------------------------------------------------------------------------- 1 | package Utils 2 | 3 | import ( 4 | "github.com/cheggaaa/pb/v3" 5 | "strings" 6 | "sync" 7 | "time" 8 | ) 9 | 10 | var ( 11 | progressBar *pb.ProgressBar 12 | StartTime time.Time 13 | ) 14 | 15 | // scanDirectory 函数用于启动一个 goroutine 来扫描指定目录 16 | func scanDirectory(scanFunc func(string), dir string, wg *sync.WaitGroup) { 17 | scanFunc(dir) 18 | progressBar.Increment() 19 | wg.Done() 20 | } 21 | 22 | func ClearDir(dir string) string { 23 | 24 | // 将 \ 转换为 / 25 | dir = strings.ReplaceAll(dir, `\\`, "/") 26 | dir = strings.ReplaceAll(dir, `\`, "/") 27 | 28 | return dir 29 | } 30 | -------------------------------------------------------------------------------- /Utils/flag.go: -------------------------------------------------------------------------------- 1 | package Utils 2 | 3 | import ( 4 | Rule2 "CodeScan/CommonVul/Rule" 5 | "CodeScan/Filter" 6 | "flag" 7 | "fmt" 8 | "github.com/fatih/color" 9 | "strings" 10 | ) 11 | 12 | var ( 13 | Dir *string 14 | language *string 15 | help *string 16 | ) 17 | 18 | func Start() { 19 | // 开始审计 20 | 21 | parseFlag() 22 | *language = strings.ToLower(*language) 23 | if *language == "java" { 24 | Java_Codeing() 25 | } 26 | 27 | if *language == "php" { 28 | PHP_Codeing() 29 | } 30 | 31 | } 32 | 33 | func parseFlag() { 34 | 35 | // 高级命令行解析 36 | help = flag.String("h", "", "使用帮助") 37 | Dir = flag.String("d", "", "要扫描的目录") 38 | language = flag.String("L", "", "审计语言") 39 | pathBlackRule := flag.String("pb", "", "路径黑名单") 40 | lineBlackRule := flag.String("lb", "", "行黑名单") 41 | uploadRule := flag.String("u", "", "文件上传规则") 42 | rceRule := flag.String("r", "", "RCE规则") 43 | filterfile := flag.String("m", "", "过滤的字符串") 44 | //outdir := flag.String("o", "", "输出结果") 45 | flag.Parse() 46 | 47 | if *language == "" && *filterfile == "" { 48 | color.Red("请使用 -L 选项提供扫描语言") 49 | return 50 | } 51 | 52 | if *language != "" { 53 | 54 | if *Dir != "" { 55 | *Dir = ClearDir(*Dir) 56 | if *pathBlackRule != "" { 57 | // 读取路径黑名单 58 | Rule2.PathBlackJava = append(Rule2.PathBlackJava, *pathBlackRule) 59 | fmt.Println("路径黑名单:", Rule2.PathBlackJava) 60 | } // 所有要执行的扫描函数 61 | 62 | if *lineBlackRule != "" { 63 | Rule2.LineBlack = append(Rule2.LineBlack, *lineBlackRule) 64 | } 65 | 66 | if *uploadRule != "" { 67 | if *language == "java" { 68 | Rule2.JavaUploadRuleList = append(Rule2.JavaUploadRuleList, *uploadRule) 69 | } else if *language == "php" { 70 | Rule2.PHPUploadRuleList = append(Rule2.PHPUploadRuleList, *uploadRule) 71 | } 72 | 73 | } 74 | 75 | if *rceRule != "" { 76 | Rule2.JavaRceRuleList = append(Rule2.JavaRceRuleList, *rceRule) 77 | } 78 | 79 | } 80 | 81 | } 82 | 83 | if *filterfile != "" { 84 | if *Dir != "" { 85 | Filter.FilterFile(*filterfile, *Dir) 86 | 87 | } else { 88 | color.Red("请使用 -d 选项提供目录") 89 | return 90 | } 91 | 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Define the list of target operating systems and architectures 4 | os_archs=("darwin:amd64" "darwin:arm64" "linux:amd64" "windows:amd64") 5 | 6 | # Define the Go compiler flags 7 | LDFLAGS="-s -w" 8 | 9 | # Loop through each OS/architecture pair and build JodeScanner 10 | for pair in "${os_archs[@]}"; do 11 | os=$(echo "$pair" | cut -d ":" -f 1) 12 | arch=$(echo "$pair" | cut -d ":" -f 2) 13 | output="./releases/CodeScan_${os}_${arch}" 14 | 15 | # For Windows, add .exe extension to the output file 16 | if [[ "$os" == "windows" ]]; then 17 | output="$output.exe" 18 | fi 19 | 20 | # Build JodeScanner for the current OS/architecture pair 21 | echo "Building $output..." 22 | GOOS="$os" GOARCH="$arch" go build -trimpath -ldflags "$LDFLAGS" -o "$output" main.go 23 | echo "Build $output done" 24 | done 25 | 26 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module CodeScan 2 | 3 | go 1.22.1 4 | 5 | require ( 6 | github.com/cheggaaa/pb/v3 v3.1.5 7 | github.com/fatih/color v1.16.0 8 | ) 9 | 10 | require ( 11 | github.com/VividCortex/ewma v1.2.0 // indirect 12 | github.com/mattn/go-colorable v0.1.13 // indirect 13 | github.com/mattn/go-isatty v0.0.20 // indirect 14 | github.com/mattn/go-runewidth v0.0.15 // indirect 15 | github.com/rivo/uniseg v0.2.0 // indirect 16 | golang.org/x/sys v0.14.0 // indirect 17 | ) 18 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow= 2 | github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4= 3 | github.com/cheggaaa/pb/v3 v3.1.5 h1:QuuUzeM2WsAqG2gMqtzaWithDJv0i+i6UlnwSCI4QLk= 4 | github.com/cheggaaa/pb/v3 v3.1.5/go.mod h1:CrxkeghYTXi1lQBEI7jSn+3svI3cuc19haAj6jM60XI= 5 | github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= 6 | github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= 7 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 8 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 9 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 10 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 11 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 12 | github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= 13 | github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 14 | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= 15 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 16 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 17 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 18 | golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= 19 | golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 20 | -------------------------------------------------------------------------------- /jarFiles.txt: -------------------------------------------------------------------------------- 1 | HikariCP-2.7.8.jar 2 | aliyun-java-sdk-core-3.4.0.jar 3 | aliyun-java-sdk-ecs-4.2.0.jar 4 | aliyun-java-sdk-kms-2.7.0.jar 5 | aliyun-java-sdk-ram-3.0.0.jar 6 | aliyun-java-sdk-sts-3.0.0.jar 7 | aliyun-sdk-oss-3.10.1.jar 8 | byte-buddy-1.7.10.jar 9 | classmate-1.3.4.jar 10 | commons-codec-1.11.jar 11 | commons-pool2-2.5.0.jar 12 | fastjson-1.2.83.jar 13 | gson-2.8.2.jar 14 | guava-18.0.jar 15 | hibernate-validator-6.0.7.Final.jar 16 | httpclient-4.5.2.jar 17 | httpcore-4.4.9.jar 18 | jackson-annotations-2.9.0.jar 19 | jackson-core-2.9.4.jar 20 | jackson-databind-2.9.4.jar 21 | jackson-dataformat-yaml-2.9.4.jar 22 | jackson-datatype-jdk8-2.9.4.jar 23 | jackson-datatype-jsr310-2.9.4.jar 24 | jackson-module-parameter-names-2.9.4.jar 25 | java-semver-0.9.0.jar 26 | javassist-3.21.0-GA.jar 27 | javax.annotation-api-1.3.2.jar 28 | jboss-logging-3.3.2.Final.jar 29 | jdom-1.1.jar 30 | jedis-2.9.0.jar 31 | jettison-1.1.jar 32 | jsqlparser-1.3.jar 33 | jul-to-slf4j-1.7.25.jar 34 | jxl-2.6.12.jar 35 | log4j-1.2.14.jar 36 | log4j-api-2.10.0.jar 37 | log4j-to-slf4j-2.15.0.jar 38 | logback-classic-1.2.3.jar 39 | logback-core-1.2.3.jar 40 | lombok-1.18.12.jar 41 | mapstruct-1.1.0.Final.jar 42 | mybatis-3.4.6.jar 43 | mybatis-plus-3.0.7.1.jar 44 | mybatis-plus-annotation-3.0.7.1.jar 45 | mybatis-plus-boot-starter-3.0.7.1.jar 46 | mybatis-plus-core-3.0.7.1.jar 47 | mybatis-plus-extension-3.0.7.1.jar 48 | mybatis-spring-1.3.2.jar 49 | mysql-connector-java-8.0.11.jar 50 | pf4j-3.1.0.jar 51 | protobuf-java-2.6.0.jar 52 | reflections-0.9.11.jar 53 | slf4j-api-1.7.25.jar 54 | snakeyaml-1.19.jar 55 | spring-aop-5.0.4.RELEASE.jar 56 | spring-beans-5.0.4.RELEASE.jar 57 | spring-boot-2.0.0.RELEASE.jar 58 | spring-boot-autoconfigure-2.0.0.RELEASE.jar 59 | spring-boot-starter-2.0.0.RELEASE.jar 60 | spring-boot-starter-jdbc-2.0.0.RELEASE.jar 61 | spring-boot-starter-json-2.0.0.RELEASE.jar 62 | spring-boot-starter-logging-2.0.0.RELEASE.jar 63 | spring-boot-starter-redis-1.4.1.RELEASE.jar 64 | spring-boot-starter-tomcat-2.0.0.RELEASE.jar 65 | spring-boot-starter-web-2.0.0.RELEASE.jar 66 | spring-context-5.0.4.RELEASE.jar 67 | spring-context-support-5.0.4.RELEASE.jar 68 | spring-core-5.0.4.RELEASE.jar 69 | spring-data-commons-2.0.5.RELEASE.jar 70 | spring-data-keyvalue-2.0.5.RELEASE.jar 71 | spring-data-redis-2.0.5.RELEASE.jar 72 | spring-expression-5.0.4.RELEASE.jar 73 | spring-jcl-5.0.4.RELEASE.jar 74 | spring-jdbc-5.0.4.RELEASE.jar 75 | spring-oxm-5.0.4.RELEASE.jar 76 | spring-plugin-core-1.2.0.RELEASE.jar 77 | spring-plugin-metadata-1.2.0.RELEASE.jar 78 | spring-tx-5.0.4.RELEASE.jar 79 | spring-web-5.0.4.RELEASE.jar 80 | spring-webmvc-5.0.4.RELEASE.jar 81 | springboot-plugin-framework-2.2.1-RELEASE.jar 82 | springboot-plugin-framework-extension-mybatis-2.2.1-RELEASE.jar 83 | springfox-core-2.7.0.jar 84 | springfox-schema-2.7.0.jar 85 | springfox-spi-2.7.0.jar 86 | springfox-spring-web-2.7.0.jar 87 | springfox-swagger-common-2.7.0.jar 88 | springfox-swagger2-2.7.0.jar 89 | stax-api-1.0.1.jar 90 | swagger-annotations-1.5.13.jar 91 | swagger-bootstrap-ui-1.6.jar 92 | swagger-models-1.5.13.jar 93 | tomcat-embed-core-8.5.28.jar 94 | tomcat-embed-el-8.5.28.jar 95 | tomcat-embed-websocket-8.5.28.jar 96 | validation-api-2.0.1.Final.jar -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "CodeScan/Utils" 5 | "fmt" 6 | "github.com/fatih/color" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | fmt.Println(` 12 | 13 | 14 | ' ██████╗ ██████╗ ██████╗ ███████╗███████╗ ██████╗ █████╗ ███╗ ██╗ 15 | ' ██╔════╝██╔═══██╗██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗████╗ ██║ 16 | ' ██║ ██║ ██║██║ ██║█████╗ ███████╗██║ ███████║██╔██╗ ██║ 17 | ' ██║ ██║ ██║██║ ██║██╔══╝ ╚════██║██║ ██╔══██║██║╚██╗██║ 18 | ' ╚██████╗╚██████╔╝██████╔╝███████╗███/.████║╚██████╗██║ ██║██║ ╚████║ 19 | ' ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═══╝ 20 | ' -- by zjacky,xiaoqiuxx 21 | 22 | `) 23 | Utils.Start() 24 | elapsed := time.Since(Utils.StartTime) // 计 25 | color.Green("[+] 扫描完成! 花费时长:%s\n", elapsed) // 算经过的时间 26 | } 27 | --------------------------------------------------------------------------------