18

While solving some CTF challenges online, I came across a situation where I needed to bruteforce a server. This is the code I wrote:

#!/bin/bash

for i in {0..9}{0..9}{0..9}{0..9} 
    do
    echo "Now trying code.."
    echo $i
    echo "a fixed string" $i | nc localhost *port here* >> /tmp/me/dump.txt
    done

This was incredibly, painfully slow. I needed to try combinations from 1000 to 9999 and this took around 5 seconds for each 10 tries. Then, following an advice, I put a '&' at the end of this line:

   echo "a fixed string" $i | nc localhost *port here* >> /tmp/me/dump.txt &

And, it tried 100s of combinations within seconds. I was very surprised. Could someone explain the logic to me? What did the '&' do?

  • 3
    I suggest you read your shell manual. & makes the command run in the background, that's all. It didn't make it faster or anything. Read whatever shell's you're using (I assume bash) manual. – polemon Apr 4 '15 at 12:31
  • It made it run in the background, you should look it it's actually finished. – DisplayName Apr 4 '15 at 12:49
  • 7
    You do not want to test beneath 1000? Please use for i in {1000..9999} – Walter A Apr 4 '15 at 13:00
  • 2
    It's possible it did make the script run faster since the ports are now timing out in parallel. You should include a wait at the end, though. – Bratchley Apr 4 '15 at 13:00
  • Did you look at nc -z localhost 1000-2000 ? – Walter A Apr 4 '15 at 13:08
30

Adding & spawns a background process.

If you write a; b, it will run command a, wait for it to finish, then run command b, in sequence.

If you write a & b, it will spawn a as a background process. It will not wait for it to finish, and it will start running b immediately. It will run both at once.

You can see what it does by experimenting in the shell. If you have X installed, xterm is a good way to see what happens: typing

$ xterm

will cause another terminal window to open, and the first one will wait until you close it. Only when you close it will you get your shell back. If you type

$ xterm &

then it will run it in the background, and you will get your shell back immediately, while the xterm window will also remain open.

So if you write

echo "a fixed string" $i | nc localhost *port here* >> /tmp/me/dump.txt

it makes the connection, sends the string, stores what comes out in the file, and only then moves on to then next one.

Adding the & makes it not wait. It will end up running all ten thousand of them more or less simultaneously.

Your script seems to "end" more quickly, because it probably did not actually finish in that time. It just made ten thousand background jobs, and then ended the foreground one.

This also means that, in your case, it will try to open ten thousand connections more or less at once. Depending on what the other end can handle, some of them might well fail. Not only that, but there is no guarantee that they will run in order, in fact they almost certainly won't, so what will actually end up in /tmp/me/dump.txt is anyone's guess.

Did you check if the output was correct?

  • 2
    Yes, I solved the challenge. The server was to respond with the password if the correct code was provided to it. I executed this command to check 'dump.txt': $ cat dump.txt | sort | uniq -u ..and the line containing the correct password was revealed to me. – learnerX Apr 4 '15 at 13:06
  • 16
    @intellikid: I don't mean to be rude, but it worked through sheer luck. Not only did the order not matter, the server's responses were smaller than nc's write buffer. Had this not been the case, the server's responses would very likely have been interleaved. I.e., if you had had a write buffer of 1 byte, and the responses were 1111 and 2222, you would likely have seen something like 11221212 rather than a neatly separated 1111 2222. – marinus Apr 4 '15 at 14:01
  • Yes, I realized that. That is why I'm playing these wargames. I learn at each level. Thank you for aiding that learning. – learnerX Apr 5 '15 at 13:46
2

The nc (netcat) command is costly, time wise. It needs to connect to the remote server, send the data, wait for a response, and return it.

By using & you're basically forking that command in a background process (it's called a "job"). By itself that doesn't make it run faster. But it does mean your loop is no longer blocked, and can do the next iteration (with the next nc) already.

So basically, your speedup is caused by making all these remote connections in parallel where otherwise they would have to wait for the previous one to complete.

Btw, depending on your terminal, echo commands can also slow down your loop (they sometimes need to wait until there is space in the write buffer).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.