MS Remote Desktop Gateway, HAProxy u password brute force

Ħbieb, bonjour!

Hemm ħafna modi kif tikkonnettja mid-dar mal-ispazju tax-xogħol tal-uffiċċju tiegħek. Waħda minnhom hija li tuża Microsoft Remote Desktop Gateway. Dan huwa RDP fuq HTTP. Ma rridx inmiss dwar it-twaqqif ta 'RDGW innifsu hawn, ma rridx niddiskuti għaliex hija tajba jew ħażina, ejja nittrattawha bħala waħda mill-għodod ta' aċċess remot. Irrid nitkellem dwar il-protezzjoni tas-server RDGW tiegħek mill-Internet ħażin. Meta waqqaft is-server RDGW, immedjatament sirt imħasseb dwar is-sigurtà, speċjalment il-protezzjoni kontra l-forza bruta tal-password. Kont sorpriż li ma sibt l-ebda artikli fuq l-Internet dwar kif tagħmel dan. Ukoll, ikollok tagħmel it yourself.

RDGW innifsu m'għandu l-ebda protezzjoni. Iva, jista 'jiġi espost b'interface vojta għal netwerk abjad u se jaħdem tajjeb. Iżda dan jagħmel l-amministratur it-tajjeb jew l-ispeċjalista tas-sigurtà tal-informazzjoni inċerti. Barra minn hekk, jippermettilek tevita s-sitwazzjoni tal-imblukkar tal-kont, meta impjegat traskurat ftakar il-password għal kont korporattiv fuq il-kompjuter tad-dar tiegħu, u mbagħad biddel il-password tiegħu.

Mod tajjeb biex jiġu protetti r-riżorsi interni mill-ambjent estern huwa permezz ta’ diversi prokuri, sistemi ta’ pubblikazzjoni, u WAFs oħra. Ejja niftakru li RDGW għadu http, allura biss jitlob li timla soluzzjoni speċjalizzata bejn is-servers interni u l-Internet.

Naf li hemm jibred F5, A10, Netscaler (ADC). Bħala amministratur ta 'waħda minn dawn is-sistemi, se ngħid li huwa wkoll possibbli li titwaqqaf protezzjoni kontra forza bruta fuq dawn is-sistemi. U iva, dawn is-sistemi jipproteġuk ukoll minn kwalunkwe għargħar syn.

Iżda mhux kull kumpanija tistax taffordja li tixtri soluzzjoni bħal din (u ssib amministratur għal sistema bħal din :), iżda fl-istess ħin jistgħu jieħdu ħsieb is-sigurtà!

Huwa kompletament possibbli li tinstalla verżjoni b'xejn ta 'HAProxy fuq sistema operattiva b'xejn. Ittestjajt fuq Debian 10, verżjoni haproxy 1.8.19 fir-repożitorju stabbli. Ittestjajtu wkoll fuq il-verżjoni 2.0.xx mir-repożitorju tal-ittestjar.

Se nħallu t-twaqqif ta' debian innifsu barra mill-ambitu ta' dan l-artikolu. Fil-qosor: fuq l-interface abjad, agħlaq kollox ħlief il-port 443, fuq l-interface griża - skont il-politika tiegħek, pereżempju, agħlaq ukoll kollox ħlief il-port 22. Iftaħ biss dak li huwa meħtieġ għax-xogħol (VRRP pereżempju, għal ip floating).

L-ewwelnett, ikkonfigurajt haproxy fil-mod SSL bridging (magħruf ukoll bħala mod http) u xgħelt il-logging biex nara x'kien qed jiġri ġewwa RDP. Biex ngħid hekk, ltqajna fin-nofs. Għalhekk, il-mogħdija /RDWeb speċifikata fl-artikoli "kollha" dwar it-twaqqif ta 'RDGateway hija nieqsa. Dak kollu li hemm huwa /rpc/rpcproxy.dll u /remoteDesktopGateway/. F'dan il-każ, ma jintużawx talbiet standard GET/POST; jintuża t-tip ta' talba tagħhom stess RDG_IN_DATA, RDG_OUT_DATA.

Mhux ħafna, imma għallinqas xi ħaġa.

Ejja nittestjaw.

Inniedi mstsc, immur fis-server, nara erba' żbalji 401 (mhux awtorizzati) fir-zkuk, imbagħad daħħal l-isem tal-utent/il-password tiegħi u nara r-rispons 200.

Itfih, nerġa’ nibda, u fir-zkuk nara l-istess erba’ żbalji 401. Ndaħħal login/password ħażin u nerġa’ nara erba’ żbalji 401. Dak hu li għandi bżonn. Dan huwa dak li se naqbdu.

Peress li ma kienx possibbli li tiddetermina l-url tal-login, u barra minn hekk, ma nafx kif naqbad l-iżball 401 f'haproxy, se naqbad (mhux fil-fatt naqbad, iżda ngħodd) l-iżbalji 4xx kollha. Adattat ukoll biex issolvi l-problema.

L-essenza tal-protezzjoni tkun li se ngħoddu n-numru ta 'żbalji 4xx (fuq il-backend) għal kull unità ta' ħin u jekk jaqbeż il-limitu speċifikat, imbagħad niċħdu (fuq il-frontend) il-konnessjonijiet ulterjuri kollha minn din l-ip għaż-żmien speċifikat. .

Teknikament, dan mhux se jkun protezzjoni kontra password brute force, se jkun protezzjoni kontra żbalji 4xx. Pereżempju, jekk spiss titlob url ineżistenti (404), allura l-protezzjoni taħdem ukoll.

L-aktar mod sempliċi u effettiv huwa li toqgħod fuq il-backend u tirrapporta lura jekk tidher xi ħaġa żejda:

frontend fe_rdp_tsc
    bind *:443 ssl crt /etc/haproxy/cert/desktop.example.com.pem
    mode http
    ...
    default_backend be_rdp_tsc


backend be_rdp_tsc
    ...
    mode http
    ...

    #создать таблицу, строковую, 1000 элементов, протухает через 15 сек, записать кол-во ошибок за последние 10 сек
    stick-table type string len 128 size 1k expire 15s store http_err_rate(10s)
    #запомнить ip
    http-request track-sc0 src
    #запретить с http ошибкой 429, если за последние 10 сек больше 4 ошибок
    http-request deny deny_status 429 if { sc_http_err_rate(0) gt 4 }
	
	...
    server rdgw01 192.168.1.33:443 maxconn 1000 weight 10 ssl check cookie rdgw01
    server rdgw02 192.168.2.33:443 maxconn 1000 weight 10 ssl check cookie rdgw02

Mhux l-aħjar għażla, ejja nikkomplikawha. Aħna ser noqogħdu fuq il-backend u l-blokk fuq il-frontend.

Aħna se nittrattaw lill-attakkant b'mod goff u niżżlu l-konnessjoni TCP tiegħu.

frontend fe_rdp_tsc
    bind *:443 ssl crt /etc/haproxy/cert/ertelecom_ru_2020_06_11.pem
    mode http
    ...
    #создать таблицу ip адресов, 1000 элементов, протухнет через 15 сек, сохрянять из глобального счётчика
    stick-table type ip size 1k expire 15s store gpc0
    #взять источник
    tcp-request connection track-sc0 src
    #отклонить tcp соединение, если глобальный счётчик >0
    tcp-request connection reject if { sc0_get_gpc0 gt 0 }
	
    ...
    default_backend be_rdp_tsc


backend be_rdp_tsc
    ...
    mode http
    ...
	
    #создать таблицу ip адресов, 1000 элементов, протухнет через 15 сек, сохранять кол-во ошибок за 10 сек
    stick-table type ip size 1k expire 15s store http_err_rate(10s)
    #много ошибок, если кол-во ошибок за 10 сек превысило 8
    acl errors_too_fast sc1_http_err_rate gt 8
    #пометить атаку в глобальном счётчике (увеличить счётчик)
    acl mark_as_abuser sc0_inc_gpc0(fe_rdp_tsc) gt 0
    #обнулить глобальный счётчик
    acl clear_as_abuser sc0_clr_gpc0(fe_rdp_tsc) ge 0
    #взять источник
    tcp-request content track-sc1 src
    #отклонить, пометить, что атака
    tcp-request content reject if errors_too_fast mark_as_abuser
    #разрешить, сбросить флажок атаки
    tcp-request content accept if !errors_too_fast clear_as_abuser
	
    ...
    server rdgw01 192.168.1.33:443 maxconn 1000 weight 10 ssl check cookie rdgw01
    server rdgw02 192.168.2.33:443 maxconn 1000 weight 10 ssl check cookie rdgw02

l-istess ħaġa, iżda bil-pulit, aħna se nirritornaw l-iżball http 429 (Too Many Requests)

frontend fe_rdp_tsc
    ...
    stick-table type ip size 1k expire 15s store gpc0
    http-request track-sc0 src
    http-request deny deny_status 429 if { sc0_get_gpc0 gt 0 }
    ...
    default_backend be_rdp_tsc

backend be_rdp_tsc
    ...
    stick-table type ip size 1k expire 15s store http_err_rate(10s)
    acl errors_too_fast sc1_http_err_rate gt 8
    acl mark_as_abuser sc0_inc_gpc0(fe_rdp_tsc) gt 0
    acl clear_as_abuser sc0_clr_gpc0(fe_rdp_tsc) ge 0
    http-request track-sc1 src
    http-request allow if !errors_too_fast clear_as_abuser
    http-request deny deny_status 429 if errors_too_fast mark_as_abuser
    ...

Niċċekkja: Inniedi mstsc u nibda ndaħħal il-passwords bl-addoċċ. Wara t-tielet tentattiv, fi żmien 10 sekondi jaqbadni lura, u mstsc jagħti żball. Kif jidher fil-zkuk.

Spjegazzjonijiet. Jien bogħod minn kaptan haproxy. Ma nifhimx għaliex, pereżempju
http-request deny deny_status 429 jekk { sc_http_err_rate(0) gt 4 }
jippermettilek tagħmel madwar 10 żbalji qabel ma taħdem.

Jien konfuż dwar in-numerazzjoni tal-bankijiet. Kaptani tal-haproxy, inkun ferħan jekk tikkumplimentani, tikkoreġini, tagħmilni aħjar.

Fil-kummenti tista 'tissuġġerixxi modi oħra biex tipproteġi RD Gateway, se jkun interessanti li tistudja.

Rigward il-Windows Remote Desktop Client (mstsc), ta 'min jinnota li ma jappoġġjax TLS1.2 (għall-inqas fil-Windows 7), għalhekk kelli nħalli TLS1; ma jappoġġjax ċifra kurrenti, għalhekk kelli wkoll inħalli dawk qodma.

Għal dawk li ma jifhmu xejn, qed jitgħallmu, u diġà jridu jagħmlu tajjeb, nagħtikom il-konfigurazzjoni kollha.

haproxy.conf

global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

        # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
        #ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE
-RSA-AES256-GCM-SHA384
        ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS
        ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
        #ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
        ssl-default-bind-options no-sslv3
        ssl-server-verify none


defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 5000
        timeout client  15m
        timeout server  15m
        errorfile 400 /etc/haproxy/errors/400.http
        errorfile 403 /etc/haproxy/errors/403.http
        errorfile 408 /etc/haproxy/errors/408.http
        errorfile 500 /etc/haproxy/errors/500.http
        errorfile 502 /etc/haproxy/errors/502.http
        errorfile 503 /etc/haproxy/errors/503.http
        errorfile 504 /etc/haproxy/errors/504.http


frontend fe_rdp_tsc
    bind *:443 ssl crt /etc/haproxy/cert/dektop.example.com.pem
    mode http
    capture request header Host len 32
    log global
    option httplog
    timeout client 300s
    maxconn 1000

    stick-table type ip size 1k expire 15s store gpc0
    tcp-request connection track-sc0 src
    tcp-request connection reject if { sc0_get_gpc0 gt 0 }

    acl rdweb_domain hdr(host) -i beg dektop.example.com
    http-request deny deny_status 400 if !rdweb_domain
    default_backend be_rdp_tsc


backend be_rdp_tsc
    balance source
    mode http
    log global

    stick-table type ip size 1k expire 15s store http_err_rate(10s)
    acl errors_too_fast sc1_http_err_rate gt 8
    acl mark_as_abuser sc0_inc_gpc0(fe_rdp_tsc) gt 0
    acl clear_as_abuser sc0_clr_gpc0(fe_rdp_tsc) ge 0
    tcp-request content track-sc1 src
    tcp-request content reject if errors_too_fast mark_as_abuser
    tcp-request content accept if !errors_too_fast clear_as_abuser

    option forwardfor
    http-request add-header X-CLIENT-IP %[src]

    option httpchk GET /
    cookie RDPWEB insert nocache
    default-server inter 3s    rise 2  fall 3
    server rdgw01 192.168.1.33:443 maxconn 1000 weight 10 ssl check cookie rdgw01
    server rdgw02 192.168.2.33:443 maxconn 1000 weight 10 ssl check cookie rdgw02


frontend fe_stats
    mode http
    bind *:8080
    acl ip_allow_admin src 192.168.66.66
    stats enable
    stats uri /stats
    stats refresh 30s
    #stats admin if LOCALHOST
    stats admin if ip_allow_admin

Għaliex żewġ servers fuq il-backend? Minħabba li dan huwa kif tista 'tagħmel tolleranza għall-ħsarat. Haproxy jista 'wkoll jagħmel tnejn b'ip abjad f'wiċċ l-ilma.

Riżorsi tal-kompjuter: tista 'tibda b'"żewġ gig, żewġ cores, PC tal-logħob." Skond Wikipedija dan se jkun biżżejjed biex spare.

Referenzi:

Twaqqif ta' rdp-gateway minn HAProxy
L-uniku artiklu li sibt fejn iddejjaq li jġorr il-password

Sors: www.habr.com

Żid kumment