Blokkere wp-admin-mappen med htaccess

quicktech

Medlem
Husk at sikkerhet handler om mye mer enn bare login formen til wp-admin, så hvis du føler deg litt på tynn is i forhold til htaccess, så er det like greit å installere en firewall plugin, som feks denne WordPress › Wordfence Security « WordPress Plugins

Den tar da hånd om påloggings-begrensing for deg, samt en drøss med andre nyttige ting. Så kan du sove godt om natta. Anbefaler også å rename wp-admin noe som ikke er standard for å forvirre botene som er konfigurert til å lete etter wp-admin.

Angående ip begrensning: forsiden leser innholdet fra wp-content mappen + databasen. Det er derfor ikke noe problem om du sperrer av tilgang til wp-admin basert på IP.
 

adeneo

Medlem
Man kan vel ikke bare gi wp-admin mappen et nytt navn ?

Hele Wordpress core systemet er bygget med faste mappenavn, slik at endrer man på navnene, så må man vel også endre alle henvisninger som ligger hardkodet i wordpress til admin mappen.
Man kan selvfølgelig bruke redirects i .htaccess, men da forsvinner lissom litt av poenget ettersom man da uansett har tilgang på vanlig måte.

Videre så bruker følgende wp-admin internt :
  • HTTP API'en (ajax, rest, soap, services osv)
  • /wp-admin/admin-ajax.php (som gjør alle interne ajax greier)
  • media-uploader'en
  • i enkelte tilfeller user-roles
slik at de tingene ovenfor og sikkert en rekke andre ting, og da også alle plugins eller widgets som bruker de tingene, vil slutte å virke for de brukerne som ikke har tilgang på wp-admin fordi de er sperret ute med .htaccess.

I utgangspunktet er det wp_login.php som bør beskyttes, ettersom man automatisk blir videresendt dit dersom man forsøker admin.php uten å være logget inn.

En veldig enkel måte å beskytte wp_login.php på dersom man ikke trenger brukerinnlogging og kun er avhengig av å logge inn selv som admin, er bare å legge til noe surr i querystringen, slik som :

PHP:
add_action('init', 'login_test');

function login_test() {
    global $pagenow;
    if(!is_user_logged_in() && $pagenow == 'wp-login.php') {
        if ( ! (isset($_GET['determeg']) && $_GET['determeg'] == 'jepp' )) {
            wp_redirect( home_url() . '/', 302 );
            exit;
        }
    }
}

Altså, hvis ikke vi er logget inn, og siden vi er på er wp_login.php, sjekk querystringen for noe egendefinert surr!
Dersom man nå forsøker å gå til :

Kode:
/wordpress/wp-login.php

så blir man bare sendt tilbake til startsiden, og man er nødt til å bruke

Kode:
/wordpress/wp-login.php?determeg=jepp

for å i det hele tatt få tilgang til login siden, og jeg skulle like å se den bot'en som gjetter den url'en, slik at det sikrer mot de fleste angrep mot login siden uten å sperre tilgangen for wordpress sine egne funksjoner ?

Wordpress har også en egen side for tiltak man kan gjøre for å bedre sikkerheten
 

adeneo

Medlem
Den løsningen ovenfor er nok ikke like sikker som å sperre IP adresser direkte i Apache, og jeg må innrømme at det var noe jeg fant på akkurat nå, og jeg har aldri sett noe lignende på nettet heller ?

Jeg har såvidt testet at det virker, og det gjør det, og det gir et ekstra lag med sikkerhet samtidig som det gjør det mulig å logge inn fra hvor som helst dersom man vet hva querystringen må være for å få tilgang til wp-login.php.

Jeg testet også kjapt med en melding, slik som :

PHP:
function login_test() { 
    global $pagenow; 
    if(!is_user_logged_in() && $pagenow == 'wp-login.php') { 
        if ( ! (isset($_GET['determeg']) && $_GET['determeg'] == 'jepp' )) { 
            echo "Get lost !";
            exit; 
        } 
    } 
}

og prøvde å kjøre en random passord generator mot wp_login.php med cURL, noe som nå ikke funker i det hele tatt, ettersom det ikke er noe login skjema å teste mot, det eneste som kommer er teksten "Get lost !".

Skal man komme forbi den sikkerheten må man først vite at det er querystringen som styrer dette, så finne ut akkurat hva den rette querystringen er, og det finnes ikke noen ferdige script (enda) som gjør slikt, så man burde være betydelig bedre sikret mot script-kiddies og den slags ved å bruke en egendefinert querystring for å i det hele tatt vise innloggingsboksen.

Har ikke testet noe mer utover dette, så det kan være bakdeler jeg ikke har tenkt på ?
 

quicktech

Medlem
Dette er den samme teknikken som å legge inn felt markert med "Vennligst skriv svaret på 5+2" eller "Hva er hovedstaden i Norge?" i kontaktskjema og liknene. Du kvitter deg umiddelbart med 99% av alle automatiserte angrep.

Det er vel og bra, hvis automatiserte og ikke-målrettede angrep er det du er mest bekymret for. Men det er klart ikke like effektivt hvis et menneske bestemmer seg for å prøve å bryte seg inn.

Derfor bør du alltid ha flere lag med sikkerhet, gjerne kombinere alt du har sett i denne tråden så langt og på den måten sikre løsningen din i alle bauger og kanter. Det er ganske enkelt og krever minimalt med tid - så hvorfor ikke gjøre det skikkelig :)
 

adeneo

Medlem
Dette er den samme teknikken som å legge inn felt markert med "Vennligst skriv svaret på 5+2" eller "Hva er hovedstaden i Norge?" i kontaktskjema og liknene. Du kvitter deg umiddelbart med 99% av alle automatiserte angrep.

Og siden det er lørdag, så kan jeg legge til et tips til!

For å forstå hvor enkelt det egentlig er, så blir det litt komplisert forklaring.
Hvis vi har et kontaktskjema som sender e-poster til eieren av siden, så ser de ofte slik ut:

PHP:
<form>
    <input name="firstname" placeholder="Fornavn" />
    <input name="lastname" placeholder="Etternavn" />
    <input type="submit" value="send skjema">
</form>

Det første en robot gjør, er å se på HTML'en, og først på <form> elementet.
Som standard så sendes skjemaet til den siden det er på, og det benyttes en GET request.
Dersom form elementet ser litt annerledes ut:

Kode:
<form action="send_meg_mail.php" method="POST">

så vet roboten at skal det sendes en POST request til "send_meg_mail.php".

Det neste en robot gjør er å se på elementene, og ettersom det er en viss standard for navn på slike felter for at de skal virke med autocomplete osv. så er det enkelt å finne ut hva som skal sendes.
Tar man da utgangspunkt i en GET request, så trenger bare roboten å besøke :

Kode:
send_meg_mail.php?firstname=Bill&lastname=Gates

For å sende den ulykkelige eieren slitsomme beskjeder fra Bill Gates.

Poenget ved å legge inn et ekstra felt som spør om ting som "Hva var fargen på Napoleons hvite hest" er at det er innlysende for et menneske at hesten var hvit, mens for en robot er det vanskelig å gjette slik ting. Samtidig er det litt irriterende å stadig fylle ut slikt tull når man skal sende noen en beskjed.

Hvis man da legger til et felt i skjemaet som ikke er synlig:

PHP:
<form>
    <input name="firstname" placeholder="Fornavn" />
    <input name="lastname" placeholder="Etternavn" />
    <input name="adress" style="display:none" autocomplete="off" /> // skjult felt
    <input type="submit" value="send skjema">
</form>

så vil roboten se "adress" feltet og automatisk forsøke å sende en adresse, slik :

Kode:
send_meg_mail.php?firsname=Bill&lastname=Gates&adress=One%20Microsoft%20Way

Ettersom en virkelig bruker aldri ville sett det feltet i nettleseren sin, og derfor heller aldri fylt det ut, kan vi bare sjekke før e-post sendes at adressefeltet ikke har noen verdi, det ville være pussig hvis noen som besøkte skjemaet vårt klarte å fylle ut et felt de ikke ser, og vips så har man luket bort 95% av roboter uten at virkelige brukere noen gang ser noe som helst eller trenger å svare på noe, ettersom det er litt "omvendt spam sjekking".

En smart robot vil selvfølgelig sjekke om feltet er synlig, men dersom feltet gjemmes med en ekstern css fil, så blir det plutselig betydelig vanskeligere ettersom roboten da også må sjekke alle stilark osv.

Jeg har brukt en litt mer avansert versjon av dette i flere år, og det fungerer utmerket, uten at brukeren må svare på dustete spørsmål for å sende et skjema.
 
Sist redigert:
Topp