Python – getting output from netcat, decoding it and returning an output

netcatpythonscripting

I have to get an output from netcat, decode it and return it.

after typing:

nc cs2107.spro.ink 9000

the output i get is this:

Welcome to the Proof of work challenge!  
Rules: i will provide hex encoded byte strings to you.  
Your task is to decode it and calculate the md5 hash in hex encoded format and return it back to me. You will need to do this 500 times!

Ready? Go!

cdde140fffda1da2bc3f

MD5:

So I have to get take in that hex encoded string, decode it and output it again and that's suppose to happen 500 times.

I think I know what I have to do but I have no idea how to code it in unix. I think an .sh file is needed? But i'm not very sure.

  1. start with nc cs2107.spro.ink 9000

  2. search for the hex string from the nc output

  3. decode it and calculate the md5 hash

  4. finally, send it back

edit:

i know i'm able to save the output of nc by doing so

nc cs2107.spro.ink 9000 > somefile.txt  

how do i then search specifically for the hex string?
how do i decode the hex string?
and finally how to i return the result back into the terminal?

edit2:
so i'm allowed to use python to do this assignment. some hints were to either use the subprocess module or the sockets module. tried doing it with subprocess as i read that

subprocess.Popen

keeps the command running in the background

i'm currently stuck with this

import subprocess
p = subprocess.Popen('nc cs2107.spro.ink 9000', shell = True, stdin = subprocess.PIPE, stdout = subprocess.PIPE)
a = subprocess.Popen('grep ^[0-9a-f] | xxd -r | md5sum | awk "{print $1}" ', stdin = p.stdout, stdout = subprocess.PIPE)

now i'm stuck trying to pipe a back into p

Best Answer

You are right that we are expected to do socket programming in order to communicate with the server. I tried Python before but ended up with using plain old Bash scripts instead.

For starters, you can take a look at how to initialize a socket with Bash by following the tutorial here: http://hacktux.com/bash/socket

Step 1: Initialize socket

You can make use of Bash exec and unix redirection <> to create a socket on the pseudo-path. The path syntax is /dev/<protocol>/<host>/<port>

exec 3<>/dev/tcp/cs2107.spro.ink/9000;

Step 2: Reading server output

We need to read the encoded bytes from the server output. This can be done with cat command but it will not work as you expected. This is because the server is waiting for the input from client and there's no EOF character. (I'm guessing it's related to streaming data) In order to prevent this you need to avoid reading beyond the server output, that is, stop at line 7.

head -7 <&3

Step 3: Grepping & transformation of data

egrep -o '^[0-9a-f]{20}' | xxd -r -p | md5sum

After we get read in the chunk of information, we can make use of egrep to retrieve the hex bytes. Since the hexdump length is fixed, we can make use of regular expression to extract the required data.

Piping the hexdump to xxd -r -p will convert hexdump into binary and output them as plain text. md5sum will then do the dirty work and calculate the answer for us.

Step 4: Writing back to Server

awk '{print $1}' >&3;

In my case md5sum output the answer and extra character at the end of string, so I make use of awk to print the first column and write back to server.

Step 5: Repeat another 499 times

Similar to the steps 2-4, except that we need to modify step 2 because the server will only output "correct" in subsequent response instead of long introductory text. Modify the head to read in 2 lines. We also need to do this for another 499 times:

for i in {1..499}
do
    head -2 <&3 | egrep -o '^[0-9a-f]{20}' | xxd -r -p | md5sum | awk '{print $1}' >&3;
done

Step 5: Capture the flag

Once all 500 response has been completed, the flag can be retrieved by catting the socket.

cat <&3

P/S I was taking the same module and doing the same assignment as OP so I guess I'll be sharing my answer here. Just happened to found out this post after the module ended.

Related Question