Lua popen with string arguments - lua

I am attempting to use popen to pipe a string containing multiple quotes to netcat. I have a Python command that works fine but I am turning it into an nmap script. I am not as familiar with Lua.
Python version:
python -c 'print "\x1b%-12345X#PJL FSDIRLIST NAME=\"0:\\..\\..\\..\\\" ENTRY=1 COUNT=999999\x0d\x0a\x1b%-12345X\x0d\x0a"' | nc 192.168.0.1 9100
Lua attempted version:
local handle = assert(io.popen("python -c 'print \"\x1b%-12345X#PJL FSDIRLIST NAME=\"0:\\..\\..\\..\\\" ENTRY=1 COUNT=999999\x0d\x0a\x1b%-12345X\x0d\x0a\"' | nc " .. host .. " " .. port, "r"))
This results in the following error:
File "<string>", line 1
print "2345X#PJL FSDIRLIST NAME="0:\..\..\..\" ENTRY=1 COUNT=999999
Is there a way to organize that string so that Lua will accept it?

Try using a long string
[[python -c 'print "\x1b%-12345X#PJL FSDIRLIST NAME=\"0:\\..\\..\\..\\\" ENTRY=1 COUNT=999999\x0d\x0a\x1b%-12345X\x0d\x0a"' | nc 192.168.0.1 9100]]

Related

Need to verify/check ipv6 address using ping in lua script

i am not aware of lua script but i need some help.
Basically current lua script will receive structure.
in those structure has address parameter where will get two index parameters(ipv6 & ipv4) addresses.
lua script need to implement below case
ping ipv6 address and result will get store in local variable.
if local variable gets (ping success) will connect/call uv.tcp_connect for passed ipv6 address.
otherwise i will check the same for ipv4 address and try to connect/call uv.tcp_connect.
I am using online lua editor there its returning nil.
local results = load('ping -q -c1 -6 localhost 2>&1 >/dev/null && printf "IPv6: true" || (ping -q -c1 www.google.com 2>&1 >/dev/null && printf "IPv4 true" || printf "false")')
print(results)
output is:nil
and
if i am using in lua online editor ..
local handler = io.popen("ping -c 3 -i 0.5 www.google.com")-- wrong here.
local response = handler:read("*a")
print(response)
output error :
lua: main.lua:3: expected near '"ping -c 3 -i 0.5 www.google.com"'
kindly suggest me , am i missing something above.
To store output of system commands i suggest io.popen().
An example for conditional ping that tries first IPv6 and if fail IPv4...
> code.cmd
-- cmd(shell)
return function(shell)
return io.popen(shell, 'r'):read('a+')
end
> results={}
> results.ping=load(code.cmd)()('ping -q -c1 -6 localhost 2>&1 >/dev/null && printf "IPv6: true" || (ping -q -c1 localhost 2>&1 >/dev/null && printf "IPv4 true" || printf "false")')
> print(results.ping)
IPv6: true
...typed in a Lua console.
EDIT
Online Lua Environments dont support above code!

regex start of line anchor alternative

I have "file.txt" with the following and I need to get only ip addresses that start a line.
I am using gnu utilities for windows and grep seems to be not behaving incorrectly.
Random Text Here
ABC 10.0.0.0 - 10.20.0.255
IP Ping Hostname
100.5.0.20 11ms N/S
GNU grep 2.5.4
grep -Po ^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} file.txt
10.0.0.0
10.20.0.255
100.5.0.20
Correct behavior should only allow 100.5.0.20 since i specified the start line anchor.
Any other Linux command solutions?
I ended up improvising,
grep -oP "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]{1,3} " file.txt| awk "{$1=$1};1" > file.txt
This will grab the ip addresses with 2 spaces, and then remove the spaces with awk.

Escaping Strings in Elixir 1.4

I know i'm probably missing something here
I've got this ruby code
system("ansible all -i #{ip_address}, -m lineinfile -u root -a'dest=/etc/setup.json state=present regexp=rpc_json line='\\\''\"rpc_json\": \"#{ip_address}:2012\",'\\\'")
I'm trying to reproduce this with System.cmd
System.cmd("ansible" ,["all", "-i", "127.0.0.1,","-m", "lineinfile","-u","root","-a","dest=/etc/cgrates/cgrates.json state=present regexp=rpc_json
line='\\\''\"rpc_json\": \"#{ip_address}:2012\",'\\\'" ])
Issue is with this :
line='\\\''\"rpc_json\": \"#{ip_address}:2012\",'\\\'"
Trying to escape double quotes around rpc_json and the interpolated value of ip_address
Tried using the ~s sigil to no avail.Any Pointer to my error would be appreciated.
Have you tried using erlang's :os.cmd/1 command? Just need to remember to send it a charlist and not an elixir string.
iex(9)> ip_address = "127.0.0.1"
"127.0.0.1"
iex(10)> cmd = "ansible all -i #{ip_address}, -m lineinfile -u root -a'dest=/etc/setup.json state=present regexp=rpc_json line='\\\''\"rpc_json\": \"#{ip_address}:2012\",'\\\'"
"ansible all -i 127.0.0.1, -m lineinfile -u root -a'dest=/etc/setup.json state=present regexp=rpc_json line='\\''\"rpc_json\": \"127.0.0.1:2012\",'\\'"
iex(11)> :os.cmd String.to_charlist(cmd)
'127.0.0.1 | UNREACHABLE! => {\n "changed": false, \n "msg": "Failed to connect to the host via ssh: ssh_askpass: exec(/usr/X11R6/bin/ssh-askpass): No such file or directory\\r\\nHost key verification failed.\\r\\n", \n "unreachable": true\n}\n'

GNU parallel sorted stdout and stderr

I've been using GNU parallel and I want to keep output order (--kepp-order), grouped by jobs (--grouped) but also with sorted stdout and stderr. Right now, the grouped options first print stdout and only after does it print stderr.
As an example, any way that these two commands give the same output?
seq 4 | parallel -j0 'sleep {}; echo -n start{}>&2; sleep {}; echo {}end'
seq 4 | parallel -j0 'sleep {}; echo -n start{} ; sleep {}; echo {}end'
thanks,
As per the comment to the other answer, to keep the output ordered, simply have parallel's bash invocation redirect stderr to stdout:
parallel myfunc '2>&1'
E.g.,
parallel -j8 eval \{1} -w1 \{2} '2>&1' ::: "traceroute -a -f9" traceroute6 ::: ordns.he.net one.one.one.one google-public-dns-a.google.com
You cannot do that if you still want stderr and stdout to be separated.
The reason for this is that stderr and stdout are buffered to 2 different files using buffered output.
But maybe you can explain a bit more on what you need this for. In that case there might be a solution.
Assuming that you don't have to use gnu parallel, and the main requirements are parallel execution with maintained ordered output of both stderr and stdout; we can create a solution that allows for the following example usage(plus providing return code), where you will have the results of the executions in a list, where each list element is in return a list of 3 strings: indexed as 0=stdout, 1=stderr and 2=return code.
source mapfork.sh
ArgsMap=("-Pn" "-p" "{}" "{}")
Args=("80" "google.com" "25" "tutanota.com" "80" "apa bepa")
declare -a Results=$(mapfork nmap "(${ArgsMap[*]#Q})" "(${Args[*]#Q})")
So, in order to print for example the stderr results, of the third destination ("apa bepa"), you can do:
declare -a res3="${Results[2]}"
declare -p res3
# declare -a res3=([0]=$'Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-21 18:55 CEST\nNmap done: 0 IP addresses (0 hosts up) scanned in 0.09 seconds' [1]=$'Failed to resolve "apa bepa".\nWARNING: No targets were specified, so 0 hosts scanned.' [2]="0")
printf '%b\n' "${res3[1]}"
mapfork.sh is shown below. It is a bit complicated but it's parts have been explained in other answers so I won't provide the details here as well:
Capture both stdout and stderr in Bash [duplicate]
How can I make an array of lists (or similar) in bash?
#!/bin/bash
# reference: https://stackoverflow.com/questions/13806626/capture-both-stdout-and-stderr-in-bash
nullWrap(){
local -i i; i="$1"
local myCommand="$2"
local -a myCommandArgs="$3"
local myfifo="$4"
local stderr
local stdout
local stdret
. <(\
{ stderr=$({ stdout=$(eval "$myCommand ${myCommandArgs[*]#Q}"); stdret=$?; } 2>&1 ;\
declare -p stdout >&2 ;\
declare -p stdret >&2) ;\
declare -p stderr;\
} 2>&1)
local -a Arr=("$stdout" "$stderr" "$stdret")
printf "${i}:%s\u0000" "(${Arr[*]#Q})" > "$myfifo"
}
mapfork(){
local command
command="$1"
local -a CommandArgs="$2"
local -a Args="$3"
local -a PipedArr
local -i i
local myfifo=$(mktemp /tmp/temp.XXXXXXXX)
rm "$myfifo"
mkfifo "$myfifo"
local -a placeHolders=()
for ((i=0;i<${#CommandArgs[#]};i++)); do
[[ "${CommandArgs[$i]}" =~ ^\{\}$ ]] && placeHolders+=("$i") ;done
for ((i=0;i<${#Args[#]};i+=0)); do
# if we have placeholders in CommandArgs we need to take args
# from Args to replace.
if [[ ${#placeHolders[#]} -gt 0 ]]; then
for ii in "${placeHolders[#]}"; do
CommandArgs["$ii"]="${Args[$i]}"
i+=1; done; fi
nullWrap "$i" "$command" "(${CommandArgs[*]#Q})" "$myfifo" &
done
for ((i=0;i<${#Args[#]};i+=$(("${#placeHolders[#]}")))) ; do
local res
res=$(read -d $'\u0000' -r temp <"$myfifo" && printf '%b' "$temp")
local -i resI
resI="${res%%:*}"
PipedArr[$resI]="${res#*:}"
done
# reference: https://stackoverflow.com/questions/41966140/how-can-i-make-an-array-of-lists-or-similar-in-bash
printf '%s' "(${PipedArr[*]#Q})"
}

Nmap and grepping of its results

folks.i would like to do reverse dns resolution using nmap where the output will be like below
Ip address resolved name
how do i go about it using grep, thanks
This should do:
nmap 8.8.8.8 | awk '/report/ {split($NF,a,"[()]");print a[2],$5}'
8.8.8.8 google-public-dns-a.google.com
The option to do reverse name resolution in Nmap (without also doing a port scan or host discovery) is -sL. Nmap also has a machine-readable output format called Grepable output, using the -oG option.
Your question asks for a solution using grep, but extracting portions of output lines is not grep's strong suit. For this, you can use awk instead:
nmap -sL 192.0.2.0/24 -oG - | awk '/^Host/{print $2, $3}'
This will have the output in this format:
64.13.134.52 (scanme.nmap.org)
If you want to remove the parentheses, you can pipe the output through tr:
nmap -sL 192.0.2.0/24 -oG - | awk '/^Host/{print $2, $3}' | tr -d '()'

Resources