получение вывода от netcat, его декодирование и возвращение вывода

Очень грубо:

awk '
    BEGIN { d = -1 }
    /lcpu/ { lcpu = substr($3, 6); next }
    $1 == "r" { ++d; next }
    d < 0 { next }
    {
        ++d
        r += $1
        id += $16
        next
    }
    END {
        if (r / d > lcpu)
            print 100 - id / d
        else
            print 0
    }
'

или, если хотите:

awk '
    /lcpu/ { lcpu=substr($3, 6) }
    $1 ~ /[0-9]+/ {
        ++d
        r += $1
        id += $16
        next
    }
    END {
        print (r/d>lcpu) ? 100 - id / d : 0
    }
'

to:

awk '/lcpu/{lcpu=substr($3,6)}$1~/[0-9]+/{++d;r+=$1;id+=$16;next;}END{print(r/d>lcpu)?100-id/d:0}'

Дает ли это желаемый результат?

{{ 1}}
4
21.11.2018, 23:54
4 ответа

Вот частичное решение, я разочаровался, заставив вводить скрипт netcat.

  1. Как мне тогда искать конкретно шестнадцатеричную строку?

Вот один простой способ:

$ nc -d cs2107.spro.ink 9000> file

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.
Return the md5 hash in hex encoded format back to me.
You will need to do this 500 times.
Ready? Go!
eeb105fb2f5e24216bd2
MD5:

Здесь изначально был ] sed , которая выбрала конкретную строку №7, но после решения первой строки байтов в шестнадцатеричной кодировке немедленно выдается следующий вывод. Поэтому я просто заменил это регулярным выражением, которое соответствует шестнадцатеричным символам:

$ cat file.txt | grep '^ [a-f0-9]'

eeb105fb2f5e24216bd2
  1. Как мне декодировать шестнадцатеричную строку?

$ cat file.txt | grep '^ [a-f0-9]' | xxd -r -p | md5

92b34e4055a92b9ec32b15f89cc22389

Итак, я получил подтверждение, что это работает вручную:

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.
Return the md5 hash in hex encoded format back to me.
You will need to do this 500 times.
Ready? Go!
eeb105fb2f5e24216bd2
MD5: 92b34e4055a92b9ec32b15f89cc22389
Correct.
9ecbc2b8d14ae903dce5
  1. И, наконец, как мне вернуть результат обратно в терминал?

Этот последний вопрос действительно является самой большой проблемой. Я не смог заставить его работать. Я написал несколько скриптов, и ни один из них не решил проблему. Проблема, как упомянул Жиль , заключается в том, что вам нужно поддерживать соединение открытым достаточно долго, чтобы прочитать данные и передать их все еще открытой программе. Это мешает обычному подходу к использованию передаваемых по конвейеру команд в оболочке, подобных тем, которые я опубликовал выше.

Это псевдокод, который мне постоянно не удается правильно реализовать в сценарии оболочки:

  1. цикл for, итерация 500 раз. РАБОТАЕТ.
  2. поддерживать соединение с: cs2107.spro.ink 9000. В ПРОЦЕССЕ.
  3. читать биты, отправленные сервером. РАБОТАЕТ.
  4. декодировать шестнадцатеричную строку. РАБОТАЕТ.
  5. вычислить хэш MD5. РАБОТАЕТ.
  6. отправить ввод для открытия соединения. В ХОДЕ ВЫПОЛНЕНИЯ.
  7. повторите шаги 3-6.
  8. конец.

Вот некоторые ресурсы, которые я пробовал

  1. Использование именованных каналов ввода / вывода для TCP-соединения
  2. https://serverfault.com/questions/188936/writing-to-stdin-of-background-process/297095 # 297095
  3. https://stackoverflow.com/questions/21130757/send-commands-to-socket-using-netcat
  4. https://superuser.com/questions/261900/how-can-i-pipe -commands-to-a-netcat-that-will-stay-alive
  5. -shell-function
  6. http://www.linuxquestions.org/questions/programming-9/dynamically-supply-input-to-netcat-in-a-script-793526/

Мне было бы любопытно узнать решение, если вы его узнаете. Может, попробую позже.

2
27.01.2020, 20:53

Вы правы, что мы должны программировать сокеты для связи с сервером. Раньше я пробовал Python, но в итоге вместо этого использовал простые старые скрипты Bash.

Для начала вы можете взглянуть на то, как инициализировать сокет с помощью Bash, следуя руководству здесь: http://hacktux.com/bash/socket

Шаг 1: Инициализировать сокет

Вы можете использовать Bash exec и перенаправление unix <> для создания сокета на псевдопуть. Синтаксис пути: / dev / / /

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

Шаг 2. Чтение выходных данных сервера

Нам нужно прочитать закодированные байты из вывода сервера. Это можно сделать с помощью команды cat , но это не сработает так, как вы ожидали. Это связано с тем, что сервер ожидает ввода от клиента и нет символа EOF. (Я предполагаю, что это связано с потоковой передачей данных) Чтобы предотвратить это, вам нужно избегать чтения за пределами вывода сервера, то есть останавливаться на строке 7.

head -7 <& 3

Шаг 3: Grepping & преобразование данных

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

После того, как мы прочитали кусок информации, мы можем использовать egrep для получения шестнадцатеричных байтов. Поскольку длина шестнадцатеричного дампа фиксирована, мы можем использовать регулярное выражение для извлечения необходимых данных.

Передача шестнадцатеричного дампа по конвейеру xxd -r -p преобразует шестнадцатеричный дамп в двоичный и выведет их как обычный текст. Затем md5sum выполнит грязную работу и вычислит за нас ответ.

Шаг 4: Обратная запись на сервер

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

В моем случае md5sum выводит ответ и дополнительный символ в конце строки, поэтому я использую awk для печати первого столбца и обратной записи на сервер.

Шаг 5: повторить еще 499 раз

Аналогично шагам 2-4, за исключением того, что нам нужно изменить шаг 2, потому что сервер будет выводить только «правильно» в последующем ответе вместо длинного вводного текста. Измените заголовок , чтобы он читался в 2 строки. Нам также нужно сделать это еще 499 раз:

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

Шаг 5: Захватить флаг

После того, как все ответы 500 были завершены, флаг может быть получен путем захвата сокета.

cat <& 3

P / S Я брал тот же модуль и выполнял то же задание, что и OP, так что, думаю, я поделюсь своим ответом здесь. Просто случайно узнал об этом посте после завершения модуля.

3
27.01.2020, 20:53

Выполнить это с оболочкой, которая вызывает nc сложно, потому что вам нужно держать соединение открытым и получить данные из nc, обработать эти данные и передать их обратно в тот же экземпляр nc. Это можно сделать, но это сложно.

Было бы намного проще, если бы вы могли взаимодействовать с сетью и контролировать поток данных на одном языке. Если вы используете одну из оболочек bash, ksh или ksh, то вы можете использовать их сетевые возможности: эти оболочки могут быть TCP-клиентами. Например, вот сценарий, который считывает строки с сервера и выводит их одну за другой:

{
  while IFS= read -r line <&3; do
    echo "$line" >&3
  done
} 3<>/dev/tcp/cs2107.spro.ink/9000

Чтобы декодировать шестнадцатеричную строку, найдите xxd. Я позволю вам разработать логику обработки данных.

0
27.01.2020, 20:53

Просто используйте трубы:

...
process_rcvd_msg() {
   while IFS= read -r msg && [[ -n $msg ]]; do
      ... do whatever you want with the message...
       echo "Received: $msg"
   done
}

... more code...
# Start listening to TCP requests and processing them
nc -k -vv -l 1234 | process_rcvd_msg
... few more code here...

Отправить данные на сервер стало еще проще:

...
send_msg() {
    local host="$1" ; shift
    local port="$1" ; shift
    local params="$*"

    exec 9<>/dev/tcp/$host/$port
    printf "%s" "$params" >&9
    exec 9<&-
}
... do something here...
# Send the message to the server
send_msg localhost 1234 "Dumb message is here!!! Let's see what happens..."
... do year another thing...

Надеюсь, это помогло. Ваше здоровье!

0
29.06.2021, 15:36

Теги

Похожие вопросы