Django Admin — Honey Pot

Berkay Şen
4 min readApr 20, 2022

Djangoda admin Honey Pot nedir demeden önce genel olarak Honey Pot nedir bundan bahsedelim. En basitten alacak olursak yetkisi olmayan bir kullanıcının sitemiz / sunucumuz üzerinde bir işlem yapmaya çalışırken onu sahte bir sunucuya / web sayfasına yönlendirerek, yetkisiz kullanıcının ya da saldırgan olarak nitelendirdiğimiz bu kullanıcının public IP gibi bilgilerini alarak hem web uygulamamızı korumuş oluruz, hem de saldırı yapan insanların yönünü şaşırtmış oluruz.

Örnek olarak Django Framework’ünün default yani varsayılan admin panelinin path’i yani url yolu “admin/” dir. Bunu bilen ya da tahmin eden herkes gerçek admin panelimize giriş işlemleri deneyebilir , burada bruteforce vb gibi saldırıları kullanarak izinsiz bir şekilde admin panelimize girmeye çalışabilir. Bunun önüne geçmek için çok da güzel bir yöntem var. Hadi gelin bunu anlatalım.

İlk başta basit bir django projesi oluşturalım. Oluşturmadan önce tabiiki de sanal ortamımızı oluşturup aktifleştirelim.

python3 -m venv env

Sanal ortamı oluşturduk şimdi aktif edelim.

source env/bin/activate

Django projemizi oluşturalım.

django-admin startproject core

Djangoyu oluşturmuş olduğumuz sanal ortamın içerisine kuralım.

pip3 install django

Admin panelimiz için gerekli migrate işlemlerini de yapalım.

python3 manage.py migrate

Migrate işlemleri tamam şimdi admin panelimize girebilmek için bir superuser oluşturalım.

python3 manage.py createsuperuser

Şimdi django projemizi runserver ile çalıştırıp admin panelimizi açalım.

Şimdi gelelim Honey-pot kısmı için yapmamız gerekenlere. İLk önce sanal ortamımız için bir paket yükleyeceğiz.

pip3 install django-admin-honeypot

Uygulamamızı settings.py dosyamızda INSTALLED_APPS listesine ekleyelim.

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'admin_honeypot', # Yeni
]

Şimdi ana klasörümüzün içerisindeki ana urls.py dosyamıza gelip kendi gerçek admin panelinin path’ini değiştirelim ki yaptığımız işin bir anlamı olsun.

urlpatterns = [
path('secretadminpath/', admin.site.urls),
]

Şimdilik böyle yaptım ,siz nasıl isterseniz admin yolunu ayarlayabilirsiniz.Şimdi ise sahte olan admin/ path’i için şu kod satırını urlpatterns listesine ekleyeceğiz.

urlpatterns = [
path('secretadminpath/', admin.site.urls),
path("admin/",include("admin_honeypot.urls")) #Yeni
]

admin/ dizinine bir istek geldiği anda yüklemiş olduğumuz paketteki url adreslerine gidip bizim istediğimiz işlemleri yapacaktır. Son olarak da tekrardan migrate işlemini yapmamız gerekiyor. Çünkü sahte admin paneline giriş işlemi deneyen kullanıcıların bilgilerini veritabanında tutmamız gerek.

python3 manage.py migrate

Peki ya bu yüklemiş modül arka tarafta ne yapıyor ,gelin biraz bundan bahsedelim.

Burada ne olduğunu anlamak zorunda değilsiniz. Atlayabilirsiniz,sadece arka taraftaki mantığını anlatıyorum.

class AdminHoneypot(generic.FormView):
template_name = 'admin_honeypot/login.html'
form_class = HoneypotLoginForm
def dispatch(self, request, *args, **kwargs):
if not request.path.endswith('/'):
return redirect(request.path + '/', permanent=True)
login_url = reverse('admin_honeypot:login')
if request.path != login_url:
return redirect_to_login(request.get_full_path(), login_url)
return super(AdminHoneypot, self).dispatch(request, *args, **kwargs)
def get_form(self, form_class=form_class):
return form_class(self.request, **self.get_form_kwargs())
def get_context_data(self, **kwargs):
context = super(AdminHoneypot, self).get_context_data(**kwargs)
path = self.request.get_full_path()
context.update({
'app_path': path,
REDIRECT_FIELD_NAME: reverse('admin_honeypot:index'),
'title': _('Log in'),})
return context
def form_valid(self, form):
return self.form_invalid(form)
def form_invalid(self, form):
instance = LoginAttempt.objects.create(
username=self.request.POST.get('username'),
session_key=self.request.session.session_key,
ip_address=self.request.META.get('REMOTE_ADDR'),
user_agent=self.request.META.get('HTTP_USER_AGENT'),
path=self.request.get_full_path(),
)
honeypot.send(sender=LoginAttempt, instance=instance, request=self.request)
return super(AdminHoneypot, self).form_invalid(form)

Burası size çok karışık gelmiş olabilir ancak dikkat etmenizi istediğim tek bir nokta var. Gördüğünüz gibi bu sınıf her zaman kullanmış olduğumuz bir FormView’den miras alınmış. Yani klasik form_valid() ve form_invalid() methodlarımız var. Burada form_valid() olduğunda fark ederseniz form_invalid() methodu çağrılıyor. Yani kullanıcı ne kadar doğru giriş işlemi yapıyor olsa dahi form_valid() methodu form_invalid() methodunu çağırdığı için kullanıcı bu sahte admin paneline giriş yapamayacaktır.

Şimdi tarayıcımızı açıp http://127.0.0.1:8000/admin dizinine gitmeye çalışalım.

Gördüğünüz gibi birebir admin panelimiz geldi. Aslında bu gerçek admin paneli değil tamamen sahte ve saldırganları kandırmaya ve yakalamaya yönelik bir admin paneli. Şimdi gelelim birkaç giriş işlemi yapmaya.

Kullanıcı adı ve şifremi doğru yazmama rağmen bana hata verdi gördüğünüz gibi. Şimdi ise gerçek admin panelimize girip bu kayıda göz gezdirelim.

ADMIN_HONEYPOT başlığı altında login attempts dizinine bakalım.

Bir kaydımız var ve bu kaydın detaylarına giriş yaptığımızda ise

IP adresimizden tarayıcı bilgilerimize kadar bilgileri tuttuğunu görüyoruz. IP adresimiz şuan localhostta olduğumuzdan dolayı 127.0.0.1 olarak gözüküyor. Ancak web uygulamanızı dışarıya açtığınız zaman burada kullanıcının public IP adresi gözükecektir.

--

--