Skip to content

Commit

Permalink
feat(wp): support csh, no sudo scan (#1523)
Browse files Browse the repository at this point in the history
Co-authored-by: MaineK00n <mainek00n.1229@gmail.com>
  • Loading branch information
kurita0 and MaineK00n authored Mar 28, 2023
1 parent 8ccaa8c commit e506125
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 24 deletions.
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ type WordPressConf struct {
OSUser string `toml:"osUser,omitempty" json:"osUser,omitempty"`
DocRoot string `toml:"docRoot,omitempty" json:"docRoot,omitempty"`
CmdPath string `toml:"cmdPath,omitempty" json:"cmdPath,omitempty"`
NoSudo bool `toml:"noSudo,omitempty" json:"noSudo,omitempty"`
}

// IsZero return whether this struct is not specified in config.toml
Expand Down
1 change: 1 addition & 0 deletions config/config_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ type WordPressConf struct {
OSUser string `toml:"osUser,omitempty" json:"osUser,omitempty"`
DocRoot string `toml:"docRoot,omitempty" json:"docRoot,omitempty"`
CmdPath string `toml:"cmdPath,omitempty" json:"cmdPath,omitempty"`
NoSudo bool `toml:"noSudo,omitempty" json:"noSudo,omitempty"`
}

// IsZero return whether this struct is not specified in config.toml
Expand Down
93 changes: 69 additions & 24 deletions scanner/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -817,39 +817,93 @@ func (d *DummyFileInfo) IsDir() bool { return false }
// Sys is
func (d *DummyFileInfo) Sys() interface{} { return nil }

func (l *base) buildWpCliCmd(wpCliArgs string, suppressStderr bool, shell string) string {
cmd := fmt.Sprintf("%s %s --path=%s", l.ServerInfo.WordPress.CmdPath, wpCliArgs, l.ServerInfo.WordPress.DocRoot)
if !l.ServerInfo.WordPress.NoSudo {
cmd = fmt.Sprintf("sudo -u %s -i -- %s --allow-root", l.ServerInfo.WordPress.OSUser, cmd)
} else if l.ServerInfo.User != l.ServerInfo.WordPress.OSUser {
cmd = fmt.Sprintf("su %s -c '%s'", l.ServerInfo.WordPress.OSUser, cmd)
}

if suppressStderr {
switch shell {
case "csh", "tcsh":
cmd = fmt.Sprintf("( %s > /dev/tty ) >& /dev/null", cmd)
default:
cmd = fmt.Sprintf("%s 2>/dev/null", cmd)
}
}
return cmd
}

func (l *base) scanWordPress() error {
if l.ServerInfo.WordPress.IsZero() || l.ServerInfo.Type == constant.ServerTypePseudo {
return nil
}

shell, err := l.detectShell()
if err != nil {
return xerrors.Errorf("Failed to detect shell. err: %w", err)
}

l.log.Info("Scanning WordPress...")
cmd := fmt.Sprintf("sudo -u %s -i -- %s core version --path=%s --allow-root",
l.ServerInfo.WordPress.OSUser,
l.ServerInfo.WordPress.CmdPath,
l.ServerInfo.WordPress.DocRoot)
if l.ServerInfo.WordPress.NoSudo && l.ServerInfo.User != l.ServerInfo.WordPress.OSUser {
if r := l.exec(fmt.Sprintf("timeout 2 su %s -c exit", l.ServerInfo.WordPress.OSUser), noSudo); !r.isSuccess() {
return xerrors.New("Failed to switch user without password. err: please configure to switch users without password")
}
}

cmd := l.buildWpCliCmd("core version", false, shell)
if r := exec(l.ServerInfo, cmd, noSudo); !r.isSuccess() {
return xerrors.Errorf("Failed to exec `%s`. Check the OS user, command path of wp-cli, DocRoot and permission: %#v", cmd, l.ServerInfo.WordPress)
}

wp, err := l.detectWordPress()
wp, err := l.detectWordPress(shell)
if err != nil {
return xerrors.Errorf("Failed to scan wordpress: %w", err)
}
l.WordPress = *wp
return nil
}

func (l *base) detectWordPress() (*models.WordPressPackages, error) {
ver, err := l.detectWpCore()
func (l *base) detectShell() (string, error) {
if r := l.exec("printenv SHELL", noSudo); r.isSuccess() {
if t := strings.TrimSpace(r.Stdout); t != "" {
return filepath.Base(t), nil
}
}

if r := l.exec(fmt.Sprintf(`grep "^%s" /etc/passwd | awk -F: '/%s/ { print $7 }'`, l.ServerInfo.User, l.ServerInfo.User), noSudo); r.isSuccess() {
if t := strings.TrimSpace(r.Stdout); t != "" {
return filepath.Base(t), nil
}
}

if isLocalExec(l.ServerInfo.Port, l.ServerInfo.Host) {
if r := l.exec("ps -p $$ | tail +2 | awk '{print $NF}'", noSudo); r.isSuccess() {
return strings.TrimSpace(r.Stdout), nil
}

if r := l.exec("ps -p %self | tail +2 | awk '{print $NF}'", noSudo); r.isSuccess() {
return strings.TrimSpace(r.Stdout), nil
}
}

return "", xerrors.New("shell cannot be determined")
}

func (l *base) detectWordPress(shell string) (*models.WordPressPackages, error) {
ver, err := l.detectWpCore(shell)
if err != nil {
return nil, err
}

themes, err := l.detectWpThemes()
themes, err := l.detectWpThemes(shell)
if err != nil {
return nil, err
}

plugins, err := l.detectWpPlugins()
plugins, err := l.detectWpPlugins(shell)
if err != nil {
return nil, err
}
Expand All @@ -866,11 +920,8 @@ func (l *base) detectWordPress() (*models.WordPressPackages, error) {
return &pkgs, nil
}

func (l *base) detectWpCore() (string, error) {
cmd := fmt.Sprintf("sudo -u %s -i -- %s core version --path=%s --allow-root 2>/dev/null",
l.ServerInfo.WordPress.OSUser,
l.ServerInfo.WordPress.CmdPath,
l.ServerInfo.WordPress.DocRoot)
func (l *base) detectWpCore(shell string) (string, error) {
cmd := l.buildWpCliCmd("core version", true, shell)

r := exec(l.ServerInfo, cmd, noSudo)
if !r.isSuccess() {
Expand All @@ -879,11 +930,8 @@ func (l *base) detectWpCore() (string, error) {
return strings.TrimSpace(r.Stdout), nil
}

func (l *base) detectWpThemes() ([]models.WpPackage, error) {
cmd := fmt.Sprintf("sudo -u %s -i -- %s theme list --path=%s --format=json --allow-root 2>/dev/null",
l.ServerInfo.WordPress.OSUser,
l.ServerInfo.WordPress.CmdPath,
l.ServerInfo.WordPress.DocRoot)
func (l *base) detectWpThemes(shell string) ([]models.WpPackage, error) {
cmd := l.buildWpCliCmd("theme list --format=json", true, shell)

var themes []models.WpPackage
r := exec(l.ServerInfo, cmd, noSudo)
Expand All @@ -900,11 +948,8 @@ func (l *base) detectWpThemes() ([]models.WpPackage, error) {
return themes, nil
}

func (l *base) detectWpPlugins() ([]models.WpPackage, error) {
cmd := fmt.Sprintf("sudo -u %s -i -- %s plugin list --path=%s --format=json --allow-root 2>/dev/null",
l.ServerInfo.WordPress.OSUser,
l.ServerInfo.WordPress.CmdPath,
l.ServerInfo.WordPress.DocRoot)
func (l *base) detectWpPlugins(shell string) ([]models.WpPackage, error) {
cmd := l.buildWpCliCmd("plugin list --format=json", true, shell)

var plugins []models.WpPackage
r := exec(l.ServerInfo, cmd, noSudo)
Expand Down
1 change: 1 addition & 0 deletions subcmds/discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ host = "{{$ip}}"
#cmdPath = "/usr/local/bin/wp"
#osUser = "wordpress"
#docRoot = "/path/to/DocumentRoot/"
#noSudo = false
#[servers.{{index $names $i}}.portscan]
#scannerBinPath = "/usr/bin/nmap"
Expand Down

0 comments on commit e506125

Please sign in to comment.