数据库配置文件查找器
0x00:前言
每次hw,最头疼的问题就是找数据库配置文件,尤其是Java站,有问题就得想办法解决,因此有了这个工具
0x01:原理
原理其实很简单,遍历所有文件,在文件中找关键字
web文件数量和文件夹是很庞大的,因此为了效率,不可能遍历每一个文件,好在JAVA开发中,配置文件后缀一般为.config、.xml、和.profile,所以只需要查找这些特定后缀即可。
解决了需要遍历哪些文件后,接下来一个问题就是如何定位数据库配置文件,众所周知,JAVA数据库连接语法为jdbc:mysql://xxxx,因此,在JAVA配置文件中,jdbc这个关键字一定存在。所以只需要找它就行。
0x02:实现
这里采用go遍历文件夹下的所有文件,并获取特定后缀文件,再在筛选后的文件中查找关键字,其中匹配规则是可以增加的,后期可以修改。
为了适应webshell场景,采用了无控制台静默执行的方式,查找完毕后会在当前目录生成ConfigFind.txt文件,然后手动筛选即可。
package main
import (
"fmt"
"io/ioutil"
"os"
"io"
"strings"
)
//匹配的关键字
var x string = "jdbc"
var x1 string = "user"
var filename = "./ConfigFind.txt"
var f1 *os.File
var err1 error
//获取指定目录下的所有文件和目录
func GetFilesAndDirs(dirPth string) (files []string, dirs []string, err error) {
dir, err := ioutil.ReadDir(dirPth)
if err != nil {
return nil, nil, err
}
PthSep := string(os.PathSeparator)
//suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写
for _, fi := range dir {
if fi.IsDir() { // 目录, 递归遍历
dirs = append(dirs, dirPth+PthSep+fi.Name())
GetFilesAndDirs(dirPth + PthSep + fi.Name())
} else {
// 过滤指定格式
ok := strings.HasSuffix(fi.Name(), ".img")
if ok {
files = append(files, dirPth+PthSep+fi.Name())
}
}
}
return files, dirs, nil
}
//获取指定目录下的所有文件,包含子目录下的文件
func GetAllFiles(dirPth string) (files []string, err error) {
var dirs []string
dir, err := ioutil.ReadDir(dirPth)
if err != nil {
return nil, err
}
PthSep := string(os.PathSeparator)
//suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写
for _, fi := range dir {
if fi.IsDir() { // 目录, 递归遍历
dirs = append(dirs, dirPth+PthSep+fi.Name())
GetAllFiles(dirPth + PthSep + fi.Name())
} else {
// 过滤指定格式
ok := strings.HasSuffix(fi.Name(), ".xml")
ok1 := strings.HasSuffix(fi.Name(), ".profile")
ok2 := strings.HasSuffix(fi.Name(), ".config")
if ok || ok1 || ok2 {
files = append(files, dirPth+PthSep+fi.Name())
}
}
}
// 读取子目录下文件
for _, table := range dirs {
temp, _ := GetAllFiles(table)
for _, temp1 := range temp {
files = append(files, temp1)
}
}
return files, nil
}
//从获取的文件中查找特定值 jdbc 不区分大小写
func findfile(f string) {
content, err := ioutil.ReadFile("./" + f)
if err != nil {
fmt.Println("读取文件失败,错误:", err)
return
}
a := string(content)
if strings.Contains((strings.ToLower(a)), x) || strings.Contains((strings.ToLower(a)), x1){
fmt.Println("该文件可能为数据库配置文件:" + f)
if checkFileIsExist(filename) { //如果文件存在
f1, err1 = os.OpenFile(filename, os.O_APPEND, 0666) //打开文件
} else {
f1, err1 = os.Create(filename) //创建文件
}
check(err1)
io.WriteString(f1, f + "\r\n") //写入文件(字符串)
}
}
func check(e error) {
if e != nil {
panic(e)
}
}
/**
* 判断文件是否存在 存在返回 true 不存在返回false
*/
func checkFileIsExist(filename string) bool {
var exist = true
if _, err := os.Stat(filename); os.IsNotExist(err) {
exist = false
}
return exist
}
func main() {
files, dirs, _ := GetFilesAndDirs("./")
for _, dir := range dirs {
fmt.Printf("当前文件夹为[%s]\n", dir)
}
fmt.Printf("=======================================\n")
for _, table := range dirs {
temp, _, _ := GetFilesAndDirs(table)
for _, temp1 := range temp {
files = append(files, temp1)
}
}
for _, table1 := range files {
findfile(table1)
}
fmt.Printf("=======================================\n")
xfiles, _ := GetAllFiles("./")
for _, file := range xfiles {
findfile(file)
}
}
import (
"fmt"
"io/ioutil"
"os"
"io"
"strings"
)
//匹配的关键字
var x string = "jdbc"
var x1 string = "user"
var filename = "./ConfigFind.txt"
var f1 *os.File
var err1 error
//获取指定目录下的所有文件和目录
func GetFilesAndDirs(dirPth string) (files []string, dirs []string, err error) {
dir, err := ioutil.ReadDir(dirPth)
if err != nil {
return nil, nil, err
}
PthSep := string(os.PathSeparator)
//suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写
for _, fi := range dir {
if fi.IsDir() { // 目录, 递归遍历
dirs = append(dirs, dirPth+PthSep+fi.Name())
GetFilesAndDirs(dirPth + PthSep + fi.Name())
} else {
// 过滤指定格式
ok := strings.HasSuffix(fi.Name(), ".img")
if ok {
files = append(files, dirPth+PthSep+fi.Name())
}
}
}
return files, dirs, nil
}
//获取指定目录下的所有文件,包含子目录下的文件
func GetAllFiles(dirPth string) (files []string, err error) {
var dirs []string
dir, err := ioutil.ReadDir(dirPth)
if err != nil {
return nil, err
}
PthSep := string(os.PathSeparator)
//suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写
for _, fi := range dir {
if fi.IsDir() { // 目录, 递归遍历
dirs = append(dirs, dirPth+PthSep+fi.Name())
GetAllFiles(dirPth + PthSep + fi.Name())
} else {
// 过滤指定格式
ok := strings.HasSuffix(fi.Name(), ".xml")
ok1 := strings.HasSuffix(fi.Name(), ".profile")
ok2 := strings.HasSuffix(fi.Name(), ".config")
if ok || ok1 || ok2 {
files = append(files, dirPth+PthSep+fi.Name())
}
}
}
// 读取子目录下文件
for _, table := range dirs {
temp, _ := GetAllFiles(table)
for _, temp1 := range temp {
files = append(files, temp1)
}
}
return files, nil
}
//从获取的文件中查找特定值 jdbc 不区分大小写
func findfile(f string) {
content, err := ioutil.ReadFile("./" + f)
if err != nil {
fmt.Println("读取文件失败,错误:", err)
return
}
a := string(content)
if strings.Contains((strings.ToLower(a)), x) || strings.Contains((strings.ToLower(a)), x1){
fmt.Println("该文件可能为数据库配置文件:" + f)
if checkFileIsExist(filename) { //如果文件存在
f1, err1 = os.OpenFile(filename, os.O_APPEND, 0666) //打开文件
} else {
f1, err1 = os.Create(filename) //创建文件
}
check(err1)
io.WriteString(f1, f + "\r\n") //写入文件(字符串)
}
}
func check(e error) {
if e != nil {
panic(e)
}
}
/**
* 判断文件是否存在 存在返回 true 不存在返回false
*/
func checkFileIsExist(filename string) bool {
var exist = true
if _, err := os.Stat(filename); os.IsNotExist(err) {
exist = false
}
return exist
}
func main() {
files, dirs, _ := GetFilesAndDirs("./")
for _, dir := range dirs {
fmt.Printf("当前文件夹为[%s]\n", dir)
}
fmt.Printf("=======================================\n")
for _, table := range dirs {
temp, _, _ := GetFilesAndDirs(table)
for _, temp1 := range temp {
files = append(files, temp1)
}
}
for _, table1 := range files {
findfile(table1)
}
fmt.Printf("=======================================\n")
xfiles, _ := GetAllFiles("./")
for _, file := range xfiles {
findfile(file)
}
}