De que é capaz o cerebro dun alumno que aprende sobre o mundo da informática?

Bo día.

Ao rematar de escribir outro guión en Bash, decateime de que todo debería ser completamente diferente, pero todo funcionou. Quero amosarche que obscenidades e muletas escribín para resolver o problema, pero aínda sen ter un vagón de coñecemento. Noutras palabras, unha caricatura da programación.

Tarefa


Algo fíxose necesario para:

  • Mostraron moitas rimas para a palabra, excepto para os cadrados
  • Cruzou as moitas rimas de dúas palabras

Para qué? Ben, iso é todo - e iso é todo.
Quen non sabe, unha rima cadrada (na linguaxe común - un cadrado) son dúas palabras cuxas últimas dúas letras da ortografía coinciden, que (moitas veces, isto é o único) as converte nunha rima. Por exemplo, as rosas son xeadas; pneumático - coche. O uso de cadrados na versificación moderna non é especialmente aprobado pola xente, debido á súa primitividade.

decisión


Pareceume que a solución máis sinxela era escribir un guión en Bash que utilizase un xerador de rimas xa existente - HOST, que os selecciona principalmente por consonancia e non pola ortografía. Que tipo de HOST? Porque se indicas o nome real do sitio, dirán que é un anuncio. Por que non seguir usándoo? En primeiro lugar, a pesar da súa vantaxe de seleccionar rimas en función de consonancias, aínda produce cadrados. En segundo lugar, aínda tes que pensar co teu cerebro, gastar tempo cambiando entre pestanas e enerxía memorizando palabras repetidas en listas para atopar unha rima para dúas palabras.

Conseguir rimas fortes

Que sei eu? Sei sobre a utilidade wget, que descarga a páxina no URL especificado. Está ben, executemos a solicitude: obtemos unha páxina HTML nun ficheiro chamado cunha palabra rimada. Por exemplo, busquemos a palabra "aquí":

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

Pero só necesito unha lista de palabras, como me podo librar de todo o demais? Miramos e vemos que a lista de palabras ten formato, por estraño que sexa, en forma de lista, e as palabras están en etiquetas . Ben, temos unha gran utilidade. sed - Escribimos así:

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

En primeiro lugar, desde o ficheiro word, selecciona as liñas que conteñen a etiqueta — obtemos un montón de etiquetas e liñas baleiras con palabras. Eliminamos a propia etiqueta e a de peche; aquí utilízanse símbolos por cento en lugar de barras inclinadas porque na propia etiqueta xa hai unha barra, por que? sed non te entende un pouco. E todo está ben con intereses. Eliminamos todos os espazos do ficheiro, eliminamos liñas baleiras. Voila - unha lista de palabras preparada.

Para eliminar as palabras que riman usando as últimas letras, seleccione as dúas últimas letras da palabra orixinal e borre a lista:

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

Miramos, intentamos - todo funciona... entón, onde está a lista da palabra "xogar"? E pola palabra "vou"? O ficheiro está baleiro! E todo isto porque estas palabras son verbos, e sabemos o que lle fan aos que riman con verbos. A rima verbal é peor que a rima cadrada, porque a lingua rusa é a que máis verbos ten, e todos teñen as mesmas terminacións, polo que non estaban no ficheiro final despois de comprobar as terminacións.

Non obstante, non temos présa. Para cada palabra non só hai rimas, senón tamén asonancias, que ás veces soan moito mellor que a rima; é por iso que son asonancias (asonancia francesa, do latín assono - soo en harmonía).

Temos asonancias

Aquí é onde comeza a diversión: as asonancias aparecen nun URL separado e na mesma páxina, executando un script, enviando unha solicitude HTTP e recibindo unha resposta. Como podo dicir wget'Preme o botón? Pero de ningún xeito. Por desgraza.

Observando que o URL da liña estaba cambiando dalgún xeito, copiei o que había despois de cambiar a asonancias e pegueino nunha nova pestana do navegador: abríronse rimas fortes. Non iso.

Esencialmente, pensei, non debería importarlle ao servidor se o script que lle envía a solicitude se executa ou se a persoa escribe a man. Entón? Quen sabe, imos comprobalo.

Onde enviar? Que enviar? Solicitude HTTP á IP do servidor, hai algo así como GET... despois hai algo HTTP/1.1... Necesitamos ver o que envía o navegador e onde. Instalar wireshark, mira o tráfico:

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Ó.

Um... que? Ah, si, temos HTTPS. Que facer? Lanzar un ataque MITM contra ti mesmo? O ideal é que a propia vítima nos axude.

En xeral, despois de decidir navegar polo navegador, por fin atopei a propia solicitude e o destinatario. Ir:

Diálogo co terminal

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.

Ola. Jejeje. De feito, iso é o que esperaba ao enviar unha solicitude HTTP simple a un porto HTTPS. Debemos cifrar agora? Todo este alboroto con claves RSA, despois con SHA256. Por que hai OpenSSL para tales cousas. Ben, xa sabemos o que facer, primeiro eliminaremos os campos Referer e Cookie; creo que non afectarán moito ao asunto:

Diálogo co terminal

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

De que é capaz o cerebro dun alumno que aprende sobre o mundo da informática?

Que é isto, xurar no servidor? Ben, polo menos me responderon 200 OK, o que significa que as cookies e o referente non afectan a nada. A compresión é gzip, pero ao copiar, cópianse caracteres ASCII. Exactamente, pode eliminar a liña Aceptar-codificación. Todo está ben: obtemos un documento HTML, agora con asonancias. Pero aquí hai dúas preguntas: como executar OpenSSL e transferir datos a el usando un script? E como ler a saída se despois de recibir a resposta seguimos, por así dicir, nun “shell” OpenSSL? Se podes chegar a algo co segundo, pero co primeiro...

É bo que o haxa Habronde lin sobre a utilidade esperar, que automatiza o proceso de interacción con programas que esperan interacción humana. Ter un equipo é aínda máis atractivo espera automática, xerando esperar guión baseado nas túas accións. Pois lanzámolo, fai todo isto e aquí tes o guión rematado. Só el é moi grande, e todo porque OpenSSL mostra certificados, claves e esperar agarda a saída de todo isto. Necesitamos isto? Non. Eliminamos todo o primeiro aviso, deixando só o último salto de liña "r". Tamén eliminamos os campos User-Agent e Acept da nosa solicitude; non afectan a nada. Entón, imos lanzar. O script executouse, pero onde está o documento HTML atesorado? Espere comíao. Para facelo cuspir, cómpre poñer:

set results $expect_out(buffer)

antes do final do script: así se escribirá a saída do executable esperar'om comando e móstrase na pantalla. En resumo, algo así:

espera un guión

#!/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

Pero iso non é todo! Como podes ver, en todos os exemplos o URL da solicitude era estático, pero é o URL o responsable de que palabra se asociará coas asonancias. E así resulta que buscaremos constantemente a palabra "%d0%b7%d0%b4%d0%b5%d1%81%d1%8c" en ASCII ou "aquí" en UTF-8. Que facer? Por suposto, simplemente xera un novo script cada vez, amigos! Non máis espera automática'Oh, e coa axuda perder, porque No noso novo, nada cambia excepto a palabra. E viva o novo problema: como podemos traducir intelixentemente unha palabra do cirílico ao formato URL? Tampouco hai nada especial para o terminal. Ben, está ben, podemos facelo, non? Pode:

Mira o que podo facer!

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')}

En total, temos un script que converte unha palabra en texto ASCII, xerando outro script que solicita unha páxina do sitio con asonancias do servidor a través de OpenSSL. E despois rediriximos a saída do último script a un ficheiro e, á antiga moda, pasámolo "filtros" cadrados extra e escríbeos no ficheiro.

Intersección de moitos. Liña de fondo

En realidade, isto é exactamente o que menos problemas causa. Realizamos os procedementos anteriores para dúas palabras, despois das dúas listas comparamos cada palabra con cada unha e se atopa unha coincidencia, saímosa. Agora temos un script que toma dúas palabras como entrada e amosa unha lista de palabras que riman con ambas, e mesmo tendo en conta as asonancias, e todo isto sen cambiar manualmente entre catro pestanas e lembrar palabras "a ollo" - todo recollido, contabilizado. para e descartado automaticamente. Marabilloso.

O propósito desta publicación era mostrar que se unha persoa necesita algo, farao igualmente. Moi ineficaz, torto, arrepiante, pero funcionará.

Fonte: www.habr.com

Engadir un comentario