[python]Code snippet to encrypt and decrypt password.

This is a code snippet which i want to use to store a password input by user, and encrypt it. My intention is to test this code snippet so that I can store the ciphertext in a file, and decrypt the cipher text file by python

import os
from getpass import getpass as GP
from Crypto.Cipher import AES
from Crypto import Random

#Prompts password, the default prompt if not specified is Password:
#When use in terminal, password entered by user will not be echoed.
password = GP(prompt='Enter password:',stream=None)

#use os.urandom() method to create a random 16 bytes string
#convert to bytes. On this example I want to use AES-128 hence 16bytes key.
#16, 24, 32bytes are AES-128,192 and 256 bits respectively.
key = bytes(os.urandom(16))

#To generate an initializing vector, fixed block size is 16 bytes.
iv = Random.new().read(AES.block_size)

#Create a cipher to use for encryption
cipher = AES.new(key,AES.MODE_CFB,iv)

#encrypts the password entered by user
ciphertext = cipher.encrypt(password)

#ciphertext is in bytes, so i open create a file - password.enc
#write the bytes into this file
with open('password.enc', 'wb') as file:
    file.write(ciphertext)
    file.close()

#print(ciphertext)

#Create a decipher to decrypt the ciphertext
decipher = AES.new(key,AES.MODE_CFB,iv)

#read byte from file
with open('password.enc', 'rb') as file:
    ctext = file.read()
    file.close()
#decrypt the ciphertext
plaintext = decipher.decrypt(ctext)

#To convert the plaintext in bytes to string, use decode "utf-8"
#print(plaintext.decode('utf-8'))
print(plaintext.decode('utf-8'))
Advertisements
Posted in Python, Scripting | Tagged , , , | Leave a comment

[Python]Adding firewall rules to Palo Alto using PA REST API

I was experimenting on adding firewall rules using the Palo Alto REST API. Did a few tries and finally got the result.

This code is very static, the intent is to test how to organize the xml elements so that the rules can be added.

import requests, time
from bs4 import BeautifulSoup as BS


rule_path = "/config/devices/entry[@name='localhost.localdomain']/vsys/entry[@name='vsys1']/rulebase/security/rules"
sample_rule = """
<entry name="API_Test_again">
    <source>
        <member>192.168.20.125</member>
    </source>
    <destination>
        <member>pool.ntp.org-128.199.224.229</member>
    </destination>
    <service>
        <member>udp-123</member>
    </service>
    <application>
        <member>any</member>
    </application>
    <action>allow</action>
    <log-end>yes</log-end>
    <from>
        <member>any</member>
    </from>
    <to>
        <member>any</member>
    </to>

</entry>
"""


try:
    response = requests.get("https://192.168.1.104/api/?type=keygen&user=admin&password=admin", verify=False, timeout=5)
    response.raise_for_status()
except requests.exceptions.RequestException as e:
    print(e)
except requests.exceptions.HTTPError as httperr:
    print(httperr)
except requests.exceptions.Timeout as timeouterr:
    print(timeouterr)
except requests.exceptions.ConnectionError as connerr:
    print(connerr)
except requests.exceptions.ConnectTimeout as conntimeout:
    print(conntimeout)

try:
    soup = BS(response.content, 'html.parser')
    key = soup.find('key').text
except AttributeError as ae:
    print("Error while parsing response:",ae)

try:
    r = requests.post("https://192.168.1.104/api/?type=config&action=set&key={}&xpath={}&element={}".format(key,rule_path,sample_rule),verify=False,timeout=5)
    r.raise_for_status()
except requests.exceptions.RequestException as e:
    print(e)
except requests.exceptions.HTTPError as httperr:
    print(httperr)
except requests.exceptions.Timeout as timeouterr:
    print(timeouterr)
except requests.exceptions.ConnectionError as connerr:
    print(connerr)
except requests.exceptions.ConnectTimeout as conntimeout:
    print(conntimeout)
time.sleep(3)

try:
    commit_response = requests.post("https://192.168.1.104/api/?type=commit&key={}&cmd=<commit></commit>".format(key),verify=False,timeout=5)
    commit_response.raise_for_status()
except requests.exceptions.RequestException as e:
    print(e)
except requests.exceptions.HTTPError as httperr:
    print(httperr)
except requests.exceptions.Timeout as timeouterr:
    print(timeouterr)
except requests.exceptions.ConnectionError as connerr:
    print(connerr)
except requests.exceptions.ConnectTimeout as conntimeout:
    print(conntimeout)

Result
Snip20171205_14

Posted in Python, Scripting | Tagged , | Leave a comment

[python]Simple tcp client

So here’s the simple code:

import socket

host = '192.168.1.152'
port = 8080
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect((host,port))
client.send(b'GET / HTTP/1.1\r\nHost: 192.168.1.152\r\n\r\n')
response = client.recv(4096)
print(response)

So first create an object client, the attributes are IPV4 (socket.AF_INET) and tcp (socket.SOCK_STREAM).

Use the send method to send http request, must send the msg in bytes, hence the b.

Posted in Python, Scripting | Tagged , , | Leave a comment

[python]Intrusive python: Reacting with interactive prompt with pexpect

Ok, I am reading some stuffs about brute forcing ssh server. So here is a python module that deals with possible interactive prompts.

The target server is a cisco router, I have put in all possible expected prompts.Such as:
1. if there is a timeout?
2. if there is an unknown ssh key prompting you to accept or not?
3. put in a password when the password prompt appears.

This code sample can be modified to read in dictionary of passwords, supposed the username is “admin” or “cisco”, in this example the code is against the username “cisco”

import pexpect

prompt = ">"
def send_command(session,cmd):
    session.sendline(cmd)
    session.expect(prompt)
    print(session.before)

def connect(username,password,host):
    ssh_unknown_key = "Are you sure you want to continue connecting"
    conn_params = "ssh " + username + "@" + host
    session = pexpect.spawn(conn_params)
    response = session.expect([pexpect.TIMEOUT, ssh_unknown_key, '[P|p]assword:'])
    if response == 0:
        print("Error connecting!")
        return
    if response == 1:
        session.sendline('yes')
        response = session.expect([pexpect.TIMEOUT, '[P|p]assword:'])
        if response == 0:
            print("Error connecting!")
            return
    session.sendline(password)
    session.expect(prompt)
    return session

def main():
    username = 'cisco'
    password = 'cisco'
    host = '192.168.1.150'
    cmd = 'sh version | in Cisco IOS'
    session = connect(username,password,host)
    send_command(session,cmd)

if __name__ == '__main__':
    main()

The result looks like this:

'sh version | in Cisco IOS\r\nCisco IOS Software, Linux Software (I86BI_LINUX-ADVENTERPRISEK9-M), Version 15.5(2)T, DEVELOPMENT TEST SOFTWARE\r\nrouter'

Posted in Python, Scripting | Tagged , | Leave a comment

[python]Intrusive python with nmap

So i was trying some simple script to invoke nmap with python. So here is a python command line version.
The python script takes in two types of arguments:
a. target host
b. target port/ports.

the port if more than one should separate by commas. The split method is called to put each port into an array dports

So here’s the code sample:

import nmap
from optparse import OptionParser

def nmapScan(dhost,dport):
    nm = nmap.PortScanner()
    nm.scan(dhost,dport)
    state = nm[dhost]['tcp'][int(dport)]['state']
    print("[*] " + dhost + " " + "tcp/"+dport + " " + state)


def main():
    parser = OptionParser(usage='usage: %prog -d <destination host> -p <destination port separated by commas>')
    parser.add_option('-d', dest='dhost', type='string', help='specify target host')
    parser.add_option('-p', dest='dport', type='string', help='specify target port separated by commas')
    (options, args) = parser.parse_args()
    dhost = options.dhost
    #split(",") not split(", "), the latter will cause python3 to give an error like this
    #ValueError: invalid literal for int() with base 10:
    dports = str(options.dport).split(",")
    if(dhost == None) | (dports == None):
        parser.print_help()
        exit(0)
    for dport in dports:
        nmapScan(dhost,dport)

if __name__ == '__main__':
    main()

If there is no argument specified the result looks like this:

Usage: nmap2.py -d -p

Options:
-h, --help show this help message and exit
-d DHOST specify target host
-p DPORT specify target port separated by commas

Another scenario is specify one host and one port for nmap scan:

Cyruss-Air:net1 cyruslok$ sudo python3 nmap2.py -d 192.168.1.150 -p22
[*] 192.168.1.150 tcp/22 open

Another scenarios is to specifiy more than one port for nmap scan:

Cyruss-Air:net1 cyruslok$ sudo python3 nmap2.py -d 192.168.1.150 -p21,22,23,80,443
[*] 192.168.1.150 tcp/21 closed
[*] 192.168.1.150 tcp/22 open
[*] 192.168.1.150 tcp/23 closed
[*] 192.168.1.150 tcp/80 closed
[*] 192.168.1.150 tcp/443 closed

Posted in Python, Scripting | Tagged , , | Leave a comment

[python]Intrusive python with nmap

Just got a new python-nmap installed, and nmap installed on my mac, did a small try out on manipulating the result.

here’s the code:

import nmap

host = '192.168.1.150'
nm = nmap.PortScanner()
nm.scan(host, '22')
state = nm[host]['tcp'][22]['state']
print("{} tcp/22 is {}".format(host,state))

I will be trying out the full scan capability with the codes, the above is just a try out… the actual usage would need to do some iteration with a for loop.

Posted in Python, Scripting | Tagged , | Leave a comment

[python]Exception handling with pan-python

pan.xapi has its own error handling, so on previous post i updated the code with exception handling.

I actually tested with wrong credential, I could see the http 403 forbidden error raised. Which is good, as I would know what went wrong…

import pan.xapi,time
#documentation on github https://github.com/kevinsteves/pan-python/blob/master/doc/pan.xapi.rst
#xpath can be navigated on PAN OS on this path https://firewall_ip/api/
deviceconfig_system_xpath = "/config/devices/entry[@name='localhost.localdomain']/deviceconfig/system"

#define the timezone, can read from a list and enumerate in dictionary
tz = {}
tz['SG'] = 'Asia/Singapore'
tz['JP'] = 'Asia/Tokyo'
tz['US'] = 'US/Pacific'

#Palo Alto credential, can be modified by using an external encrypted list
def get_pan_credentials(username,password):
    cred = {}
    cred['api_username'] = username
    cred['api_password'] = password
    cred['hostname'] = '192.168.1.104'
    return cred

#device configuration setting only time
def set_time(timezone,ntp_primary,ntp_secondary):
    deviceconfig = """
    <timezone>{}</timezone>
    <ntp-servers>
        <primary-ntp-server>
            <ntp-server-address>{}</ntp-server-address>
        </primary-ntp-server>
        <secondary-ntp-server>
            <ntp-server-address>{}</ntp-server-address>
        </secondary-ntp-server>
    </ntp-servers>
""".format(timezone,ntp_primary,ntp_secondary)
    return deviceconfig
                
config = set_time(tz['SG'],'203.123.48.219','128.199.169.185')

#below code modified with exception handling, by using pan-python own error
try:
    xapi = pan.xapi.PanXapi(**get_pan_credentials('admin','admin'))
except pan.xapi.PanXapiError as PE:
    print(PE)

try:
    xapi.set(xpath=deviceconfig_system_xpath,element=config)
    time.sleep(3)
    print(xapi.status)
except pan.xapi.PanXapiError as PE:
    print(PE)

time.sleep(3)
try:
    xapi.commit(cmd="<commit></commit>",timeout=10)
    print(xapi.status)
except pan.xapi.PanXapiError as PE:
    print(PE)

This is how it looked like:
Snip20171112_11

Posted in Python, Scripting | Tagged , , , , | Leave a comment