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)
    }
}

0x03:项目地址

https://github.com/pureqh/ConfigFind

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注