Merhabalar,
Saldırı vektörlerinin tespitinde WAF uygulamaları blacklist/whitelist tabanlı çalışmakta. Bu yaklaşımları WAF’ın öğrenme moduyla birlikte kullandığımızda otomatik olarak atak vektörü eklememiz mümkün olabiliyor. Bu bağlamda Rus güvenlik araştırmacıları Denis Kolegov ve Arseny Reutov WAF’ların öğrenme moduna katkı sağlayacak bir yapıyı client-side fazında nasıl geliştiririz sorusunun cevabını aramışlar ve AST dediğimiz yapı ile buna bir çözüm üretmişler.
Özetle, tespit aşamasının özünde AST yapısı yatıyor. Bu kısmı biraz anlamaya çalışalım. Bu konuda uzman değilim fakat referanslarda belirttiğim kaynakları incelemeye çalıştım.
AST (Abstract Syntax Tree) nedir?
Programla dillerinde yazılan komutların anlaşılması için ilk olarak parsing işleminin gerçekleşmesi gerekmektedir. Bir kodun anlamlı küçük parçalara ayrılmasında lexer görev alır. Bu aşamada kod token haline getirilir ve sonraki aşamada ise parser’a geçerek lexer’dan aldığı tokenlar ile gramer yapısını doğrular ve sonucunda AST kodunu ortaya çıkartır. Bu yapının anlaşılması adına bir örnekle devam edelim.
var x= 34; kod parçası doğru bir gramere sahiptir. İlgili değişken için bir Online bir araçla AST analizi yaptığımızda aşağıdaki gibi bir sonuca ulaşmaktayız.
Token Yapısı şu şekilde: Keyword(var) Identifier(x) Punctuator(=) Numeric(34) Punctuator(;)

Görüldüğü gibi boşluklar dışındaki değerler token olarak belirlendi. Eğer JavaScript’in syntaxını doğru bir şekilde yazmazsak hata verecekti. İlk olarak basit bir JavaScript kodu denedik. Şimdi bir tane XSS atak vektörü kullanarak AST çıktısını incelemeye çalışalım.
Kaynak kodumuzdaki taslağımızda var a = "BURAYAPAYLOADGELECEK";
şeklinde bir Js kodu olduğunu varsayalım ve bu değişkene kullanıcıdan değer gönderilebildiğini varsayalım.Saldırgandan gelen isteği öyle bir yazmalıyız ki mevcut syntax’i bozmayacak şekilde olmalı.
Mesela şu şekilde var a = " BURAYAPAYLOADGELECEK" ";
bir istek attığımızı düşünelim. “Unexpected token ILLEGAL” gibi bir hata alacağız ve JavaScript çalışmayacak. Saldırgan kodu şu şekilde yazsın. var a = "";alert(1)//";
Bu tasklaktaki atak vektörü de şu şekilde ";alert(1)//
Atak vektörünü böyle yazdığımızda AST çıktısını alabildik. Bu şu demek oluyor; Saldırgan anlamlı bir kod yapısı oluşturabildiği için alert() fonksiyonunu çalıştırabildi.
Peki bu atak vektörünün AST çıktısı nasıl, online bir AST aracıyla inceleyelim.

Ağaç yapısına baktığımızda bir önceki ağaç yapısından farklı olarak ExpressionStatement kısmı ilgimizi çekiyor. Callexpression node değerinde alert fonksiyonunu görebiliyorsunuz. Callexpression bize davranışsal analiz aşaması için yol gösteriyor. Bunun dışında aşağıdaki durumları da bilmekte fayda var.
-
Sadece tek bir taslak kullandık. Çok farklı taslaklar oluşturulabilir.
-
alert fonksiyonun çok farklı gösterimleri var. Function Invocation örneklerini inceleyebilirsiniz. (https://gist.github.com/myshov/05800f083a0afce56e0f782314a103eb#file-function_invocation-js)
Bu noktalar başka bir blog yazısının konusu diyelim ve devam edelim.
Şu an elimizde şöyle bir bilgi var. Eğer saldırgan belirtilen JavaScript kodunun gramerini doğru bir şekilde oluşturursa AST çıktısı alabiliriz..
Bu noktada tespit aşaması için Esprima parserı kullanarak neler yapabileceğimizi inceleyelim. Aşağıdaki kod parçasında mevcut taslak için Esprima parserını kullandık.
var esprima = require('esprima');
var buf = new Buffer(process.argv[2], 'base64').toString('ascii');
console.log("Payload: " + buf);
var b = "var x =\"" + buf + "\"";
console.log("Template: " + b);
esprima.parseScript(b, { comment: true }, function (node) {
if (node.type === 'CallExpression') {
console.log("XSS tespit edildi");
}
});
Kodun şu kısmında, ilgili node CallExpression ile eşleşirse XSS atak vektörünü tespit edebiliyoruz.
esprima.parseScript(b, { comment: true }, function (node) {
if (node.type === 'CallExpression') {
console.log("XSS tespit edildi");
}
});
Saldırgan popup çıkartmak için alert dışında başka fonksiyonlarda kullanabilir. Mesela console.log
atak vektörü. Yine aynı taslak için deneyelim.

Evet görüldüğü gibi bu çıktıyla da CallExpression’ı gözlemledik. Bunun dışında, bazı evasion’lar için yine CallExpression node bilgisine ulaşabiliyoruz.
$.globalEval("al"+"ert()");
ama aşağıdaki gibi bir evasion için NewExpression kullanıldığını görüyoruz.
new Function`al\ert\`1\``
Başka bir evasion örneği için TaggedTemplateExpression kullanılmış
setTimeout`\x64ocument.write\x28\x64ocument.\x63ookie\x29`
Bunun gibi çok sayıda atak vektörü denemesi yapılabilir. Sonuç olarak AST yaklaşımı ile;
- 0dayclient-side ataklarını tespit edebilmek
- Katmanlı güvenlik mimarisi oluşturabilmek
mümkün olabilir.
Faydalı olması dileğiyle.
Bu yazıda emeği geçen @A_Burak_Gokalp ‘a teşekkürler.
Referanslar :
https://speakerdeck.com/dnkolegov/waf-dot-js-how-to-protect-web-applications-using-javascript
https://medium.com/basecs/leveling-up-ones-parsing-game-with-asts-d7a6fc2400ff
https://www.slideshare.net/JarrodOverson/javascript-asts-transformations-analysis-and-transpiling
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API
https://www.slideshare.net/JamundFerguson/ui-40829744
https://jotadeveloper.com/blog/2016/03/19/abstract-syntax-trees-on-javascript/
https://zhuanlan.zhihu.com/p/32189701
https://itnext.io/ast-for-javascript-developers-3e79aeb08343
http://tobyho.com/2013/12/02/fun-with-esprima/
https://ariya.io/2016/12/on-the-fly-javascript-syntax-node-inspection
https://stackoverflow.com/questions/47972903/difference-between-callexpression-and-memberexpression
http://www.ecma-international.org/ecma-262/5.1/
https://esprima.org/demo/parse.html?code=
https://tomnomnom.com/talks/advxss.pdf
https://github.com/0xInfection/Awesome-WAF
https://medium.com/basecs/leveling-up-ones-parsing-game-with-asts-d7a6fc2400ff
https://gist.github.com/myshov/05800f083a0afce56e0f782314a103eb#file-function_invocation-js
https://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/
http://resources.jointjs.com/demos/javascript-ast
https://blog.buildo.io/a-tour-of-abstract-syntax-trees-906c0574a067
https://twitter.com/c0mr3x/status/1149284940028272640?s=19
https://ysar.net/python/parsing-parser-topdown-operator-precedence.html
https://medium.com/@sddkal/python-ile-python-lexer-yazal%C4%B1m-1447d0b23dc3