package services import ( "context" "database/sql" "fmt" "strings" // _ "github.com/mattn/go-oci8" // Oracle驱动需要特殊安装,暂时注释 "github.com/shadow1ng/fscan/common" "github.com/shadow1ng/fscan/common/i18n" ) // OraclePlugin Oracle数据库扫描和利用插件 - 包含数据库查询利用功能 type OraclePlugin struct { name string ports []int } // NewOraclePlugin 创建Oracle插件 func NewOraclePlugin() *OraclePlugin { return &OraclePlugin{ name: "oracle", ports: []int{1521, 1522, 1525}, // Oracle端口 } } // GetName 实现Plugin接口 func (p *OraclePlugin) GetName() string { return p.name } // GetPorts 实现Plugin接口 func (p *OraclePlugin) GetPorts() []int { return p.ports } // Scan 执行Oracle扫描 - 弱密码检测 func (p *OraclePlugin) Scan(ctx context.Context, info *common.HostInfo) *ScanResult { target := fmt.Sprintf("%s:%s", info.Host, info.Ports) // 如果禁用暴力破解,只做服务识别 if common.DisableBrute { return p.identifyService(ctx, info) } // 生成测试凭据 credentials := GenerateCredentials("oracle") if len(credentials) == 0 { // Oracle默认凭据 credentials = []Credential{ {Username: "sys", Password: "sys"}, {Username: "sys", Password: "system"}, {Username: "sys", Password: "oracle"}, {Username: "system", Password: "system"}, {Username: "system", Password: "oracle"}, {Username: "system", Password: "manager"}, {Username: "scott", Password: "tiger"}, {Username: "oracle", Password: "oracle"}, {Username: "admin", Password: "admin"}, } } // 逐个测试凭据 for _, cred := range credentials { // 检查Context是否被取消 select { case <-ctx.Done(): return &ScanResult{ Success: false, Service: "oracle", Error: ctx.Err(), } default: } // 测试凭据 if db := p.testCredential(ctx, info, cred); db != nil { db.Close() // 关闭测试连接 // Oracle认证成功 common.LogSuccess(i18n.GetText("oracle_scan_success", target, cred.Username, cred.Password)) return &ScanResult{ Success: true, Service: "oracle", Username: cred.Username, Password: cred.Password, } } } // 所有凭据都失败 return &ScanResult{ Success: false, Service: "oracle", Error: fmt.Errorf("未发现弱密码"), } } // Exploit 执行Oracle利用操作 - 实现数据库查询功能 func (p *OraclePlugin) Exploit(ctx context.Context, info *common.HostInfo, creds Credential) *ExploitResult { // 建立Oracle连接 db := p.testCredential(ctx, info, creds) if db == nil { return &ExploitResult{ Success: false, Error: fmt.Errorf("Oracle连接失败"), } } defer db.Close() target := fmt.Sprintf("%s:%s", info.Host, info.Ports) common.LogSuccess(fmt.Sprintf("Oracle利用开始: %s (用户: %s)", target, creds.Username)) var output strings.Builder output.WriteString(fmt.Sprintf("=== Oracle利用结果 - %s ===\n", target)) // 获取版本信息 if version := p.getVersion(db); version != "" { output.WriteString(fmt.Sprintf("\n[版本信息]\n%s\n", version)) } // 获取数据库信息 if dbInfo := p.getDatabaseInfo(db); dbInfo != "" { output.WriteString(fmt.Sprintf("\n[数据库信息]\n%s\n", dbInfo)) } // 获取表空间信息 if tablespaces := p.getTablespaces(db); len(tablespaces) > 0 { output.WriteString(fmt.Sprintf("\n[表空间] (共%d个)\n", len(tablespaces))) for i, ts := range tablespaces { if i >= 5 { // 限制显示前5个 output.WriteString("... (更多表空间)\n") break } output.WriteString(fmt.Sprintf(" %s\n", ts)) } } // 获取用户列表 if users := p.getUsers(db); len(users) > 0 { output.WriteString(fmt.Sprintf("\n[用户列表] (共%d个)\n", len(users))) for i, user := range users { if i >= 10 { // 限制显示前10个用户 output.WriteString("... (更多用户)\n") break } output.WriteString(fmt.Sprintf(" %s\n", user)) } } // 获取表列表(当前用户) if tables := p.getTables(db, creds.Username); len(tables) > 0 { output.WriteString(fmt.Sprintf("\n[用户表] (共%d个)\n", len(tables))) for i, table := range tables { if i >= 5 { // 限制显示前5个表 output.WriteString("... (更多表)\n") break } output.WriteString(fmt.Sprintf(" %s\n", table)) } } // 获取权限信息 if privileges := p.getPrivileges(db, creds.Username); privileges != "" { output.WriteString(fmt.Sprintf("\n[用户权限]\n%s\n", privileges)) } common.LogSuccess(fmt.Sprintf("Oracle利用完成: %s", target)) return &ExploitResult{ Success: true, Output: output.String(), } } // testCredential 测试单个凭据 - 返回数据库连接或nil func (p *OraclePlugin) testCredential(ctx context.Context, info *common.HostInfo, cred Credential) *sql.DB { // Oracle驱动需要特殊安装,这里简化实现 // 在实际环境中需要安装Oracle客户端和go-oci8驱动 return nil } // getVersion 获取Oracle版本信息 func (p *OraclePlugin) getVersion(db *sql.DB) string { var version string err := db.QueryRow("SELECT banner FROM v$version WHERE rownum = 1").Scan(&version) if err != nil { // 尝试备用查询 err = db.QueryRow("SELECT version FROM product_component_version WHERE rownum = 1").Scan(&version) if err != nil { return "" } } return version } // getDatabaseInfo 获取数据库基本信息 func (p *OraclePlugin) getDatabaseInfo(db *sql.DB) string { var info strings.Builder // 获取数据库名 var dbName string err := db.QueryRow("SELECT name FROM v$database").Scan(&dbName) if err == nil { info.WriteString(fmt.Sprintf("数据库名: %s\n", dbName)) } // 获取实例名 var instanceName string err = db.QueryRow("SELECT instance_name FROM v$instance").Scan(&instanceName) if err == nil { info.WriteString(fmt.Sprintf("实例名: %s\n", instanceName)) } // 获取字符集 var charset string err = db.QueryRow("SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET'").Scan(&charset) if err == nil { info.WriteString(fmt.Sprintf("字符集: %s\n", charset)) } return info.String() } // getTablespaces 获取表空间列表 func (p *OraclePlugin) getTablespaces(db *sql.DB) []string { query := "SELECT tablespace_name FROM dba_tablespaces" rows, err := db.Query(query) if err != nil { // 尝试用户表空间查询 query = "SELECT tablespace_name FROM user_tablespaces" rows, err = db.Query(query) if err != nil { return nil } } defer rows.Close() var tablespaces []string for rows.Next() { var tsName string if err := rows.Scan(&tsName); err == nil { tablespaces = append(tablespaces, tsName) } } return tablespaces } // getUsers 获取用户列表 func (p *OraclePlugin) getUsers(db *sql.DB) []string { query := "SELECT username FROM dba_users ORDER BY username" rows, err := db.Query(query) if err != nil { // 尝试all_users query = "SELECT username FROM all_users ORDER BY username" rows, err = db.Query(query) if err != nil { return nil } } defer rows.Close() var users []string for rows.Next() { var userName string if err := rows.Scan(&userName); err == nil { users = append(users, userName) } } return users } // getTables 获取指定用户的表列表 func (p *OraclePlugin) getTables(db *sql.DB, owner string) []string { query := "SELECT table_name FROM dba_tables WHERE owner = :1 ORDER BY table_name" rows, err := db.Query(query, strings.ToUpper(owner)) if err != nil { // 尝试用户表查询 query = "SELECT table_name FROM user_tables ORDER BY table_name" rows, err = db.Query(query) if err != nil { return nil } } defer rows.Close() var tables []string for rows.Next() { var tableName string if err := rows.Scan(&tableName); err == nil { tables = append(tables, tableName) } } return tables } // getPrivileges 获取用户权限信息 func (p *OraclePlugin) getPrivileges(db *sql.DB, username string) string { var privileges strings.Builder // 检查DBA权限 var dbaRole int err := db.QueryRow("SELECT COUNT(*) FROM dba_role_privs WHERE grantee = :1 AND granted_role = 'DBA'", strings.ToUpper(username)).Scan(&dbaRole) if err == nil && dbaRole > 0 { privileges.WriteString("DBA权限: YES\n") } else { privileges.WriteString("DBA权限: NO\n") } // 检查SYSDBA权限 var sysdbaCount int err = db.QueryRow("SELECT COUNT(*) FROM v$pwfile_users WHERE username = :1 AND sysdba = 'TRUE'", strings.ToUpper(username)).Scan(&sysdbaCount) if err == nil && sysdbaCount > 0 { privileges.WriteString("SYSDBA权限: YES\n") } // 获取角色列表 query := "SELECT granted_role FROM dba_role_privs WHERE grantee = :1 AND rownum <= 5" rows, err := db.Query(query, strings.ToUpper(username)) if err == nil { defer rows.Close() privileges.WriteString("已授予角色: ") var roles []string for rows.Next() { var role string if err := rows.Scan(&role); err == nil { roles = append(roles, role) } } if len(roles) > 0 { privileges.WriteString(strings.Join(roles, ", ") + "\n") } else { privileges.WriteString("无\n") } } return privileges.String() } // identifyService 服务识别 - 检测Oracle服务 func (p *OraclePlugin) identifyService(ctx context.Context, info *common.HostInfo) *ScanResult { // Oracle驱动需要特殊安装,这里简化实现 // 在实际环境中需要安装Oracle客户端和go-oci8驱动 return &ScanResult{ Success: false, Service: "oracle", Error: fmt.Errorf("Oracle驱动未安装"), } } // init 自动注册插件 func init() { RegisterPlugin("oracle", func() Plugin { return NewOraclePlugin() }) }