f-string script conversion to earlier version of Python - python

I have a question in regards to comparing files using python. For context, the problem I am having is that I have two firewalls with different configurations (over 14000 lines each on Notepad++) and I need to find the differences and annotate them.
Quick Example -
Firewall 1:
Version: 123
set policy EXPLICIT_DENY ALL
IP address allow 1.2.3.4
IP address allow 4.3.2.1
set policy EXPLICIT_ALLOW NONE
Firewall 2:
Version: 321
set policy EXPLICIT_ALLOW NONE
IP address allow 4.3.2.1
IP address allow 1.2.3.4
set policy EXPLICIT_DENY ALL
A line-by-line comparison would show that all of those lines are incorrect because they do not match side by side, however, the configuration is the same and would not need to be annotated. The only difference would be the Version # in the example. The script below was able to work for my purposes.
Current Script I ran -
'file1 = open("OLD FW.txt",'r')
'file2 = open("NEW FW.txt",'r')
'file3 = open("Results.txt",'r+')
'file1_lines = file1.readlines()
'file2_lines = file2.readlines()
'for position, a in enumerate(file1_lines):
'linematch = False
'for b in file2_lines:
'if a == b:
'linematch = True
'if linematch == False:
'file.3write(f"{position+1}: {a.strip()}\")
'file1.close()
'file2.close()'
The output would show every line from the OLD firewall that does not appear on the NEW firewall. This would effectively let me see what configurations are missing and/or different AND show me what line is is on the original FW.
The issue I figured out after coming up with this is that my current software version at work is only Python 2.7.16 which doesn't support f-strings. I did a little bit of research but am far to novice currently to figure this out in the short time window I have.
Mai question: How do I convert this Python f-string script to something that would work the same in an older version of Python that doesn't support f-strings?
Thanks in advance to anyone who can help me figure this out!

For simple cases like you show, you can use the .format() method.
file.write("{}: {}\n".format(position+1, a.strip()))

Related

Is there a way to find which firewall-profile is active?

I had a problem with servers connecting to the wrong firewall-profile so I am trying to find a solution to track this information.
I have already got the powershell commands in my python script:
subprocess.getoutput('netsh advfirewall show allprofiles')
subprocess.check_output('netsh advfirewall show currentprofile')
I can also convert them to strings.
The actual problem is that these informations look very fractured and are probably not always in the same order on different systems, as well as different languages.
Is there a simple way to find which firewall-profile is on and active?
In the best case the function gives me a String like "yes"/"no" or a boolean.
Yes you can! You just had not defined the PolicyStore to query - Details below...
Just use the following query - It returns the names of all active policies - For example "Domain"
Get-NetFirewallSetting -PolicyStore ActiveStore |
Select-Object -ExpandProperty ActiveProfile
Additionally, there is to mention that "ActiveProfile" might contain multiple profiles, as a system can have more adapters that might need different settings. So this example might also be normal "Domain, Public"
Information about "PolicyStore" and why you need it pretty often:
This store contains the currently active policy, which is the sum of all policy stores that apply to the computer
Source: https://learn.microsoft.com/en-us/powershell/module/netsecurity/get-netfirewallprofile
If you need true or false responses for each you could use this
$intvalue = (Get-NetFirewallSetting -PolicyStore activestore).`
CimInstanceProperties.Where{$_.Name -eq "Profile"}.value
$DomainEnabled = [bool]($intvalue -band 0x1)
$PrivateEnabled = [bool]($intvalue -band 0x2)
$PublicEnabled = [bool]($intvalue -band 0x4)
For this example you also can have multiple $true values

Incrementing a numerical value of a string by 1 - Python

Im currently writing a script for python that will enable users to easily configure snort, I have a rule to protect TCP port 23 from access called IoTProtect with the following syntax:
reject tcp any any -> 169.254.183.24 23 (msg:Unauthorized access to IoT device!; sid:00000000;rev:003; )
The issue is that I have added functionality so that a user can add an IP address and this rule will be applied for that IP as well, however, for the rule to work the SID must be incremented by one or be unique.
Currently the python script i've created is:
import fileinput
def incrementsid():
incremented = 0
added = incremented + 2
text = "sid:00000000"
new_text = "sid:0000000{}".format(added)
for line in fileinput.input("C:\\Users\\Admin\\Desktop\\Test\\IoTProtection.rules", inplace = 1):
if text in line:
print(line.replace(line,new_text))
print("Sid replaced!")
else:
print(line.strip())
incrementsid()
However what actually happens is I receive this output:
reject tcp any any -> 169.254.183.24 23 (msg:Unauthorized access to IoT device!; sid:00000000;rev:003; )
and inside my Test folder the IoTProtect.rules file now only says:
sid:00000002
Sid replaced!
where I actually need IoTProtect.rules to say:
reject tcp any any -> 169.254.183.24 23 (msg:Unauthorized access to IoT device!; sid:00000002;rev:003; )
Apologies if my code is garbage but would I would really appreciate any advice or feedback on how to get this functionality working.
Thanks!
There are two problems in code:
1) use fileinput.Fileinput insted of fileinput.input
2) replace:
print(line.replace(line,new_text))
by:
print(line.replace(text,new_text))
UPDATE:
Your question is already answered Here
more info about string.replace()

How do I log text and a variable in the same line in Python?

I am relativly new to coding with Python.
I recently set up a gps logging device with a raspberry pi and I want to make my log file look cleaner.
My current code for logging is:
logging.info('Altitude:')
logging.info(gpsd.fix.altitude)
It logs:
INFO:root:Altitude:
INFO:root:80
What I want to see in the log is:
Altitude: 80
I tried to do this with my limited knowledge with python, but it only resulted in failure.
Thanks!
Also, any other tips for cleaning up the log file?
If altitude is a decimal then
logging.info('Altitude: %d' % gpsd.fix.altitude)
will do it, there are several other ways to achieve the same thing though as I'm sure others can present!
In Python >=3.6 you can do this :
logging.info(f"Altitude: {gpsd.fix.altitude}")
By adding the "f" at the beginning of the string the value between brackets will be interpreted as a variable and will be replaced by its value.
logging.info('{}:{}'.format("Altitude", gpsd.fix.altitude)
You can use format method. Have a look at the examples to understand format better.
Example:
print '{}:{}'.format("Altitude", 80)
Output
Altitude:80
Try:
logging.info('Altitude:%s' % gpsd.fix.altitude)

extracting ip address from raw_input

I have compiled a script in python 2.6.5, The script is simply to automate my most used functions for nmap and log the output to a txt file on the desktop.
I haven't written this all myself as i am still only learning python. I found an update script for updating backtrack and used that as a template for indentation and commands and modified it and added some of my own stuff to give me what i needed.
The problem i'm having is with this block
def nmap_target():
try: ip = raw_input(" [>] Enter ip to scan: ")
except KeyboardInterrupt:
print "\n [>] Exiting!\n"
sleep(1)
sys.exit()
print " [>] Attempting targeted scan.\n"
#print ip
if subprocess.Popen("nmap ip >> //root/Desktop/Target.txt && tail /root/Desktop/Target.txt",shell=True).wait() == 0:
print "\n"
print " [>] Targeted scan completed successfully!\n"
menu_main()
else:
print "\n"
print " [>] Nmap scan failed.\n"
The idea behind it is that it asks the user to input an ip address into raw_input() and call it ip, I'm trying to then pass it to nmap using subprocess.Popen("nmap ip as can be seen above.
The problem is its just writing nmap ip rather than printing the ip address and then returning errors, It even tries to scan out of my network, every time i test it i make sure the internet cable is unplugged from my router, This causes a bug with my internet test though, so if you try running the code bellow you may need to hash out the internet_check() option in the menu_main() section if you have your internet unplugged from the router
I have spent 4 days on this now and its driving me mad, At first i thought i needed to convert the number to floating point so i tried that and still the same, I've tried all sorts of things and spent hours trawling the internet looking for an answer to no avail.
I am now convinced its not the command i'm trying that is to blame i think it is the exit statement, I have tried putting "print ip" right after the line where it says "print " [>] Attempting targeted scan.\n" and sure enough the ip address that was entered is displayed on the screen, That proved to me that raw_input() is working. As soon as i move it anywhere bellow that it fails, This suggests to me that it must be either a problem with the exit statement or maybe indentation, I'm not sure though.
I have also tried hashing out the keyboard interrupt as well as the couple of lines bellow, i tried moving the try: and if statements around and even tried other commands instead but it just wont work aaaarrrrrgggghhhhhh
Would i be right in thinking that the ip is being entered into raw_input() and then the file ip that was created that holds the ip address is being destroyed before i can pass it to subprocess.Popen("nmap ip.
Like i mentioned i didn't write this script from scratch and this is my first project like this so i've got a lot to learn, I've been all through the python man pages and looked through all sorts of tutorials but just can't figure this out.
Any help will be much appreciated
i will post the full script if anyone is interested,just as soon as i can figure out how to post code properly
You need to seperate the variable from the string! Try this :D
if subprocess.Popen('nmap '+ip+' >> //root/Desktop/Target.txt && tail /root/Desktop/Target.txt',shell=True).wait() == 0:
Hope it helps!
EDIT - If for some reason python takes the raw input as an integer, convert it to string like so:
if subprocess.Popen('nmap '+str(ip)+' >> //root/Desktop/Target.txt && tail /root/Desktop/Target.txt',shell=True).wait() == 0:
Python doesn't like to concatenate str and int types, or so it tells when my script fails :P I am pretty sure your ip variable will be str type though so the first example should work.
Cheers!
You need to format the string properly or the string ip won't be interpreted at all, i.e. it won't get replaced wth the actual IP. Try something like:
cmd = "nmap ${0} >> [....] root/Desktop/Target.txt".format(ip)
if subprocess.Popen(cmd):
You could also use the % operator:
cmd = "nmap %s >> [....] root/Desktop/Target.txt" % ip

MAC address generator in python

For purpose of creating bulk virtual machines, I need to create a random MAC address generator in Python. I don't know how to generate random MAC addresses.
Is the following program correct or not?
import random
# The first line is defined for specified vendor
mac = [ 0x00, 0x24, 0x81,
random.randint(0x00, 0x7f),
random.randint(0x00, 0xff),
random.randint(0x00, 0xff) ]
print ':'.join(map(lambda x: "%02x" % x, mac))
For anyone wanting to generate their own MAC addresses (a good example is for VM NICs), you probably just want this:
"02:00:00:%02x:%02x:%02x" % (random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 255))
Or, if you want to do this in a unix'y shell, this works on many:
printf '02:00:00:%02X:%02X:%02X\n' $((RANDOM%256)) $((RANDOM%256)) $((RANDOM%256))
This gives you a unicast MAC address that is 100% safe to use in your environment, and isn't trampling on anyone's registered MAC address space.
More detail...
The bottom two bits of the top byte (0x02) give you a locally administered unicast address, which is probably what you want if you are hitting stackoverflow for how to generate this. :)
If the MAC address is not locally administered, it means it is supposed to be "globally unique". MAC addresses in this category are centrally registered with the IEEE, and you should have a unique OUI (Organizationally Unique Identifier) issued to you by the IEEE. See this link for the global registry of OUI values. This OUI value ends up in the first 3 bytes (or just the top 22 bits, really).
MAC addresses aren't that complicated, so you should probably also just have a look at the definition. Wikipedia has a good one.
Modified from mamofish's code to Python3:
mac = '00:00:00:'
for number in range(16**6):
hex_num = hex(number)[2:].zfill(6)
print("{}{}{}:{}{}:{}{}".format(mac,*hex_num))
Generates mac addresses as strings from 00:00:00:00:00:00 to 00:00:00:ff:ff:ff.
Since uniqueness is all you should care about (beyond making the address well-formed), I'd worry about the MSBs in the OUI and use a sequence in the NIC specific bytes. The distribution of the addresses is likely unimportant to your application (even though some NIC or switch implementations might use them as an input to a hash, this is likely not to be a big concern).
You may want to consider using the "locally administered" flag in the OUI to avoid a conflict with an existing device manufacturer.
Avoid pitfalls like setting the multicast bit (your example does).
To avoid duplicates:
If you're going to generate a LOT (millions) of such MAC addresses, you might want to generate an in-order list of MAC's, feed that to a linear randomization process (GNU sort -R should do fine - I don't think it does this in linear time, but it has a similar end result) once, and then pull your fresh addresses off one end of the randomized list as needed. I believe such a list should fit in about 34 megabytes.
If you merely need thousands, you're probably better off maintaining a text file with already-selected values, and checking for collisions against that, adding new values as you go. This is a slower algorithm asympotically speaking, but it has a much less overhead, so it should still be a win for lower numbers of mac addresses.
BTW, should the 4th octet (numbered from 1 starting on the left), be 0-ff instead of 0-7f? I see no occurrences of 7f or 127 in the Wikipedia page on Mac addresses:
http://en.wikipedia.org/wiki/MAC_address

Categories