{"id":2203,"date":"2024-01-10T15:48:28","date_gmt":"2024-01-10T15:48:28","guid":{"rendered":"https:\/\/berenkudaygorun.com\/blog\/?p=2203"},"modified":"2024-01-10T15:49:55","modified_gmt":"2024-01-10T15:49:55","slug":"aws-waf-temel-kurulum","status":"publish","type":"post","link":"https:\/\/berenkudaygorun.com\/blog\/blog\/2024\/01\/10\/aws-waf-temel-kurulum\/","title":{"rendered":"AWS WAF Temel Kurulum"},"content":{"rendered":"<blockquote>\n<p>Halbuki o (Kur\u2019an), ancak \u00e2lemler i\u00e7in (ger\u00e7e\u011fi) hat\u0131rla(t)mad\u0131r.<br \/>\nKalem 52<\/p>\n<\/blockquote>\n<h1>Giri\u015f<\/h1>\n<p>Projelerde bir\u00e7ok alanda WAF ihtiyac\u0131 do\u011fal bir ihtiya\u00e7t\u0131r. \u00d6rnek vermek gerekirse bir mobil uygulama geli\u015ftirdi\u011finizde login ekran\u0131n\u0131z\u0131 bruteforce sald\u0131r\u0131lar\u0131na kar\u015f\u0131 kapatmak istiyorsan\u0131z WAF ile \u00f6nlem almay\u0131 d\u00fc\u015f\u00fcnebilirsiniz. Elbette farkl\u0131 \u00e7\u00f6z\u00fcm y\u00f6ntemleri de vard\u0131r. Sald\u0131rgan\u0131n ip adresini bir tabloya kaydederek belirli zaman aral\u0131klar\u0131nda sizin limitinizden fazla login iste\u011finde bulunursa bunu tespit edip ilgili ip adresine bloklama koyabilirsiniz ancak bu arkaplanda \u00e7ok fazla geli\u015ftirme isteyecektir. IP adreslerini tuttu\u011funuz bir tablo, o tabloya hem yazma hem de g\u00fcncelleme yapacak olan kodlar, belirli zaman aral\u0131klar\u0131nda tablonun temizlenmesi ve e\u015fik de\u011ferini ge\u00e7en ip adresleri i\u00e7in job'lar\u0131n \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131 vb. B\u00fct\u00fcn bu s\u00fcre\u00e7ler k\u00fc\u00e7\u00fck firmalarda belki esnek bir \u015fekilde i\u015fletilebilir ve asl\u0131nda kendi bruteforce \u00f6nlemini kendiniz alabilirsiniz ancak b\u00fcy\u00fck firmalarada, task'\u0131n a\u00e7\u0131lmas\u0131, assing edilmesi, geli\u015ftirmenin yap\u0131lmas\u0131, test edilmesi, bir sorun varsa sorunun \u00e7\u00f6z\u00fclmesi ve tekrar test edilmesi gibi s\u00fcre\u00e7ler verimlilik d\u00fc\u015fman\u0131d\u0131r. Bu tarz durumlarda paray\u0131 veren d\u00fcd\u00fc\u011f\u00fc \u00e7alar \u015feklinde direkt olarak WAF teknolojilerinden yararlan\u0131labilir. AWS taraf\u0131nda ise bunu yapmak olduk\u00e7a kolayd\u0131r. Bu yaz\u0131 i\u00e7erisinde temel WAF kullan\u0131m\u0131ndan bahsetmek istiyorum ancak ben de bu konuda yeni oldu\u011fumdan dolay\u0131 \u00e7ok basit bir anlat\u0131m ger\u00e7ekle\u015ftirece\u011fim. Paragraf\u0131n ba\u015f\u0131ndaki \u00f6rne\u011fi baz alarak Bruteforce sald\u0131r\u0131lar\u0131na \u00f6nlem ald\u0131\u011f\u0131m\u0131z bir sistem geli\u015ftirece\u011fiz.<\/p>\n<h1>Haz\u0131rl\u0131k<\/h1>\n<p>Bu senaryoyu i\u015fletmek i\u00e7in bir lambda aya\u011fa kald\u0131rd\u0131m ve a\u015fa\u011f\u0131daki kodlar\u0131 yazd\u0131m.<\/p>\n<pre><code class=\"language-py\">import json\nimport urllib.parse\n\ndef lambda_handler(event, context):\n    try:\n\n        # &#039;username&#039; ve &#039;password&#039; alanlar\u0131n\u0131 \u00e7\u00f6z ve de\u011ferlerini al\n        username = event.get(&#039;username&#039;, [None])\n\n        # Kullan\u0131c\u0131 ad\u0131 ve parolay\u0131 kontrol et\n        if username == &quot;admin&quot;:\n            return {\n                &#039;statusCode&#039;: 200,\n                &#039;body&#039;: json.dumps(&#039;Login successful&#039;)\n            }\n        else:\n            return {\n                &#039;statusCode&#039;: 300,\n                &#039;body&#039;: json.dumps(&#039;Invalid credentials&#039;)\n            }\n\n    except Exception as e:\n        return {\n            &#039;statusCode&#039;: 500,\n            &#039;body&#039;: json.dumps(f&quot;An error occurred: {str(e)}&quot;)\n        }<\/code><\/pre>\n<p>Kodlardan da anla\u015f\u0131ld\u0131\u011f\u0131 \u00fczere e\u011fer kullan\u0131c\u0131 ad\u0131 parametresi admin olarak gelirse 200 d\u00f6nd\u00fcrmekteyiz. Di\u011fer b\u00fct\u00fcn giri\u015fler i\u00e7in 300 de\u011feri d\u00f6nd\u00fcrmekteyiz. Daha sonras\u0131nda bir api-gateway aya\u011fa kald\u0131r\u0131p bu lambday\u0131 ap-gateway'e ba\u011flad\u0131m. Lambdam Canada'da api-gateway ise Stockholm'da yer almaktad\u0131r. WAF ile ap-gateway'in ayn\u0131 region'da yer almas\u0131 gerekmektedir.<\/p>\n<h1>Kurulum<\/h1>\n<p>WAF ekran\u0131na geldi\u011fimde yeni bir WEB ACL \u00fcretmek istedi\u011fimi belirttim ve Stockholm'da yer alan api gateway'i burada se\u00e7tim. Burada bahsetmem gerken bir husus var nedenin bilmedi\u011fim bir durumdan dolay\u0131 yaln\u0131zca rest-api olarak aya\u011fa kald\u0131rd\u0131\u011f\u0131n\u0131 api-gateway'ler g\u00f6z\u00fckmetedir. http-api'ler g\u00f6z\u00fckmemektedir. Daha sonras\u0131nda a\u015fa\u011f\u0131daki gibi bir rule olu\u015fturdum.<\/p>\n<pre><code class=\"language-json\">{\n  &quot;Name&quot;: &quot;bruteforce&quot;,\n  &quot;Priority&quot;: 0,\n  &quot;Statement&quot;: {\n    &quot;RateBasedStatement&quot;: {\n      &quot;Limit&quot;: 100,\n      &quot;EvaluationWindowSec&quot;: 300,\n      &quot;AggregateKeyType&quot;: &quot;IP&quot;,\n      &quot;ScopeDownStatement&quot;: {\n        &quot;ByteMatchStatement&quot;: {\n          &quot;SearchString&quot;: &quot;test\/login&quot;,\n          &quot;FieldToMatch&quot;: {\n            &quot;UriPath&quot;: {}\n          },\n          &quot;TextTransformations&quot;: [\n            {\n              &quot;Priority&quot;: 0,\n              &quot;Type&quot;: &quot;NONE&quot;\n            }\n          ],\n          &quot;PositionalConstraint&quot;: &quot;CONTAINS&quot;\n        }\n      }\n    }\n  },\n  &quot;Action&quot;: {\n    &quot;Block&quot;: {\n      &quot;CustomResponse&quot;: {\n        &quot;ResponseCode&quot;: 404\n      }\n    }\n  },\n  &quot;VisibilityConfig&quot;: {\n    &quot;SampledRequestsEnabled&quot;: true,\n    &quot;CloudWatchMetricsEnabled&quot;: true,\n    &quot;MetricName&quot;: &quot;bruteforce&quot;\n  }\n}<\/code><\/pre>\n<p>Yukar\u0131daki konfig\u00fcrasyonu g\u00f6rsel hale getirdi\u011fimizde daha net bir \u015fekilde anla\u015f\u0131lacakt\u0131r ama 300 saniye i\u00e7erisinde api gateway'im i\u00e7eriisnde test\/login k\u0131sm\u0131na bir ip'den e\u011fer 100 istek gelirse bunu bir bruteforce olarak adland\u0131r ve art\u0131k 404 \u015feklinde d\u00f6n\u00fc\u015f yap diyorum.<\/p>\n<h1>Test<\/h1>\n<p><img decoding=\"async\" src=\"http:\/\/berenkudaygorun.com\/blog\/wp-content\/uploads\/2024\/01\/Ekran-Resmi-2024-01-10-18.15.09.png\" style=\"width: 100%; height: auto;\"><\/p>\n<p>Daha sonras\u0131nda yukar\u0131daki gibi burp ile bir brute force ba\u015flatt\u0131m. Sonu\u00e7lar a\u015fa\u011f\u0131daki gibi...<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/berenkudaygorun.com\/blog\/wp-content\/uploads\/2024\/01\/Ekran-Resmi-2024-01-10-18.19.47.png\" style=\"width: 100%; height: auto;\"><\/p>\n<p>AWS taraf\u0131 limiti tutturma konusunda tam stabil \u00e7al\u0131\u015fmasada belirli bir s\u00fcre sonunda isteklerin art\u0131k 404 geldi\u011fini g\u00f6rebiliyoruz. Ayn\u0131 zamanda burada istersek kendimiz WAF taraf\u0131ndan bir cevap ile de d\u00f6nebiliriz. Ve vermi\u015f oldu\u011fumuz kuraldan dolay\u0131 sadece bu api'ye bloklama i\u015flemi ger\u00e7ekle\u015ftirdik. E\u011fer istersek defaul halinde b\u00fct\u00fcn api'lere kar\u015f\u0131 bir bloklamada yapabilirdik.<\/p>\n<p>\u015eimdi cevap \u00fcreterek bir bloglama i\u015flemi yapal\u0131m. Bu noktada kural\u0131m\u0131z art\u0131k a\u015fa\u011f\u0131daki gibi olacakt\u0131r.<\/p>\n<pre><code class=\"language-json\">{\n  &quot;Name&quot;: &quot;bruteforce&quot;,\n  &quot;Priority&quot;: 0,\n  &quot;Statement&quot;: {\n    &quot;RateBasedStatement&quot;: {\n      &quot;Limit&quot;: 100,\n      &quot;EvaluationWindowSec&quot;: 300,\n      &quot;AggregateKeyType&quot;: &quot;IP&quot;,\n      &quot;ScopeDownStatement&quot;: {\n        &quot;ByteMatchStatement&quot;: {\n          &quot;SearchString&quot;: &quot;test\/login&quot;,\n          &quot;FieldToMatch&quot;: {\n            &quot;UriPath&quot;: {}\n          },\n          &quot;TextTransformations&quot;: [\n            {\n              &quot;Priority&quot;: 0,\n              &quot;Type&quot;: &quot;NONE&quot;\n            }\n          ],\n          &quot;PositionalConstraint&quot;: &quot;CONTAINS&quot;\n        }\n      }\n    }\n  },\n  &quot;Action&quot;: {\n    &quot;Block&quot;: {\n      &quot;CustomResponse&quot;: {\n        &quot;ResponseCode&quot;: 404,\n        &quot;CustomResponseBodyKey&quot;: &quot;test&quot;\n      }\n    }\n  },\n  &quot;VisibilityConfig&quot;: {\n    &quot;SampledRequestsEnabled&quot;: true,\n    &quot;CloudWatchMetricsEnabled&quot;: true,\n    &quot;MetricName&quot;: &quot;bruteforce&quot;\n  }\n}<\/code><\/pre>\n<p>&quot;CustomResponseBodyKey&quot;: &quot;test&quot; k\u0131sm\u0131n\u0131 i\u00e7eride sarikamyon ifadesine denk gelecek \u015fekilde ayarlad\u0131m ve bu i\u015flem sonucunda a\u015fa\u011f\u0131daki gibi bir http response d\u00f6nmeye ba\u015fld\u0131.<\/p>\n<pre><code class=\"language-http\">HTTP\/2 404 Not Found\nDate: Wed, 10 Jan 2024 15:30:48 GMT\nContent-Type: text\/plain\nContent-Length: 10\nX-Amzn-Requestid: fb851cb2-df6c-459b-b125-e903a48afffb\nX-Amzn-Errortype: ForbiddenException\nX-Amz-Apigw-Id: RVG2ZHOagi0Ektw=\n\nsarikamyon<\/code><\/pre>\n<p>Burada d\u00f6nen cevap t\u00fcr\u00fcn\u00fc plantext, json vb. istedi\u011finiz \u015fekilde ayarlayabilirsiniz.<\/p>\n<p>\u015eimdilik bu kadar. \u0130lerleye s\u00fcre\u00e7te WAF taraf\u0131nda engellenen ip adresline s\u00fcre atanamad\u0131\u011f\u0131nda dolay\u0131 CloudWatch, Lambda ve WAF i\u015fbirli\u011fi ile engellenen ip adreslerine nas\u0131l custom s\u00fcre atayabilece\u011fimizi g\u00f6sterece\u011fim.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Halbuki o (Kur\u2019an), ancak \u00e2lemler i\u00e7in (ger\u00e7e\u011fi) hat\u0131rla(t)mad\u0131r. Kalem 52 Giri\u015f Projelerde bir\u00e7ok alanda WAF ihtiyac\u0131 do\u011fal bir ihtiya\u00e7t\u0131r. \u00d6rnek vermek gerekirse bir mobil uygulama&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/berenkudaygorun.com\/blog\/blog\/2024\/01\/10\/aws-waf-temel-kurulum\/\">Devam\u0131n\u0131 oku<span class=\"screen-reader-text\">AWS WAF Temel Kurulum<\/span><\/a><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[618,697],"tags":[703],"class_list":["post-2203","post","type-post","status-publish","format-standard","hentry","category-aws","category-aws-pentesting","tag-waf","entry"],"_links":{"self":[{"href":"https:\/\/berenkudaygorun.com\/blog\/wp-json\/wp\/v2\/posts\/2203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/berenkudaygorun.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/berenkudaygorun.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/berenkudaygorun.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/berenkudaygorun.com\/blog\/wp-json\/wp\/v2\/comments?post=2203"}],"version-history":[{"count":2,"href":"https:\/\/berenkudaygorun.com\/blog\/wp-json\/wp\/v2\/posts\/2203\/revisions"}],"predecessor-version":[{"id":2207,"href":"https:\/\/berenkudaygorun.com\/blog\/wp-json\/wp\/v2\/posts\/2203\/revisions\/2207"}],"wp:attachment":[{"href":"https:\/\/berenkudaygorun.com\/blog\/wp-json\/wp\/v2\/media?parent=2203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/berenkudaygorun.com\/blog\/wp-json\/wp\/v2\/categories?post=2203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/berenkudaygorun.com\/blog\/wp-json\/wp\/v2\/tags?post=2203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}