![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Поштівки шелóві
Колись на початку 2000х були популярні сервіси віртуальних откриток, де були колекції чиїхось котів с бльосткамі і формою для поздоровлень.
Зараз емулятор терміналу є на будь-якій ОС майже зразу після її інсталяції. Можна штампувати текстові поштівки, які будуть працювати будь-де. Наприклад:
$ fold -w40 hello
tail -c+37 "$0"|base64 -d|gzip -cd
#H4sIAC1EjWUAA62TzQqDMAyA7z71/tA5GLLbdjK
pwthtJ90Y2HfJk8ymrbTaThlCkDQ/X9I0UiVpDUl
mIlASbJSIz2JQnyNGlJIRQHgIsPx4B6Qrjyna0rL
36IH8+DgIMj521sJH8foDxJeKt7AMhJP6ypiuBcq
WgaqaJQ4CH+TGh/bobktFxHi7UWJoIYNbY5oqmPK
cuuY2+4cgf4ULwoLEmwvmtnJOwBY8KwVKEg+q+nZ
uvNC5SoELYUNw0rmJGa1amdrMEvYEV3M79a/tWNc
FUhJbNSDzGji8ib5aa4fXsN5YY8PSWX1wSUfXATL
5AjV3WkpHBAAA
допитливому тхіру скаже мало, доки він скрипта не запустить:
$ ./hello
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
⣿⣿⣿⡿⢿⣿⣿⣿⣿⡟⠀⢠⡄⠀⢻⣿⣿⣿⣿⡿⢿⣿⣿⣿
⣿⣿⣿⠀⠀⣿⣿⣿⡟⠀⢀⣿⣷⠀⠈⣿⣿⣿⣿⠀⠀⣿⣿⣿
⣿⣿⣿⠀⠀⣿⣿⣿⠇⠀⣾⣿⣿⣇⠀⢸⣿⣿⣿⠀⠀⣿⣿⣿
⣿⣿⣿⠀⠀⣿⣿⣿⠀⢠⣿⣿⣿⣿⠀⠀⣿⣿⣿⠀⠀⣿⣿⣿
⣿⣿⣿⠀⠀⣿⣿⡇⠀⢸⣿⣿⣿⣿⡆⠀⣿⣿⣿⠀⠀⣿⣿⣿
⣿⣿⣿⠀⠀⣿⣿⡇⠀⢸⣿⣿⣿⣿⡇⠀⣿⣿⣿⠀⠀⣿⣿⣿
⣿⣿⣿⣤⣤⣿⣿⡇⠀⢸⣿⣿⣿⣿⠇⠀⣿⣿⣿⣤⣤⣿⣿⣿
⣿⣿⣿⣿⣿⣧⠀⠀⣀⣀⣀⣀⣀⣀⣀⣀⠀⠀⣾⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⡄⠀⢻⣿⣿⣿⣿⣿⣿⠏⠀⣰⣿⣿⣿⣿⣿⣿
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⣿⢿⣿⣿
⣿⡏⢹⣿⠉⣿⣿⠉⠹⣿⡍⠹⠟⢩⣏⠙⡿⢉⡏⠑⡶⠊⢹⣿
⣿⡇⢠⣤⠀⣿⠃⠘⠀⢻⡿⠂⠀⢿⣿⠆⢁⣾⡇⠀⢡⠀⢸⣿
⣿⣷⣾⣿⣶⣷⣶⣿⣷⣶⣶⣾⣷⣶⣷⣶⣿⣿⣷⣶⣿⣶⣾⣿
(Цей ascii art я знайшов на гітхабі.)
Я би залишив результат gzip'у ув коментарі і так, без base64, але тоді у bash стається інфаркт, коли він бачить '\0'. Shebang, якщо хтось забув, у багатьох випадках є необов'язковим.
hello
був згенерований ось цим скриптом, який читає повідомлення для
користувача з stdin:
#!/bin/sh
prefix() { printf 'tail -c+37 "$0"|base64 -d|gzip -cd\n#'; }
script=`mktemp`
trap 'rm -f $script' 0
prefix > "$script"
gzip -c | base64 -w0 >> "$script"
chmod +x "$script"
mv "$script" "${1:-hello}"
Можна піти ще далі та генерувати секретну поштівку яка вимагає пароля для показу поздоровлення. На жаль, у такому випадку, гарантія на присутність потрібної утілити (openssl) є відсутня. Є варіянт з xor cipher'ом на awk, чи з тасканням вихідного коду якогось chacha20 на C (але тоді отримувач має мати компілятора), або з вбудованим ув скрипта αcτµαlly pδrταblε εxεcµταblε, який буде байти розшифровувати.
Про тулчейна Cosmopolitan Libc чули майже всі під час кетайської чуми, але я не бачив щоб хтось його використовував.
Наприклад, мінімальна реалізація rc4:
#define S ,t=s[i],s[i]=s[j],s[j]=t /* rc4 hexkey <file */
unsigned char k[256],s[256],i,j,t;main(c,v,e)char**v;{++v;while(++i)s[
i]=i;for(c=0;*(*v)++;k[c++]=e)sscanf((*v)++-1,"%2x",&e);while(j+=s[i]
+k[i%c]S,++i);for(j=0;c=~getchar();putchar(~c^s[t+=s[i]]))j+=s[++i]S;}
компілюється ув такий exe
$ file rc4
rc4: DOS/MBR boot sector; partition 1 : ID=0x7f, active,
start-CHS (0x0,0,1), end-CHS (0x3ff,255,63), startsector 0, 4294967295 sectors
$ du rc4
404K rc4
який запускається на лайнаксі (x86_64 чи aarch64) або fbsd (має також на маку, але я не перевіряв).
Тоді секретна поштівка буде виглядати так:
- байнарі rc4 пхається ув коментар;
- ув наступному коментарі--зашифроване поздоровлення;
- скрипта слайсить потрібні діапазони самого себе (
$0
) щоб видобути пп. 1-2; - питає пароля, розшифрофує текта.
Щоб згенерувати це, простіше всього використати якийсь templating engine, наприклад рубівський erb:
$ cat message.erb
#<%= rc4=File.read(rc4) %>
#<%= message=File.read(message) %>
slice() { tail -c+$1 "$0" | head -c $2 | base64 -d | gzip -cd; }
cleanup() { rm -f "$rc4"; stty echo; }
set -e
rc4=`mktemp`
trap cleanup 0
trap 'cleanup; echo 1>&2; exit 1' 1 2 15
slice 2 '<%= rc4.length %>' > "$rc4"
chmod +x "$rc4"
stty -echo
printf 'Password: ' 1>&2; read -r password; printf "\n" 1>&2
[ -n "$password" ]
hexkey=`printf '%s' "$password" | od -A n -t x1 -v | tr -d ' \n'`
slice '<%= rc4.length+4 %>' '<%= message.length %>' | "$rc4" $hexkey
erb пускається з параметрами rc4=
та message=
$ erb rc4=rc4.text message=message.text message.erb
де *.text є файли з підготовленим base64.
Мейкфайла:
out := _out
password := monkey
message := hello1.txt
CC := ~/opt/s/cosmocc/bin/cosmocc
all: $(out)/message
$(out)/%: %.c
@mkdir -p $(dir $@)
$(CC) --std=c89 -o $@ $<
$(out)/message: message.erb $(out)/rc4
gzip -c < $(out)/rc4 | base64 -w0 > rc4.text
$(out)/rc4 $(hexkey) < $(message) | gzip -c | base64 -w0 >message.text
erb rc4=rc4.text message=message.text $< > $@
chmod +x $@
rm *.text
.DELETE_ON_ERROR:
hexkey = $(shell printf '%s' $(call se,$(password)) | od -A n -t x1 -v | tr -d ' \n')
se = '$(subst ','\'',$1)'
Космополітанський тулчейна очікується ув ~/opt/s/cosmocc/
.
$ make password="всім нам" message=hello2.txt
...
$ du _out/message
304K _out/message
Так, 304KB здається трохи забагато, але по сьогоднішнім стандартам це є ніщо.
$ _out/message
Password:
▁
▃ ▅▖
▘ ▄
┏▃ ▌ ▘▌ ▖ ▃▄▌
▎ ▌ ▌ ▌ ▖ ▊ ▊ ▎
▎ ▌ ▎ ▗ ▌ ▌ ▊ ▎
▎ ▌ ▌ ▌ ▎ ▊ ▊ ▎
▎ ▌ ▌ ▊ ▊ ▎ ▊ ▎
▎ ▌ ▎ ▌ ▌ ▎ ▊ ▎
▎ ▌ ▊ ▌ ▊ ▌ ▊ ▎
▎ ▌ ▊ ▌ ▊ ▌ ▊ ▎
▅▅▘▂▂▂▎ ▊▂▂▂▂▂▂ ▂▂▂▖▅▅▘
▌ ▁▁▁▁▁▁▁▁▁▁▁ ▎
▝▖ ▝ ▌ ▗
▝▄▄▃ ╺▄▄▄
▗▂▂▄
▊▅▌ ┏▖ ▃▅▖ ▄▅▄▃▅╸▄▄▁▃▄▌▅▌▗▅▖
▊ ▆▆ ▊ ▗ ▄ ▖ ▊ ▌ ▝▖▅▗▘▊ ▄▗ ▌
▊▂▌ ▂┛▌▂▅▅▂▂▄▂▅▃▂▖▄▂▄ ▌▂▄▊▂▌
Бовзери це рендерять погано.