fscan/plugins/services/oracle.go
ZacharyZcR 6cf5719e8a refactor: 彻底清理插件系统,消除虚假利用功能
- 删除整个legacy插件系统(7794行代码)
- 完成所有插件向单文件架构迁移
- 移除19个插件的虚假Exploit功能,只保留真实利用:
  * Redis: 文件写入、SSH密钥注入、计划任务
  * SSH: 命令执行
  * MS17010: EternalBlue漏洞利用
- 统一插件接口,简化架构复杂度
- 清理临时文件和备份文件

重构效果:
- 代码行数: -7794行
- 插件文件数: 从3文件架构→单文件架构
- 真实利用插件: 从22个→3个
- 架构复杂度: 大幅简化
2025-08-26 11:43:48 +08:00

287 lines
7.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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("未发现弱密码"),
}
}
// 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()
})
}