VIOLENT PYTHON

#2 MAKING A PORT SCANNER

Η συγκέντρωση πληροφοριών είναι το πρώτο και σημαντικότερο βήμα για να έχουμε ένα σωστό αποτέλεσμα, όσον αφορά την εύρεση του στόχου και την επιλογή του κατάλληλου exploit(προς τον στόχο αυτόν).

Στις ακόλουθες παραγράφους θα δημιουργήσουμε ένα script το οποίο θα σκανάρει τον host του θύματος για να βρει ανοικτές θύρες. Όπως και να χει για να αλληλεπιδράσουμε με τις TCP θύρες θα χρειαστούμε να οικοδομήσουμε πρώτα TCP sockets.

Η Python όπως οι περισσότερες μοντέρνες γλώσσες έχει πρόσβαση στον BSD socket interface.

Οι BSD sockets παρέχουν ένα interface που επιτρέπει στους coders να γράφουν εφαρμογές με σκοπό να πραγματοποιούν διαδικτυακή επικοινωνία μεταξύ δύο υπολογιστών. Μέσα από μια σειρά απο socket ΑPI λειτουργιών, μπορούμε να δημιουργήσουμε και να συνδεθούμε με TCP/IP sockets.

Σ αυτό το σημείο μια καλύτερη κατανόηση του TCP/IP και των sockets χρειάζεται για να αναπτύξουμε καλύτερα τις επιθέσεις μας.

Η πλειοψηφία των εφαρμογών που έχουν πρόσβαση στο διαδίκτυο βασίζονται στην TCP. Για παράδειγμα σ'έναν στοχευμένο οργανισμό, ο web server μπορεί να βασίζεται στην TCP θύρα 80, το email στην θύρα 25 και η μεταφορά φακέλων στην θύρα 21. Για να συνδεθείς σε οποιαδήποτε απο αυτές τις υπηρεσίες πρέπει να να ξέρεις την IP και TCP θύρα που σχετίζονται μ'αυτές.

 Ένας τύπος port scan είναι να στέλνεις TCP SYN πακέτα σε μια σειρά απο θύρες και να περιμένεις μια TCP ACK απάντηση που θα χει ως αποτέλεσμα να βρει μια ανοιχτή θύρα.

Οπότε ας ξεκινήσουμε να γράφουμε τον δικό μας TCP port scanner.

Η Socket API μας παρέχει κάποιες λειτουργίες που θα μας είναι χρήσιμες για να δημιουργήσουμε τον TCP port scanner μας. Ας εξετάσουμε μερικές(Για καλύτερη κατανόηση http://docs.Python.org/library/socket.html.)

socket.gethostbyname(hostname) –Αυτή η λειτουργία παίρνει μια διεύθυνση(www.google.com) και την μετατρέπει σε IPv4 διεύθυνση, όπως 69.163.177.2.

socket.gethostbyaddr(ip address) –Αυτή η λειτουργία παίρνει μια IPv4 διεύθυνση και την μετατρέπει σε hostname.

socket.socket([family[, type[, proto]]]) –Δημιουργεί ένα νέο socket στην οικογένεια των sockets όπως AF_INET, AF_INET6 ΑF_UNIX κλπ.

socket.create_connection(address[, timeout[, source_address]]).

Για να καταλάβουμε καλύτερα πως δουλεύει το TCP Port Scanner θα σπάσουμε το πρόγραμμ αμας σε πέντε βήματα. Πρώτα θα τοποθετήσουμε ένα Hostname και μία λίστα απο θύρες για να σκαναριστούν.

Μετά θα μεταφράσουμε το hostname σε IPv4 διεύθυνση.Για κάθε θύρα στην λίστα θα συνδεθούμε με την  διεύθυνση του στόχου και την συγκεκριμένη θύρα.

Τέλος θα στείλουμε garbage data και θα διαβάσουμε τα αποτελέσματα των Banners.

Στο πρώτο μας βήμα, θα δεχτούμε το hostname και την θύρα απο τον χρήστη. Γι'αυτό το πρόγραμμα μας θα χρησιμοποιήσει την optparse βιβλιοθήκη για να έχει command-line επιλογές.

To επόμενο παράδειγμα δείχνει μια σύντομη μέθοδο για να αναλύουμε την θύρα και το hostname για να σκανάρουμε:

import optparse
parser = optparse.OptionParser('usage %prog –H'+\
   '<target host> -p <target port>')

parser.add_option('-H', dest='tgtHost', type='string', \
   help='specify target host')

parser.add_option('-p', dest='tgtPort', type='int', \
   help='specify target port')

(options, args) = parser.parse_args()

tgtHost = options.tgtHost
tgtPort = options.tgtPort
if (tgtHost == None) | (tgtPort == None):
  print parser.usage
  exit(0)

Μετά θα δημιουργήσουμε δύο λειτουργίες connScan και portScan. H πρώτη λειτουργία θα παίρνει  το Hostname και τις Ports σαν arguments. Θα προσπαθήσει πρώτα να αναλύσει την IP σε ένα φιλικό hostname χρησιμοποιώντας το gethostbyname().

Mετά θα τυπώνει το hostname και θα απαριθμεί κάθε Port που θα θέλει να συνδεθεί χρησιμοποιώντας την connScan function.

Η connScan  θα προσπαθήσει να δημιουργήσει σύνδεση στον επιτιθέμενο host και port.

import optparse
from socket import *
def connScan(tgtHost, tgtPort):
    try:
       connSkt = socket(AF_INET, SOCK_STREAM)
       connSkt.connect((tgtHost, tgtPort))
       print '[+]%d/tcp open'% tgtPort
       connSkt.close()
except:
       print '[-]%d/tcp closed'% tgtPort
def portScan(tgtHost, tgtPorts):
    try:
       tgtIP = gethostbyname(tgtHost)
except:
      print "[-] Cannot resolve '%s': Unknown host"%tgtHost
      return
try:
     tgtName = gethostbyaddr(tgtIP)
     print '\n[+] Scan Results for: ' + tgtName[0]
except:
     print '\n[+] Scan Results for: ' + tgtIP
setdefaulttimeout(1)
for tgtPort in tgtPorts:
    print 'Scanning port ' + tgtPort
   connScan(tgtHost, int(tgtPort))

Παρακάτω αφού βρούμε κάποια ανοιχτή θύρα θα στείλουμε data στην θύρα και περιμένουμε για απάντηση. Απ'αυτήν την απάντηση μπορούμε να δούμε ποια εφαρμογή τρέχει στην θύρα αυτή.

import optparse
import socket
from socket import *
def connScan(tgtHost, tgtPort):
    try:
        connSkt = socket(AF_INET, SOCK_STREAM)
       connSkt.connect((tgtHost, tgtPort))
       connSkt.send('ViolentPython\r\n')
       results = connSkt.recv(100)
       print '[+]%d/tcp open'% tgtPort
       print '[+] ' + str(results)
      connSkt.close()
except:
      print '[-]%d/tcp closed'% tgtPort
def portScan(tgtHost, tgtPorts):
     try:
      tgtIP = gethostbyname(tgtHost)
except:
      print "[-] Cannot resolve '%s': Unknown host" %tgtHost
      return
try:
     tgtName = gethostbyaddr(tgtIP)
     print '\n[+] Scan Results for: ' + tgtName[0]
except:
   print '\n[+] Scan Results for: ' + tgtIP
setdefaulttimeout(1)
for tgtPort in tgtPorts:
   print 'Scanning port ' + tgtPort
   connScan(tgtHost, int(tgtPort))
def main():
   parser = optparse.OptionParser("usage%prog "+\
         "-H <target host> -p <target port>")
parser.add_option('-H', dest='tgtHost', type='string', \
     help='specify target host')
parser.add_option('-p', dest='tgtPort', type='string', \
    help='specify target port[s] separated by comma')
(options, args) = parser.parse_args()
tgtHost = options.tgtHost
tgtPorts = str(options.tgtPort).split(', ')
if (tgtHost == None) | (tgtPorts[0] == None):
    print '[-] You must specify a target host and port[s].'
   exit(0)
portScan(tgtHost, tgtPorts)
if __name__ == '__main__':
   main()

Το αποτέλεσμα θα είναι:

attacker$ python portscanner.py -H 192.168.1.37 -p 21, 22, 80
[+] Scan Results for: 192.168.1.37
Scanning port 21
[+] 21/tcp open
[+] 220 FreeFloat Ftp Server (Version 1.00)



#1 UNIX PASSWORD CRACKER USING PYTHON

Η αληθινή δύναμη της γλώσσας PYTHON βρίσκεται  στην μεγάλη ποικιλία των βιβλιοθηκών της. Για να γράψουμε τον UNIX password cracker θα χρειαστεί να χρησιμοποιήσουμε τον crypt() αλγόριθμο ο οποίος κάνει hash τους Unix κωδικούς. Ανοίγουμε τον διερμηνέα μας και θα δούμε ότι η crypt βιβλιοθήκη υπάρχει ήδη στην standard βιβλιοθήκη.


Ας προσπαθήσουμε να κάνουμε hash έναν κωδικό χρησιμοποιώντας την λειτουργία crypt(). Αφού εισάγουμε την βιβλιοθήκη, γράφουμε τον κωδικό "egg" και τον salt "HX". To αποτέλεσμα είναι: 'HX9LLTdc/jiDE'. Τώρα μπορούμε να γράψουμε ένα πρόγραμμα το οποίο θα δοκιμάζει κάθε λέξη ενός ολόκληρου λεξικού μαζί με το κατάλληλο salt για το hashed pass.

 programmer$ python
>>> import crypt
>>> crypt.crypt("egg","HX")
'HX9LLTdc/jiDE'

Για να γράψουμε το πρόγραμμα μας, θα δημιουργήσουμε δύο λειτουργίες-main και tespass. Είναι μια καλή προγραμματιστική πρακτική το να ξεχωρίζεις το πρόγραμμα σε ξεχωριστές λειτουργίες, κάθε μία με συγκεκριμένο σκοπό(σ.σ Αυτά είναι σχόλια του συγγραφέα, τα οποία πολλές φορές είναι λίγο retro, όπως και ο κώδικας του που πραγματικά είναι πολύ old school.Δεν έχει σημασία όμως το πάν σε ένα tutorial είναι η γενική ιδέα παρά η ακριβής εκτέλεση του, η οποία δεν έχει και νόημα στην τελική).

Η κύρια μας λειτουργία ανοίγει τον κρυπτογραφημένο φάκελο:"passwords.txt" και διαβάζει τα περιεχόμενα κάθε γραμμής του φακέλου. Για κάθε γραμμή, χωρίζει το Username  και το Hashed pass. Για κάθε hashed pass, η κύρια λειτουργία καλεί το testPass() που τεστάρει τους κωδικούς με το λεξικό.

Η testPass(), παίρνει το κρυπτογραφημένο κωδικό σαν παράμετρο και τον επιστρέφει αφού βρει τον κωδικό ή αφού τελειώσουν οι λέξεις στο λεξικό. Παρατηρείστε ότι η λειτουργία πρώτα πετάει τους δύο χαρακτήρες του salt και μετά ανοίγει το λεξικό.

Αν το αποτέλεσμα ταιριάζει με το κρυπτογραφημένο hash βγαίνει ένα μήνυμα το οποίο δηλώνει την εύρεση του password αλλιώς συνεχίζει να ψάχνει στο λεξικό.


import crypt
def testPass(cryptPass):
   salt = cryptPass[0:2]
dictFile = open('dictionary.txt','r')
for word in dictFile.readlines():
  word = word.strip('\n')
  cryptWord = crypt.crypt(word,salt)
  if (cryptWord == cryptPass):
     print "[+] Found Password: "+word+"\n"
     return
  print "[-] Password Not Found.\n"
  return
def main():
  passFile = open('passwords.txt')
  for line in passFile.readlines():
    if ":" in line:
      user = line.split(':')[0]
      cryptPass = line.split(':')[1].strip(' ')
      print "[*] Cracking Password For: "+user
      testPass(cryptPass)
if __name__ == "__main__":
   main()

Όπως βλέπουμε το πρόγραμμα μας σπάει τον κωδικό του θύματος αλλά όχι του root. Αυτό σημαίνει οτι δεν χρησιμοποιεί ο administrator λέξεις του λεξικού μας.
Δεν χρειάζεται ανησυχία , θα καλύψουμε μερικούς άλλους τρόπους αργότερα για να έχουμε πρόσβαση στο root.

programmer$ python crack.py
[*] Cracking Password For: victim
[+] Found Password: egg
[*] Cracking Password For: root
[-] Password Not Found.





    Blogger Comment
    Facebook Comment

0 σχόλια:

Δημοσίευση σχολίου