ΠΠΎΠ΄ Π½Π°Π·Π°Π΄, 21 ΠΌΠ°ΡΡΠ° 2019, Π²
ΠΡΠΎ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠ°Ρ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΡ, Ρ.ΠΊ. Π·Π°ΠΏΡΠΎΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠ°Ρ Π² ΡΠΎΠΌ ΡΠΈΡΠ»Π΅ ΡΠ΅ΡΡΠΈΠΎΠ½Π½ΡΠ΅ ΠΊΡΠΊΠΈ. Π§Π΅ΡΠ΅Π· Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°ΡΠΎΠ² Π±ΡΠ» ΡΠ΄Π΅Π»Π°Π½ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΉ ΡΠΈΠΊΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΈΠ»ΡΡΡΠΎΠ²Π°Π» Π½ΡΠ»Π΅Π²ΠΎΠΉ Π±Π°ΠΉΡ (ΠΊΠ°ΠΊ ΠΏΠΎΡΠΎΠΌ Π²ΡΡΡΠ½ΠΈΠ»ΠΎΡΡ, ΡΡΠΎΠ³ΠΎ Π±ΡΠ»ΠΎ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ, Ρ.ΠΊ. ΠΎΡΡΠ°Π²Π°Π»Π°ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΠ½ΡΠ΅ΠΊΡΠΈΠΈ CRLF /ASCII 13, 10, ΡΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΌΠ°Π½ΠΈΠΏΡΠ»ΠΈΡΠΎΠ²Π°ΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°ΠΌΠΈ ΠΈ Π΄Π°Π½Π½ΡΠΌΠΈ HTTP-ΠΎΡΠ²Π΅ΡΠ°, ΡΡΠΎ ΠΌΠ΅Π½Π΅Π΅ ΠΊΡΠΈΡΠΈΡΠ½ΠΎ, Π½ΠΎ Π²ΡΠ΅ ΡΠ°Π²Π½ΠΎ Π½Π΅ΠΏΡΠΈΡΡΠ½ΠΎ). ΠΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ Ρ ΡΡΠΈΠΌ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Π±ΡΠ»Π° ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π° Π°Π½Π°Π»ΠΈΡΠΈΠΊΠ°ΠΌ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ ΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°ΠΌ Π΄Π»Ρ ΠΏΠΎΠΈΡΠΊΠ° ΠΈ ΡΡΡΡΠ°Π½Π΅Π½ΠΈΡ ΠΏΡΠΈΡΠΈΠ½ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΡ Π±Π°Π³Π°.
ΠΠΎΡΡΠ° Mail.ru β ΡΡΠΎ ΠΎΡΠ΅Π½Ρ Π½Π΅ΠΏΡΠΎΡΡΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π² ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ ΠΎΡΠ²Π΅ΡΠ° ΠΌΠΎΠΆΠ΅Ρ ΡΡΠ°ΡΡΠ²ΠΎΠ²Π°ΡΡ Π±ΠΎΠ»ΡΡΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ
ΡΡΠΎΠ½ΡΠ΅Π½Π΄/Π±Π΅ΠΊΠ΅Π½Π΄-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ², ΠΊΠ°ΠΊ ΠΎΠΏΠ΅Π½ΡΠΎΡΡΠ½ΡΡ
(Π±ΠΎΠ»ΡΡΠΎΠ΅ ΡΠΏΠ°ΡΠΈΠ±ΠΎ Π²ΡΠ΅ΠΌ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°ΠΌ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΠ), ΡΠ°ΠΊ ΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎΠΉ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ. Π£Π΄Π°Π»ΠΎΡΡ ΠΈΡΠΊΠ»ΡΡΠΈΡΡ Π²ΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΠΊΡΠΎΠΌΠ΅ nginx ΠΈ openresty ΠΈ Π»ΠΎΠΊΠ°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π΄ΠΎ Π²ΡΠ·ΠΎΠ²Π°
OpenResty β ΡΡΠΎ Π²Π΅ΡΡΠΌΠ° ΠΏΠΎΠΏΡΠ»ΡΡΠ½ΡΠΉ ΠΏΠ»Π°Π³ΠΈΠ½, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡΠΈΠΉ ΠΏΠΈΡΠ°ΡΡ Lua-ΡΠΊΡΠΈΠΏΡΡ Π²Π½ΡΡΡΠΈ nginx, ΠΈ ΠΎΠ½ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π² Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ
ΠΏΡΠΎΠ΅ΠΊΡΠ°Ρ
Mail.ru, ΠΏΠΎΡΡΠΎΠΌΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ° Π½Π΅ ΡΡΠΈΡΠ°Π»Π°ΡΡ ΡΠ΅ΡΠ΅Π½Π½ΠΎΠΉ. Π ΡΠΏΡΡΡΡ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ΅ Π²ΡΠ΅ΠΌΡ ΠΊ Π½Π΅ΠΉ Π²ΡΠ΅-ΡΠ°ΠΊΠΈ Π²Π΅ΡΠ½ΡΠ»ΠΈΡΡ, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ½ΠΈΠΌΠ°ΡΡ ΠΈΡΡΠΈΠ½Π½ΡΠ΅ ΠΏΡΠΈΡΠΈΠ½Ρ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠ΅ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΠ²ΠΈΡ ΠΈ ΡΠΎΡΡΠ°Π²ΠΈΡΡ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°ΡΠΈΠΈ Π΄Π»Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ². Π ΡΠ°ΡΠΊΠΎΠΏΠΊΠ°Ρ
ΠΈΡΡ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° ΡΡΠ°ΡΡΠ²ΠΎΠ²Π°Π»ΠΈ
- Π nginx ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ rewrite Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΌΠΈ Π΄Π°Π½Π½ΡΠΌΠΈ Π΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ directory traversal (ΠΈ Π²Π΅ΡΠΎΡΡΠ½ΠΎ SSRF) Π² Π½Π΅ΠΊΠΎΡΠΎΡΡΡ
ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡ
, Π½ΠΎ ΡΡΠΎ ΠΈΠ·Π²Π΅ΡΡΠ½ΡΠΉ ΡΠ°ΠΊΡ, ΠΈ ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΠ²Π°ΡΡΡΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΌΠΈ Π°Π½Π°Π»ΠΈΠ·Π°ΡΠΎΡΠ°ΠΌΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΉ Π²
Nginx Amplify ΠΈGixy ΠΎΡ Π―Π½Π΄Π΅ΠΊΡ (Π΄Π°, ΠΌΡ Π΅Π³ΠΎ ΡΠΎΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ, ΡΠΏΠ°ΡΠΈΠ±ΠΎ). ΠΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ OpenResty ΡΠ°ΠΊΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ Π»Π΅Π³ΠΊΠΎ ΠΏΡΠΎΠΏΡΡΡΠΈΡΡ, Π½ΠΎ Π½Π°ΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ ΡΡΠΎ Π½Π΅ Π·Π°ΡΡΠ°Π³ΠΈΠ²Π°Π»ΠΎ.ΠΏΡΠΈΠΌΠ΅Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ:
location ~ /rewrite { rewrite ^.*$ $arg_x; } location / { root html; index index.html index.htm; }
ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ
curl localhost:8337/rewrite?x=/../../../../../../../etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
... - Π nginx Π΅ΡΡΡ ΠΎΡΠΈΠ±ΠΊΠ°, ΠΏΡΠΈΠ²ΠΎΠ΄ΡΡΠ°Ρ ΠΊ ΡΡΠ΅ΡΠΊΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ³ΠΎ ΠΏΠ°ΠΌΡΡΠΈ, Π΅ΡΠ»ΠΈ ΡΡΡΠΎΠΊΠ° rewrite ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½ΡΠ»Π΅Π²ΠΎΠΉ Π±Π°ΠΉΡ. ΠΡΠΈ ΠΎΡΠ΄Π°ΡΠ΅ ΡΠ΅Π΄ΠΈΡΠ΅ΠΊΡΠ° nginx Π²ΡΠ΄Π΅Π»ΡΠ΅Ρ Π½ΠΎΠ²ΡΠΉ Π±ΡΡΠ΅Ρ ΠΏΠ°ΠΌΡΡΠΈ, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ ΠΏΠΎΠ»Π½ΠΎΠΉ Π΄Π»ΠΈΠ½Π΅ ΡΡΡΠΎΠΊΠ΅, Π½ΠΎ ΠΊΠΎΠΏΠΈΡΡΠ΅Ρ ΡΡΠ΄Π° ΡΡΡΠΎΠΊΡ ΡΠ΅ΡΠ΅Π· ΡΡΡΠΎΡΠ½ΡΡ ΡΡΠ½ΠΊΡΠΈΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ Π½ΡΠ»Π΅Π²ΠΎΠΉ Π±Π°ΠΉΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ΅ΡΠΌΠΈΠ½Π°ΡΠΎΡΠΎΠΌ ΡΡΡΠΎΠΊΠΈ, ΠΏΠΎΡΡΠΎΠΌΡ ΡΡΡΠΎΠΊΠ° ΠΊΠΎΠΏΠΈΡΡΠ΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π΄ΠΎ Π½ΡΠ»Π΅Π²ΠΎΠ³ΠΎ Π±Π°ΠΉΡΠ°, ΠΎΡΡΠ°ΡΠΎΠΊ Π±ΡΡΠ΅ΡΠ° ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½Π΅ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅. ΠΠΎΠ΄ΡΠΎΠ±Π½ΡΠΉ ΡΠ°Π·Π±ΠΎΡ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡΠΈ
Π·Π΄Π΅ΡΡ .ΠΏΡΠΈΠΌΠ΅Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ (^@ Π½ΡΠ»Π΅Π²ΠΎΠΉ Π±Π°ΠΉΡ)
location ~ /memleak { rewrite ^.*$ "^@asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdasdf"; } location / { root html; index index.html index.htm; }
ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ
curl localhost:8337/secret -vv
...
curl localhost:8337/memleak -vv
...
Location: http://localhost:8337/secret
...
- Nginx Π·Π°ΡΠΈΡΠ°Π΅Ρ GET-ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΎΡ ΠΈΠ½ΡΠ΅ΠΊΡΠΈΠΈ ΡΠ»ΡΠΆΠ΅Π±Π½ΡΡ
ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ² ΠΈ Π΄Π°Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² rewrite ΡΠΎΠ»ΡΠΊΠΎ GET-ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ. ΠΠΎΡΡΠΎΠΌΡ ΡΠΊΡΠΏΠ»ΡΠ°ΡΠΈΡΠΎΠ²Π°ΡΡ ΠΈΠ½ΡΠ΅ΠΊΡΠΈΡ ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΡΠ΅ΠΌΡΠ΅ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π² nginx Π½Π΅ ΠΏΠΎΠ»ΡΡΠ°Π΅ΡΡΡ. POST ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΏΡΠΈ ΡΡΠΎΠΌ Π½Π΅ Π·Π°ΡΠΈΡΠ΅Π½Ρ. OpenResty ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΈ Ρ GET ΠΈ Ρ POST ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ POST ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠ² ΡΠ΅ΡΠ΅Π· OpenResty ΠΏΠΎΡΠ²Π»ΡΠ΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΠ½ΡΠ΅ΠΊΡΠΈΠΈ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΡ
ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ².
ΠΏΡΠΈΠΌΠ΅Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ:
location ~ /memleak { rewrite_by_lua_block { ngx.req.read_body(); local args, err = ngx.req.get_post_args(); ngx.req.set_uri( args["url"], true ); } } location / { root html; index index.html index.htm; }
ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ:
curl localhost:8337 -d "url=secret" -vv
...
curl localhost:8337 -d "url=%00asdfasdfasdfasdfasdfasdfasdfasdf" -vv
...
Location: http://localhost:8337/{...ΠΌΠΎΠΆΠ΅Ρ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ secret...}
...
ΠΠ°Π»ΡΠ½Π΅ΠΉΡΠ°Ρ ΡΠ΅Π°ΠΊΡΠΈΡ
Π ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ΅ ΡΠΎΠΎΠ±ΡΠΈΠ»ΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°ΠΌ nginx ΠΈ OpenResty, ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ Π½Π΅ ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΠΊΠ°ΠΊ ΠΎΡΠΈΠ±ΠΊΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ Π² nginx, Ρ.ΠΊ. Π² ΡΠ°ΠΌΠΎΠΌ nginx Π½Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ ΡΠΊΡΠΏΠ»ΡΠ°ΡΠ°ΡΠΈΠΈ ΠΎΡΠΈΠ±ΠΊΠΈ ΡΠ΅ΡΠ΅Π· ΠΈΠ½ΡΠ΅ΠΊΡΠΈΡ ΡΠΏΠ΅ΡΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ², ΡΠΈΠΊΡ
Portswigger
Π’Π°ΠΊ Π² ΡΠ΅ΠΌ ΠΆΠ΅ Π±ΡΠ»Π° ΠΎΡΠΈΠ±ΠΊΠ° ΠΈ ΡΡΠΎ Π΄Π΅Π»Π°ΡΡ, ΡΡΠΎΠ±Ρ Π΅Π΅ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠΈΡΡ?
ΠΡΠ»Π° Π»ΠΈ ΠΎΡΠΈΠ±ΠΊΠ° Π² nginx? ΠΠ°, Π±ΡΠ»Π°, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ ΡΡΠ΅ΡΠΊΠ° ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ³ΠΎ ΠΏΠ°ΠΌΡΡΠΈ ΡΡΠΎ Π² Π»ΡΠ±ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΎΡΠΈΠ±ΠΊΠ°.
ΠΡΠ»ΠΈ Π»ΠΈ ΠΎΡΠΈΠ±ΠΊΠ° Π² OpenResty? ΠΠ°, ΠΊΠ°ΠΊ ΠΌΠΈΠ½ΠΈΠΌΡΠΌ Π½Π΅ Π±ΡΠ» ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°Π½ ΠΈ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½ Π²ΠΎΠΏΡΠΎΡ ΠΎ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ ΠΏΡΠ΅Π΄Π»Π°Π³Π°Π΅ΠΌΠΎΠΉ OpenResty ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΠΈ.
ΠΡΠ»Π° Π»ΠΈ Π΄ΠΎΠΏΡΡΠ΅Π½Π° ΠΎΡΠΈΠ±ΠΊΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ / ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ OpenResty? ΠΠ°, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Π² ΠΎΡΡΡΡΡΡΠ²ΠΈΠΈ ΡΠ²Π½ΠΎΠ³ΠΎ ΡΠΊΠ°Π·Π°Π½ΠΈΡ, Π±ΡΠ»ΠΎ ΡΠ΄Π΅Π»Π°Π½ΠΎ Π½Π΅ΠΏΡΠΎΠ²Π΅ΡΠ΅Π½Π½ΠΎΠ΅ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΎ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΠΈ.
ΠΠ°ΠΊΠ°Ρ ΠΈΠ· ΡΡΠΈΡ ΠΎΡΠΈΠ±ΠΎΠΊ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΡΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ Ρ Π±Π°ΡΠ½ΡΠΈ Π½Π° $10000? ΠΠ»Ρ Π½Π°Ρ ΡΡΠΎ Π² ΠΎΠ±ΡΠ΅ΠΌ-ΡΠΎ Π½Π΅ Π²Π°ΠΆΠ½ΠΎ. Π Π»ΡΠ±ΠΎΠΌ ΠΠ, ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ Π½Π° ΡΡΡΠΊΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ, ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅ΠΌΡΡ ΡΠ°Π·Π½ΡΠΌΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠ°ΠΌΠΈ ΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°ΠΌΠΈ Π½ΠΈΠΊΡΠΎ ΠΈ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ Π³Π°ΡΠ°Π½ΡΠΈΡΠΎΠ²Π°ΡΡ, ΡΡΠΎ Π²ΡΠ΅ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΠΈ ΠΈΡ ΡΠ°Π±ΠΎΡΡ ΠΈΠ·Π²Π΅ΡΡΠ½Ρ ΠΈ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Ρ ΠΈ ΠΎΡΡΡΡΡΡΠ²ΡΡΡ ΠΎΡΠΈΠ±ΠΊΠΈ. ΠΠΎΡΡΠΎΠΌΡ Π»ΡΠ±Π°Ρ ΡΡΠ·Π²ΠΈΠΌΠΎΡΡΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ ΠΈΠΌΠ΅Π½Π½ΠΎ ΡΠ°ΠΌ, Π³Π΄Π΅ ΠΎΠ½Π° Π²Π»ΠΈΡΠ΅Ρ Π½Π° Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΡ.
Π Π»ΡΠ±ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅, Ρ ΠΎΡΠΎΡΠ΅ΠΉ ΠΏΡΠ°ΠΊΡΠΈΠΊΠΎΠΉ Π±ΡΠ΄Π΅Ρ Π½ΠΎΡΠΌΠ°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΈΠ»ΠΈ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎ ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΠ²Π°ΡΡ/ΡΠΈΠ»ΡΡΡΠΎΠ²Π°ΡΡ Π²Ρ ΠΎΠ΄Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΡ ΠΎΠ΄ΡΡ Π² Π»ΡΠ±ΠΎΠΉ Π²Π½Π΅ΡΠ½ΠΈΠΉ ΠΌΠΎΠ΄ΡΠ»Ρ/API, Π΅ΡΠ»ΠΈ Π½Π΅Ρ ΡΠ²Π½ΡΡ ΡΠΊΠ°Π·Π°Π½ΠΈΠΉ ΠΈ ΠΎΠ΄Π½ΠΎΠ·Π½Π°ΡΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΡ, ΡΡΠΎ ΡΡΠΎΠ³ΠΎ Π½Π΅ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ.
Errata
ΠΠΎ ΠΎΠΏΡΡΡ
Π±Π°Π³ Π±Π°ΡΠ½ΡΠΈ β ΠΊΠΎΠ½ΠΊΡΡΡ ΠΎΡ
ΠΎΡΡ Π·Π° ΠΎΡΠΈΠ±ΠΊΠ°ΠΌΠΈ
Π±Π°Π³ΡΠ΅ΠΏΠΎΡΡ β ΡΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ΅
ΡΠ΅Π΄ΠΈΡΠ΅ΠΊΡ β ΠΏΠ΅ΡΠ΅Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅
ΠΎΠΏΠ΅Π½ΡΠΎΡΡΠ½ΡΠΉ β Ρ ΠΎΡΠΊΡΡΡΡΠΌ ΠΊΠΎΠ΄ΠΎΠΌ
errata β ΡΠ°Π±ΠΎΡΠ° Π½Π°Π΄ ΠΎΡΠΈΠ±ΠΊΠ°ΠΌΠΈ
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com