Za što je sposoban mozak učenika koji uči o svijetu računala?

Dobar dan.

Nakon što sam završio pisanje druge skripte u Bashu, shvatio sam da bi sve trebalo biti potpuno drugačije, ali sve je funkcioniralo. Želim vam pokazati koje sam bezobrazluke i štake napisao da bih riješio problem, ali još nemam vagon znanja. Drugim riječima, karikatura programiranja.

Zadatak


Nešto je postalo potrebno za:

  • Prikazane mnoge rime za riječ, osim za kvadrate
  • Ukrstio mnoge rime dviju riječi

Za što? Pa to je to – i to je to.
Tko ne zna, kvadratna rima (u običnom govoru - kvadrat) su dvije riječi čija se posljednja dva slova u pravopisu podudaraju, što ih (često jedino to) čini rimom. Na primjer, ruže su ledene; guma - auto. Korištenje kvadrata u suvremenoj versifikaciji ljudi ne odobravaju osobito zbog njihove primitivnosti.

odluka


Činilo mi se da je najjednostavnije rješenje napisati skriptu u Bashu koja koristi već postojeći generator rima - HOST, koji ih primarno odabire po konsonanciji, a ne po pravopisu. Kakav HOST? Jer ako navedete pravi naziv stranice, reći će da je to reklama. Zašto ga ne biste nastavili koristiti? Prvo, unatoč njegovoj prednosti odabira rima na temelju suzvučja, on još uvijek često proizvodi kvadrate. Drugo, još uvijek morate razmišljati svojim mozgom, trošiti vrijeme na prebacivanje između kartica i energiju na pamćenje ponovljenih riječi na popisima kako biste pronašli rimu za dvije riječi.

Dobivanje jakih rima

Što ja znam? Znam za uslužni program wget, koji preuzima stranicu na navedeni URL. U redu, izvršimo zahtjev - dobivamo HTML stranicu u datoteci s nazivom riječi koja se rimuje. Na primjer, pretražimo riječ "ovdje":

wget https://HOST/rifma/здесь

Ali trebam samo popis riječi, kako se mogu riješiti svega ostalog? Gledamo i vidimo da je lista riječi formatirana, koliko god to čudno bilo, u obliku liste, a riječi su u tagovima . Pa, imamo veliku pomoć. žeđ - zapišimo to ovako:

cat $word | grep '<li>' | sed -e "s%<li>%%" | sed -e "s%</li>%%" | sed -e "s/ //g" | sed -e "/^$/d" 1> $word

Najprije iz Word datoteke odaberite retke koji sadrže oznaku — dobivamo hrpu praznih oznaka i redaka s riječima. Uklanjamo samu oznaku i njenu završnu oznaku - ovdje se umjesto kosih crta koriste simboli postotaka jer u samoj oznaci već postoji kosa crta, zašto? žeđ malo te ne razumije. A s kamatama je sve u redu. Uklanjamo sve razmake iz datoteke, uklanjamo prazne retke. Voila - gotov popis riječi.

Kako biste uklonili riječi koje se rimuju korištenjem zadnjih slova, odaberite posljednja dva slova iz originalne riječi i očistite popis:

squad=${word:((${#word}-2)):2}
cat $word | sed -e "/.$squad$/d" 1> $word

Gledamo, pokušavamo - sve radi... pa, gdje je popis za riječ "play"? A za riječ "Idem"? Datoteka je prazna! A sve je to zato što su te riječi glagoli, a znamo što čine onima koji se rimuju s glagolima. Glagolska rima je gora čak i od uglate rime, jer ruski jezik ima najviše glagola, a svi imaju iste završetke, zbog čega nisu bili u konačnoj datoteci nakon provjere završetaka.

Međutim, nama se ne žuri. Za svaku riječ ne postoje samo rime, već i asonance, koje ponekad zvuče puno bolje od rime - zato su i asonance (francuski assonance, od latinskog assono - zvučim usklađeno).

Dobivamo asonance

Ovdje počinje zabava: asonance se pojavljuju na zasebnom URL-u, a na istoj stranici, izvršavanjem skripte, slanjem HTTP zahtjeva i primanjem odgovora. Kako mogu reći wget'Pritišćeš li tipku? Ali nikako. Nažalost.

Primijetivši da se URL u retku nekako mijenja, kopirao sam ono što je bilo nakon prebacivanja na asonance i zalijepio to u novu karticu preglednika - otvorile su se jake rime. Ne to.

U biti, pomislio sam, poslužitelju ne bi trebalo biti važno hoće li se skripta koja mu šalje zahtjev izvršiti ili ga osoba upisuje rukom. Tako? Tko zna, idemo provjeriti.

Gdje poslati? Što poslati? HTTP zahtjev prema IP poslužitelju, postoji nešto kao GET... zatim postoji nešto HTTP/1.1... Moramo vidjeti što preglednik šalje i gdje. Instalirati Wireshark, pogledajte promet:

0040 37 5d a3 84 27 e7 fb 13 6d 93 ed cd 56 04 9d 82 7]£.'çû.m.íÍV...
0050 32 7c fb 67 46 71 dd 36 4d 42 3d f3 62 1b e0 ad 2|ûgFqÝ6MB=ób.à.
0060 ef 87 be 05 6a f9 e1 01 41 fc 25 5b c0 77 d3 94 ï.¾.jùá.Aü%[ÀwÓ.

Hm... što? O da, imamo HTTPS. Što uraditi? Pokrenuti MITM napad na sebe? U idealnom slučaju, sama žrtva će nam pomoći.

Općenito, nakon što sam odlučio surfati preglednikom, konačno sam pronašao sam zahtjev i primatelja. Ići:

Dijalog s terminalom

telnet IP PORT
Trying IP...
Connected to IP.
Escape character is '^]'.
GET /rifma/%D0%BC%D0%B0%D1%82%D1%8C?mode=block&type=asn HTTP/1.1
Host: HOST
Accept-Language: en-US,en;q=0.5
X-Requested-With: XMLHttpRequest
Connection: close

HTTP/1.1 400 Bad Request
Server: nginx/1.8.0
Date: Sun, 03 Nov 2019 20:06:59 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 270
Connection: close

<html>
<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>The plain HTTP request was sent to HTTPS port</center>
<hr><center>nginx/1.8.0</center>
</body>
</html>
Connection closed by foreign host.

hej Hehehe. Doista, to je ono što sam očekivao kada sam slao goli HTTP zahtjev na HTTPS priključak. Trebamo li sada šifrirati? Sva ova frka s RSA ključevima, pa sa SHA256. Zašto, postoji OpenSSL za takve stvari. Pa već znamo što nam je činiti, samo ćemo prvo ukloniti polja Referer i Cookie - mislim da neće puno utjecati na stvar:

Dijalog s terminalom

openssl s_client -connect IP:PORT
{Всякие ключи, сертификаты}
GET /rifma/%D0%B7%D0%B4%D0%B5%D1%81%D1%8C?mode=block&type=asn HTTP/1.1
Host: HOST
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:70.0) Gecko/20100101 Firefox/70.0
Accept: text/javascript,text/html,application/xml,text/xml,*/*
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
X-Requested-With: XMLHttpRequest
Connection: keep-alive

HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Status: 200 OK
Date: Sun, 03 Nov 2019 20:34:33 GMT
Set-Cookie: COOKIE
X-Powered-By: Phusion Passenger 5.0.16
Server: nginx/1.8.0 + Phusion Passenger 5.0.16
Expires: Thu, 01 Jan 1970 00:00:01 GMT
Cache-Control: no-cache
Strict-Transport-Security: max-age=31536000
Content-Security-Policy: block-all-mixed-content
Content-Encoding: gzip

Za što je sposoban mozak učenika koji uči o svijetu računala?

Što je ovo, psovanje na serveru? Pa barem su mi odgovorili 200 OK, što znači da cookies i referer ne utječu na ništa. Kompresija je gzip, ali prilikom kopiranja kopiraju se ASCII znakovi. Točno, možete ukloniti liniju Prihvati-kodiranje. Sve je u redu - dobivamo HTML dokument, sada s asonancijama. Ali evo dva pitanja: kako pokrenuti OpenSSL i prenijeti podatke na njega pomoću skripte? I kako pročitati izlaz ako nakon primitka odgovora ostajemo, takoreći, u OpenSSL "ljusci"? Ako s drugom nešto smisliš, ali s prvom...

Dobro je da postoji Habrgdje sam čitao o korisnosti očekivati, koji automatizira proces interakcije s programima koji očekuju ljudsku interakciju. Imati tim još je privlačnije autoexpect, generiranje očekivati scenarij na temelju vaših radnji. Pa, pokrenemo ga, napravimo sve ovo i evo gotove skripte. Samo što je on vrlo ogroman, a sve zato OpenSSL prikazuje certifikate, ključeve i očekivati čeka rezultate svega ovoga. Treba li nam ovo? Ne. Uklanjamo cijeli prvi prompt, ostavljajući samo zadnji prijelom retka 'r'. Također uklanjamo polja User-Agent i Accept iz našeg zahtjeva - oni ne utječu ni na što. Dakle, pokrenimo. Skripta je izvršena, ali gdje je dragocjeni HTML dokument? Očekivati pojeo ga. Da ga natjerate da ispljune, morate staviti:

set results $expect_out(buffer)

prije kraja skripte - ovako će biti zapisan izlaz izvršne datoteke očekivati'om naredbu i prikazuje se na ekranu. Ukratko, nešto ovako:

očekuj skriptu

#!/usr/bin/expect -f

set timeout -1
spawn openssl s_client -connect IP:PORT
match_max 100000
expect -exact "
---r
"
send -- "GET /rifma/%d0%b7%d0%b4%d0%b5%d1%81%d1%8c?mode=block&type=asn HTTP/1.1rHost: HOSTrAccept-Language: en-US,en;q=0.5rX-Requested-With: XMLHttpRequestrConnection: close"
expect -exact "GET /rifma/%d0%b7%d0%b4%d0%b5%d1%81%d1%8c?mode=block&type=asn HTTP/1.1r
Host: HOSTr
Accept-Language: en-US,en;q=0.5r
X-Requested-With: XMLHttpRequestr
Connection: close"
send -- "r"
set results $expect_out(buffer)
expect -exact "r
"
send -- "r"
expect eof

Ali to nije sve! Kao što vidite, u svim primjerima URL zahtjeva bio je statičan, ali je URL odgovoran za to koja će riječ biti povezana s asonancijama. I tako ispada da ćemo stalno tražiti riječ “%d0%b7%d0%b4%d0%b5%d1%81%d1%8c” u ASCII ili “ovdje” u UTF-8. Što uraditi? Naravno, samo jednostavno generirajte novu skriptu svaki put, prijatelji! Ne više autoexpect'oh, i uz pomoć odjek, jer U našem novom ništa se ne mijenja osim riječi. I živio novi problem: kako možemo inteligentno prevesti riječ iz ćirilice u URL format? Ni za terminal nema ništa posebno. Pa, u redu je, možemo mi to, zar ne? Limenka:

Pogledaj što mogu!

function furl {
furl=$(echo "$word" | sed 's:А:%d0%90:g;s:Б:%d0%91:g;s:В:%d0%92:g;s:Г:%d0%93:g;s:Д:%d0%94:g;s:Е:%d0%95:g;s:Ж:%d0%96:g;s:З:%d0%97:g;s:И:%d0%98:g;s:Й:%d0%99:g;s:К:%d0%9a:g;s:Л:%d0%9b:g;s:М:%d0%9c:g;s:Н:%d0%9d:g;s:О:%d0%9e:g;s:П:%d0%9f:g;s:Р:%d0%a0:g;s:С:%d0%a1:g;s:Т:%d0%a2:g;s:У:%d0%a3:g;s:Ф:%d0%a4:g;s:Х:%d0%a5:g;s:Ц:%d0%a6:g;s:Ч:%d0%a7:g;s:Ш:%d0%a8:g;s:Щ:%d0%a9:g;s:Ъ:%d0%aa:g;s:Ы:%d0%ab:g;s:Ь:%d0%ac:g;s:Э:%d0%ad:g;s:Ю:%d0%ae:g;s:Я:%d0%af:g;s:а:%d0%b0:g;s:б:%d0%b1:g;s:в:%d0%b2:g;s:г:%d0%b3:g;s:д:%d0%b4:g;s:е:%d0%b5:g;s:ж:%d0%b6:g;s:з:%d0%b7:g;s:и:%d0%b8:g;s:й:%d0%b9:g;s:к:%d0%ba:g;s:л:%d0%bb:g;s:м:%d0%bc:g;s:н:%d0%bd:g;s:о:%d0%be:g;s:п:%d0%bf:g;s:р:%d1%80:g;s:с:%d1%81:g;s:т:%d1%82:g;s:у:%d1%83:g;s:ф:%d1%84:g;s:х:%d1%85:g;s:ц:%d1%86:g;s:ч:%d1%87:g;s:ш:%d1%88:g;s:щ:%d1%89:g;s:ъ:%d1%8a:g;s:ы:%d1%8b:g;s:ь:%d1%8c:g;s:э:%d1%8d:g;s:ю:%d1%8e:g;s:я:%d1%8f:g;s:ё:%d1%91:g;s:Ё:%d0%81:g')}

Sve u svemu, imamo skriptu koja pretvara riječ u ASCII tekst, generirajući drugu skriptu koja od poslužitelja putem OpenSSL-a zahtijeva stranicu web-mjesta s asonancijama. Zatim preusmjeravamo izlaz posljednje skripte u datoteku i, na starinski način, prosljeđujemo je "filteri" dodatne kvadrate i zapišite ih u datoteku.

Sjecište mnogih. Poanta

Zapravo, upravo to uzrokuje najmanje problema. Provodimo gornje postupke za dvije riječi, zatim iz dva popisa uspoređujemo svaku riječ sa svakom i ako se pronađe podudaranje, ispisujemo ga. Sada imamo skriptu koja uzima dvije riječi kao unos i prikazuje popis riječi koje se rimuju s obje, čak uzimajući u obzir asonance, i sve to bez ručnog prebacivanja između četiri kartice i pamćenja riječi "na oko" - sve prikupljeno, uračunato za i automatski se odbacuje. Predivno.

Svrha ove publikacije bila je pokazati da ako čovjeku nešto treba, on će to svakako učiniti. Vrlo neučinkovito, krivo, jezivo, ali će raditi.

Izvor: www.habr.com

Dodajte komentar