split() on one character OR another - python-3.x

Python 3.6.0
I have a program that parses output from Cisco switches and routers.
I get to a point in the program where I am returning output from the 'sh ip int brief'
command.
I place it in a list so I can split on the '>' character and extract the hostname.
It works perfectly. Pertinent code snippet:
ssh_channel.send("show ip int brief | exc down" + "\n")
# ssh_channel.send("show ip int brief" + "\n")
time.sleep(0.6)
outp = ssh_channel.recv(5000)
mystring = outp.decode("utf-8")
ipbrieflist = mystring.splitlines()
hostnamelist = ipbrieflist[1].split('>')
hostname = hostnamelist[0]
If the router is in 'enable' mode the command prompt has a '#' character after the hostname.
If I change my program to split on the '#' character:
hostnamelist = ipbrieflist[1].split('#')
it still works perfectly.
I need for the program to handle if the output has the '>' character OR the '#' character in 'ipbrieflist'.
I have found several valid references for how to handle this. Ex:
import re
text = 'The quick brown\nfox jumps*over the lazy dog.'
print(re.split('; |, |\*|\n',text))
The above code works perfectly.
However, when I modify my code as follows:
hostnamelist = ipbrieflist[1].split('> |#')
It does not work. By 'does not work' I mean it does not split on either character. No splitting at all.
The following debug is from PyCharm:
ipbrieflist = mystring.splitlines() ipbrieflist={list}: ['terminal length 0', 'rtr-1841>show ip int brief | exc down', 'Interface'] IP-Address OK? Method Status Protocol', 'FastEthernet0/1 192.168.1.204 YES NVRAM up up ', 'Loopback0 172.17.0.1 YES NVRAM up up ', '', 'rtr-1841>']
hostnamelist = ipbrieflist[1].split('> |#') hostnamelist={list}: ['rtr-1841>show ip int brief | exc down']
hostname = {str}'rtr-1841>show ip int brief | exc down'
As you can see the hostname variable still contains the 'show ip int brief | exc down' appended to it.
I get the same exact behavior if the hostname is followed by the '#' character.
What am I doing wrong?
Thanks.

Instead of this:
ipbrieflist[1].split('> |#')
You want this:
re.split('>|#', ipbrieflist[1])

Related

Angr can't solve the googlectf beginner problem

I am a student studying angr, first time.
I'm watching the code in this url.
https://github.com/Dvd848/CTFs/blob/master/2020_GoogleCTF/Beginner.md
import angr
import claripy
FLAG_LEN = 15
STDIN_FD = 0
base_addr = 0x100000 # To match addresses to Ghidra
proj = angr.Project("./a.out", main_opts={'base_addr': base_addr})
flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(FLAG_LEN)]
flag = claripy.Concat( *flag_chars + [claripy.BVV(b'\n')]) # Add \n for scanf() to accept the input
state = proj.factory.full_init_state(
args=['./a.out'],
add_options=angr.options.unicorn,
stdin=flag,
)
# Add constraints that all characters are printable
for k in flag_chars:
state.solver.add(k >= ord('!'))
state.solver.add(k <= ord('~'))
simgr = proj.factory.simulation_manager(state)
find_addr = 0x101124 # SUCCESS
avoid_addr = 0x10110d # FAILURE
simgr.explore(find=find_addr, avoid=avoid_addr)
if (len(simgr.found) > 0):
for found in simgr.found:
print(found.posix.dumps(STDIN_FD))
https://github.com/google/google-ctf/tree/master/2020/quals/reversing-beginner/attachments
Which is the answer of googlectf beginner.
But, the above code does not work. It doesn't give me the answer.
I want to know why the code is not working.
When I execute this code, the output was empty.
I run the code with python3 in Ubuntu 20.04 in wsl2
Thank you.
I believe this script isn't printing anything because angr fails to find a solution and then exits. You can prove this by appending the following to your script:
else:
raise Exception('Could not find the solution')
If the exception raises, a valid solution was not found.
In terms of why it doesn't work, this code looks like copy & paste from a few different sources, and so it's fairly convoluted.
For example, the way the flag symbol is passed to stdin is not ideal. By default, stdin is a SimPackets, so it's best to keep it that way.
The following script solves the challenge, I have commented it to help you understand. You will notice that changing stdin=angr.SimPackets(name='stdin', content=[(flag, 15)]) to stdin=flag will cause the script to fail, due to the reason mentioned above.
import angr
import claripy
base = 0x400000 # Default angr base
project = angr.Project("./a.out")
flag = claripy.BVS("flag", 15 * 8) # length is expected in bits here
initial_state = project.factory.full_init_state(
stdin=angr.SimPackets(name='stdin', content=[(flag, 15)]), # provide symbol and length (in bytes)
add_options ={
angr.options.SYMBOL_FILL_UNCONSTRAINED_MEMORY,
angr.options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS
}
)
# constrain flag to common alphanumeric / punctuation characters
[initial_state.solver.add(byte >= 0x20, byte <= 0x7f) for byte in flag.chop(8)]
sim = project.factory.simgr(initial_state)
sim.explore(
find=lambda s: b"SUCCESS" in s.posix.dumps(1), # search for a state with this result
avoid=lambda s: b"FAILURE" in s.posix.dumps(1) # states that meet this constraint will be added to the avoid stash
)
if sim.found:
solution_state = sim.found[0]
print(f"[+] Success! Solution is: {solution_state.posix.dumps(0)}") # dump whatever was sent to stdin to reach this state
else:
raise Exception('Could not find the solution') # Tell us if angr failed to find a solution state
A bit of Trivia - there are actually multiple 'solutions' that the program would accept, I guess the CTF flag server only accepts one though.
❯ echo -ne 'CTF{\x00\xe0MD\x17\xd1\x93\x1b\x00n)' | ./a.out
Flag: SUCCESS

From SSH not decoded from bytes to ASCII?

Good afternoon.
I get the example below from SSH:
b"rxmop:moty=rxotg;\x1b[61C\r\nRADIO X-CEIVER ADMINISTRATION\x1b[50C\r\nMANAGED OBJECT DATA\x1b[60C\r\n\x1b[79C\r\nMO\x1b[9;19HRSITE\x1b[9;55HCOMB FHOP MODEL\x1b[8C\r\nRXOTG-58\x1b[10;19H54045_1800\x1b[10;55HHYB"
I process ssh.recv (99999) .decode ('ASCII')
but some characters are not decoded for example:
\x1b[61C
\x1b[50C
\x1b[9;55H
\x1b[9;19H
The article below explains that these are ANSI escape codes that appear since I use invoke_shell. Previously everything worked until it moved to another server.
Is there a simple way to get rid of junk values that come when you SSH using Python's Paramiko library and fetch output from CLI of a remote machine?
When I write to the file, I also get:
rxmop:moty=rxotg;[61C
RADIO X-CEIVER ADMINISTRATION[50C
MANAGED OBJECT DATA[60C
[79C
MO[9;19HRSITE[9;55HCOMB FHOP MODEL[8C
RXOTG-58[10;19H54045_1800[10;55HHYB
If you use PuTTY everything is clear and beautiful.
I can't get away from invoke_shell because the connection is being thrown from one server to another.
Sample code below:
# coding:ascii
import paramiko
port = 22
data = ""
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=host, username=user, password=secret, port=port, timeout=10)
ssh = client.invoke_shell()
ssh.send("rxmop:moty=rxotg;\n")
while data.find("<") == -1:
time.sleep(0.1)
data += ssh.recv(99999).decode('ascii')
ssh.close()
client.close()
f = open('text.txt', 'w')
f.write(data)
f.close()
The normal output is below:
MO RSITE COMB FHOP MODEL
RXOTG-58 54045_1800 HYB BB G12
SWVERREPL SWVERDLD SWVERACT TMODE
B1314R081D TDM
CONFMD CONFACT TRACO ABISALLOC CLUSTERID SCGR
NODEL 4 POOL FLEXIBLE
DAMRCR CLTGINST CCCHCMD SWVERCHG
NORMAL UNLOCKED
PTA JBSDL PAL JBPTA
TGFID SIGDEL BSSWANTED PACKALG
H'0001-19B3 NORMAL
What can you recommend in order to return normal output, so that all characters are processed?
Regular expressions do not help, since the structure of the record is shifted, then characters from certain positions are selected in the code.
PS try to use ssh.invoke_shell (term='xterm') don't work.
There is an answer here:
How can I remove the ANSI escape sequences from a string in python
There are other ways...
https://unix.stackexchange.com/questions/14684/removing-control-chars-including-console-codes-colours-from-script-output
Essentially, you are 'screen-scraping' input, and you need to strip the ANSI codes. So, grab the input, and then strip the codes.
import re
... (your ssh connection here)
data = ""
while data.find("<") == -1:
time.sleep(0.1)
chunk = ssh.recv(99999)
data += chunk
... (your ssh connection cleanup here)
ansi_escape = re.compile(r'\x1B(?:[#-Z\\-_]|\[[0-?]*[ -/]*[#-~])')
data = ansi_escape.sub('', data)

how can i extract a string or pattern from a result set

I included an oracle command
$DOMAIN_HOME/reports/bin/rwdiag.sh -findall
in a linux script that does a check of our env and returns a sample output below
(1) Name = rep_wls_reports_orclas4t : Type = server : Host =
(2) Name = rep_wls_reports_ias10t_frasinst_1 : Type = server : Host
=
(3) Name = rptsvr_orclas5p_frasinst_1 : Type = server : Host =
...
(a list of existing report servers available for use in our ERP)
I am trying to extract just the portion **Name = rep****** and report just that only in my output. How can I use sed and/or grep to achieve this.
Many thanks for any assistance.
Regards
you can use the awk
$DOMAIN_HOME/reports/bin/rwdiag.sh -findall | awk -F' ' $'{print $2,$3,$4}'
With this command you use the string like a list separate by space(defined with -F).

Python3 - Remove last (n) lines from file and append new data [duplicate]

This question already has answers here:
Delete final line in file with python
(10 answers)
Closed 3 years ago.
I have a little python script that I'm working on that will add the local weather conditions and some network information to my .bashrc file. Everything works as expected except for two bugs: first instead of removing the old data and appending the new it just appends the new data like this:
('echo [Local weather]:', 66.9, 'F', 'with', 'overcast clouds')
('echo [Your public IP is]:', 'x.x.x.x'('echo [Local weather]:', 66.9, 'F', 'with', 'overcast clouds')
('echo [Your public IP is]:', 'x.x.x.x')
and second I need to drop the formatting from the printed text, eg (parentheses, commas, etc..) so that the string appears as such:
echo [Local weather]: 66.9F with overcast clouds
echo [Public IP]: x.x.x.x
Here is the file operations portion of my script:
with open('HOME/.bashrc', 'a') as f:
w = "echo [Local weather]:", wx_t,"F", "with", wx_c
i = "echo [Your public IP is]:", ip
out = [str(w), str(i)]
f.write('\n'.join(out)[0:-3])
so I thought that f.write('\n'.join(out)[0:-3]) would remove the last 3 lines of the file but apparently it drops the last 3 characters of the string. What do I need to change to achieve that which I attempting? Should I be using f.writelines() instead of f.write()?
The expected result will eventually look like this:
Welcome to [hostname] You are logged in as user [some_user]
[Local time]: Mon Mar 20 08:28:32 CDT 2017.
[Local weather]: 66.56 F with clear sky
[Local IP]: 192.168.x.x [Public IP]: x.x.x.x
Thanks in advance and if this is a duplicate question I apologize. I felt I've done my due-diligence in searching for a solution but I have been unsuccessful.
UPDATE:
So i fixed the formatting by changing
w = "echo [Local weather]:", wx_t,"F", "with", wx_c
to
w = "echo [Local weather]: " + str(wx_t) + " F, with " + wx_c
and using f.writelines() instead of f.write(). Also I removed f.close() as suggested by DeepSpace
The first bug is caused by using 'a' instead of 'w' in the first line. This cause Python to add to the file rather than overwrite the file.
The second bug is caused because you are joining all your data into a string, and getting [0:-3] of the joined string, rather than [0:-3] of the list out.
Your code, fixed, should look like this:
with open('HOME/.bashrc', 'w') as f:
w = "echo [Local weather]:", wx_t,"F", "with", wx_c
i = "echo [Your public IP is]:", ip
out = [str(w), str(i)]
f.write('\n'.join(out[0:-3]))

How get ESSID and Access Point when I write iwconfig

I write iwconfig so I can have he name of my lan ESSID and mac of point acess ,I want to recover his two fields for using in a script I can be on the first line, but I can not have the information that I want.
how to ubuntu I vaoir that valeus ESSID and Access Point
wlan0 IEEE 802.11bgn ESSID:"Home"
Mode:Managed Frequency:2.437 GHz Access Point: 00:03:B6:K9:L1:9E
I need help. thanks.
try:
proc = Popen(['iwconfig'], stdout=PIPE, stderr=DN)
print "try de iwconfig %s"%proc
except OSError:
sys.exit("Could not execute iwconfig")
for line in proc.communicate()[0].split('\n'): print "line %s"%line if len(line) == 0:
continue # Isn't an empty string
if line[0] != ' ':
if 'IEEE 802.11' in line:
if "ESSID:\"" in line:
print line[ESSID][0]
if "Access Point:\"" in line:
print line[Access Point][0]
For my output of iwconfig, a regex like this seems to work perfectly fine:
from re import *
from subprocess import *
proc = Popen(['iwconfig'], stdout=PIPE)
intext=str(proc.communicate()[0])
m1=search('Access Point: [ABCDEF0123456789:]*',intext)
AP=m1.group(0).split(' ')[2]
print AP
m2=search('ESSID:".*" ',intext)
ESSID=m2.group(0).split('"')[1]
print ESSID

Resources