[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.

Advertisements
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

[python]Working with Palo Alto firewall API with pan-python module

This is another demonstration on the use of pan-python module. The usage documentation can be found in github.

This is a simple demonstration on using the pan.xapi module from pan-python. Only changes the device configuration time settings. The demo uses the module to set the time zone and ntp primary and secondary addresses. To reduce the number of xml tags required, the xpath is used. The commit is used after the set command is issued, this code sample can be improved with try and except loop to handle exceptions.

My personal opinion this module is actually not required, requests module can give the same result without a lot of coding, this pan-python module would be useful if it has list of xml commands and list of xpaths.

Code sample:

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')

#shoud use try and except, if status code is error then break exit with error code.
#this is a demo hence not as good on error handling.
xapi = pan.xapi.PanXapi(**get_pan_credentials('admin','admin'))
xapi.set(xpath=deviceconfig_system_xpath,element=config)
time.sleep(3)
print(xapi.status)
time.sleep(3)
xapi.commit(cmd="<commit></commit>",timeout=10)
print(xapi.status)

Here’s the result:
Snip20171112_8.png

Snip20171112_9

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

[python]working with pan-python module. Module that calls Palo Alto API

I found the example of usage in here. The code will not work on python3. In fact i am not sure why the print(credentials) in the code is necessary, there is no arg passed into the PanXapi which puzzles me why the code will work.

To pass dictionary of arguments into the PanXapi method you will need double asterix.

So here’s the modification for python3, actually i have not tried on python2.7 yet, but i dun think it mattered to me since python3 will be de facto standard henceforth.

import pan.xapi


def get_pan_credentials():
 cred = {}
 cred['api_username'] = "admin"
 cred['api_password'] = "admin"
 cred['hostname'] = "192.168.1.104"
 return cred

credentials = get_pan_credentials()
xapi = pan.xapi.PanXapi(**credentials)
xapi.op(cmd='show system info', cmd_xml=True)
print(xapi.xml_result())

The output is the same as using the requests module to call the REST API directly. the difference with Pan-Python is that passing arguments is made easy.
So here’s the complete output:

<system><hostname>PA-VM</hostname><ip-address>192.168.1.104</ip-address><netmask>255.255.255.0</netmask><default-gateway>192.168.1.1</default-gateway><is-dhcp>yes</is-dhcp><ipv6-address>unknown</ipv6-address><ipv6-link-local-address>fe80::5200:ff:fe01:0/64</ipv6-link-local-address><ipv6-default-gateway /><mac-address>50:00:00:01:00:00</mac-address><time>Sun Nov 12 00:48:47 2017
</time>
<uptime>0 days, 21:49:26</uptime>
<devicename>PA-VM</devicename>
<family>vm</family><model>PA-VM</model><serial>unknown</serial><vm-mac-base>BA:DB:EE:FB:AD:00</vm-mac-base><vm-mac-count>255</vm-mac-count><vm-uuid>3E304129-D98B-4BD4-A3EE-8C74A586B7BA</vm-uuid><vm-cpuid>KVM:23060000FDFB8B07</vm-cpuid><vm-license>none</vm-license><vm-mode>KVM</vm-mode>
<sw-version>8.0.0</sw-version>
<global-protect-client-package-version>0.0.0</global-protect-client-package-version>
<app-version>655-3816</app-version>
<app-release-date>unknown</app-release-date>
<av-version>0</av-version>
<av-release-date>unknown</av-release-date>
<threat-version>0</threat-version>
<threat-release-date>unknown</threat-release-date>
<wf-private-version>0</wf-private-version>
<wf-private-release-date>unknown</wf-private-release-date>
<url-db>paloaltonetworks</url-db>
<wildfire-version>0</wildfire-version>
<wildfire-release-date>unknown</wildfire-release-date>
<url-filtering-version>0000.00.00.000</url-filtering-version>
<global-protect-datafile-version>unknown</global-protect-datafile-version>
<global-protect-datafile-release-date>unknown</global-protect-datafile-release-date><global-protect-clientless-vpn-version>0</global-protect-clientless-vpn-version>
<global-protect-clientless-vpn-release-date>unknown</global-protect-clientless-vpn-release-date>
<logdb-version>8.0.15</logdb-version>
<platform-family>vm</platform-family>
<vpn-disable-mode>off</vpn-disable-mode>
<multi-vsys>off</multi-vsys>
<operational-mode>normal</operational-mode>
</system>
Posted in Python, Scripting | Tagged | Leave a comment