Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
RASP vs WAF
Mario	Contestabile
Who am I
•  Professional	Penetra0on	Tester/Applica0on	Security	Analyst	
•  h:ps://ca.linkedin.com/in/0utlaw	
•  h:ps://twi:er.com/gymfigh0ng	
•  Mario@immun.io	
•  CEH,	MCSD,	CCP,	ACP,	CCNA,	CISSP,	GWAPT,	GXPN,	GCUX	
•  Currently	at	Montreal	Security	startup	IMMUNIO
WTF is a RASP?
•  PuPng	security	smarts	inside	an	app		
•  Not	around-it	
•  Not	outside-of-it	
•  	Let	me	show	you	code!	
•  h:ps://github.com/webarmor	(different	agents)	
•  h:ps://github.com/webarmor/agent-python/blob/master/immunio/
plugins/plugin_fileio.py	(	Python	hooks)	
•  h:ps://github.com/webarmor/agent-ruby/blob/master/lib/immunio/
plugins/io.rb	(Ruby	hooks)
WTF is a RASP?
•  No0ce	we	had	3	different	agents/plaZorm	
•  Python	
•  Java	
•  Ruby	
•  Customers	have	access	to	all	of	the	client	code	
•  No0ce	the	similari0es	
•  They	all	need	to	get	up	early!	
•  Python	example,	“import	RASP.start”	in	a	run.py…	
•  Java	example,	“java	RASP.jar	server.jar”	on	the	command	line…	
•  Ruby	not	as	bad
WTF is a RASP?
•  No0ce	the	similari0es	
•  They	all	need	“hooking”	
•  Easy	in	Python	“os.open	=	my_open”	
•  Easy	in	Ruby	(“alias_method”	and	“extend”)	
•  Java	Instrumenta0on	API,	Transformers,	and	premain()	
•  IO	example,	in	Ruby	
•  Kernel.send :alias_method, :backtick_without_immunio, :`
And
•  IO.extend Immunio::IOClassHooks
WTF is a RASP?
•  It	is	not	your	mom’s	func0on-pointer-replacing	(remember	
GetProcAddress!),	DLL-shimming	(remember	IAT	Import	Address	
Table)	header.
•  These	are	run0me	languages.	
•  These	run0me	language	support	dynamic	replacement	of	a:ributes	
at	run0me,	you	may	know	this	as	“monkey	patching”.	
•  A	way	in	which	we	can	modify	or	extend	the	execu?on	of	code	at	
run?me.
RASP – 2 Concerns
•  Code	reuse	
•  Lua	(don’t	want	to	rewrite	algorithms	each	0me)	
•  Database	language	drivers	(dbapi2	(python),	mysql-connector-java,	Ac0ve	
Record	(ruby))	for	SQLi	(always	specifics	to	write	code	for)	
•  Templates	(Django	and	jinja2	(Python),	Ac0on	View	(Rails),	Jasper	(Java))	for	
XSS	(a	RASP	is	not	stack	agnos0c,	it’s	stack	expert)	
•  Performance	
•  Lua/LuaJIT		
•  LPeg		
•  Lua	is	used	in	embedded	systems,	games,	size	of	400KB.	LuaJIT	compiles	it	to	
very	fast	machine	code,	and	LPeg	is	its	fast	pa:ern-matching	library.
RASP – 2 Concerns
•  Code	reuse	example	-	Python	
>>> import lupa
>>> from lupa import LuaRuntime
>>> lua = LuaRuntime(unpack_returned_tuples=True)
>>> lua.eval('1+1')
2
Run;me App Self-Protec;on 
•  New	technology	to	solve	an	old	problem.	
•  Not	tackled	prior	to	2014,	why?	
•  Requires	per-plaZorm	code	
•  Meaning	per-plaZorm	dev	teams,	QA,	etc..	
•  Market	money	going	to	WAF	like	products	and	solu0ons,	<	1%	of	security	used	today	is	based	
on	RASP	
•  In	fact,	if	you	Google	“RASP”	you	have	to	get	to	page	4	for	any	security	related	
hits.	
•  But	now,	there	is	
•  HP	Applica0on	Defender	
•  Checkmarx		
•  Contrast	Security	
•  Prevoty
How does it work? (xss example)
•  At	a	high	level	a	RASP	can	do	xss	protec0on	the	“right”	way,	from	
within	the	template	rendering	mechanism.	The	algorithm	goes	
something	like:	
•  Look	at	the	html	page	rendered	
•  Note	each	dynamic	parameter’s	loca0on	and	context	
•  Depending	on	the	context,	encode	accordingly	
•  Why	is	this	“right”?	
•  No	more	cat-and-mouse	regular	expression	game	(WAFs)	
•  Source	of	input	values	are	unimportant,	may	be	something	other	than	the	
request	
•  Developers	need	not	proac0vely	call	the	proper	encoding	APIs
How does it work? (xss example)
•  Rendering	hooks	fire	
•  Dynamic	variables	in	output	are	determined	
•  Determine	context	(code	reuse,	LUA)	
•  Mark	each	variable	with	meta-data,	including	context	
•  Encode	for	proper	context	during	rendering
How does it work? (xss example)
•  Easy	
<html>
Welcome to Hackfest {value}
</html>
•  Not	so	easy	
<html>
<head>
<title>Hackfest 2015</title>
<style type="text/css">
body {
background-color: {value} }
</style>
</head>
What your WAF sees
GET / HTTP/1.1
Host: 1.0.0.6:5000
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
46.0.2490.80 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Cookie: __utma=foo; __utmz=162530492.1442505958.1.1.utmcsr=(direct)|utmccn=(direct)|
utmcmd=(none); csrftoken=bar; remember_token=1|
317ae4390a37e7ac78bd4bfb083e6482e068cc9d9a1077ed23df1c3df92fbf1d0503ee435ab52fba09d4a4f53c
469b9b938104ff5010bdf56d30b4e56dfd8c42;
session=eyJfZnJlc2giOmZhbHNlLCJjc3JmX3Rva2VuIjp7IiBiIjoiTW1JNFpXUTJPR0V4TkdZMU5HSTJPREJqWT
JKa01HUmhNV1F4TlRsbVl6WXdNemhpTjJRd05RPT0ifSwidXNlcl9pZCI6IjEifQ.CRKNJw.OJL9399JCUzaUWoFBj
7sTjNI20s
But what didn’t it see…
•  Is	that	a	real	session,	or	an	anonymous	one?	
•  Is	that	session	an	actual,	valid	value?	
•  Who	if	anyone	is	logged	in?	What’s	their	username!?	
•  Is	that	CSRF	token	real	or	bogus?
What your WAF sees
POST /accounts/login/?next=/ HTTP/1.1
Host: 1.0.0.6:8010
Content-Length: 125
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://1.0.0.6:8010
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://1.0.0.6:8010/accounts/login/?next=/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Cookie: __utma=162530492.1677577446.1442505958.1442505958.1442515406.2; __utmz=162530492.1442505958.1.1.utmcsr=(direct)|utmccn=(direct)|
utmcmd=(none); _vulnerable_session=JlXcvMQ38Tx1fbTD3VIpomnZtRnn2QYB; remember_token=1|
317ae4390a37e7ac78bd4bfb083e6482e068cc9d9a1077ed23df1c3df92fbf1d0503ee435ab52fba09d4a4f53c469b9b938104ff5010bdf56d30b4e56dfd8c42;
session=683be987ca49acd97e4097bd402e281830050593gAJKEwwxVkdB1YxC0yqiFn1xAVUHX2NzcmZ0X3ECWCgAAAA4MzI0YzYxMGViMGI4MTFlMGM3NGFkZDY5ZGJjZTYyZmYwMjI0YjI5cQ
Nzh3EELg==; csrftoken=JmfbGeRGsWv3XGjdIEYjBUYDL4BcJsm3
referrer=http%3A%2F%2F1.0.0.6%3A8010%2F&csrfmiddlewaretoken=JmfbGeRGsWv3XGjdIEYjBUYDL4BcJsm3&username=james&password=12345678
But what didn’t it see…
•  That	was	a	login	a:empt,	and	not	simply	a	POST	
•  How	many	0mes	did	this	user	“james”	a:empt	logins?	Is	this	the	first,	
or	the	101st?	
•  Was	the	login	successful,	or	not?	
•  Has	“james”	logged	in	from	different	IPs?	What	region	did	these	
logins	occur	from?	Was	“james”	using	a	Tor	node?	
•  Lets	take	a	real	app	h:ps://github.com/miguelgrinberg/microblog
What your WAF sees
POST / HTTP/1.1
Host: 1.0.0.6:5000
Content-Length: 102
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://1.0.0.6:5000
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://1.0.0.6:5000/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Cookie: __utma=162530492.1677577446.1442505958.1442505958.1442515406.2; __utmz=162530492.1442505958.1.1.utmcsr=(direct)|
utmccn=(direct)|utmcmd=(none); _vulnerable_session=JlXcvMQ38Tx1fbTD3VIpomnZtRnn2QYB;
csrftoken=JmfbGeRGsWv3XGjdIEYjBUYDL4BcJsm3; remember_token=1|
317ae4390a37e7ac78bd4bfb083e6482e068cc9d9a1077ed23df1c3df92fbf1d0503ee435ab52fba09d4a4f53c469b9b938104ff5010bdf56d30b4e56df
d8c42;
session=eyJfZnJlc2giOmZhbHNlLCJjc3JmX3Rva2VuIjp7IiBiIjoiTW1JNFpXUTJPR0V4TkdZMU5HSTJPREJqWTJKa01HUmhNV1F4TlRsbVl6WXdNemhpTjJ
Rd05RPT0ifSwidXNlcl9pZCI6IjEifQ.CRKNZw.22a8XCyVPcy5nYrf6LM4wcIwagQ
csrf_token=1446054390.9%23%23d6030368991a5da453071f0747682fe2d01dcbef&post=%3CH1%3EHackfest%3C%2FH1%3E
What a RASP sees instead…the real jinja2
template
From:	h:ps://github.com/miguelgrinberg/microblog/blob/master/app/templates/post.html	
<table	class="table	table-hover">	
			{%	autoescape	false	%}	
				<tr>	
								<td	width="70px"><a	href="{{	url_for('user',	nickname=post.author.nickname)	}}"><img	src="{{	post.author.avatar(70)	}}"	/></a></td>	
								<td>	
													
												<p>{{	_('%(nickname)s	said	%(when)s:',	nickname='<a	href="%s">%s</a>'	%	(url_for('user',	nickname=post.author.nickname),	post.author.nickname),	when=momentjs(post.0mestamp).fromNow())	}}</p>	
												<p><strong><span	id="post{{	post.id	}}">{{	post.body	}}</span></strong></p>	
												{%	if	post.language	!=	None	and	post.language	!=	''	and	post.language	!=	g.locale	%}	
												<div>	
																<span	id="transla0on{{	post.id	}}">	
																				<a	href="javascript:translate('{{	post.language	}}',	'{{	g.locale	}}',	'#post{{	post.id	}}',	'#transla0on{{	post.id	}}',	'#loading{{	post.id	}}');">{{	_('Translate')	}}</a>	
																</span>	
																<img	id="loading{{	post.id	}}"	style="display:	none"	src="/sta0c/img/loading.gif">	
												</div>	
												{%	endif	%}	
												{%	if	post.author.id	==	g.user.id	%}	
												<div><a	href="{{	url_for('delete',	id	=	post.id)	}}">{{	_('Delete')	}}</a></div>	
												{%	endif	%}	
								</td>	
				</tr>	
				{%	endautoescape	%}	
</table>
Which do you think stands the best chance of
catching you…
Which do you think stands the best chance of
catching you…
•  Even	IFF	a	WAF	had	world-class	unbeatable	string	parsing	with	no	
false	posi0ves	for	any	language	for	any	scenario	such	that	it	blocks		
•  =%3CH1%3EHackfest%3C%2FH1%3E
•  That’s	it?	So	if	the	a:ack	payload	doesn’t	come	via	a	request	we	lose?	
We	tell	developers	to	call	the	ESAPI	the	right	way	in	the	right	place?	
•  RASPs	here	really	shine.	Not	only	could	they	block	at	the	request	
level,	but	what	they	can	do,	is	take	care	of	encoding	since	they	have	
all	the	informa0on	needed.	
•  No	developer	interven0on,	no	code	changes,	no	more	XSS.
If we try our typical <script>alert(0)</script>
•  RASP	encoding	enabled,	results	with	this	page	in	your	browser.	No	API	calls:	
	<p><a href="/user/IMMUNIO">IMMUNIO</a> said <script>
document.write(moment("2015-10-28T19:11:07 Z").fromNow());
</script>:</p>
<p><strong><span
id="post1">&lt;script&gt;alert(0)&lt;&#47;script&gt;</span></
strong></p>
		
•  Turning	off	RASP	encoding,	results	are	as	expected:	
	<p><a href="/user/IMMUNIO">IMMUNIO</a> said <script>
document.write(moment("2015-10-28T19:11:07 Z").fromNow());
</script>:</p>
<p><strong><span id="post1"><script>alert(0)</script></
span></strong></p>
Agents are great, but we can do more!
•  We’ve	seen	low-level	hooks	for	files	and	html,	and	we’ve	seen	how	
this	gives	a	RASP	powerful	protec0on	for	file	access	and	cross-site	
scrip0ng.	
•  But	what	if	agents	added	smarts	so	that	ac0ons	can	be	taken	on	the	
meta-informa0on?	
•  Lets	go	back	to	“james”	logging	into	the	app…
What your WAF sees
POST /accounts/login/?next=/ HTTP/1.1
Host: 1.0.0.6:8010
Content-Length: 125
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://1.0.0.6:8010
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://1.0.0.6:8010/accounts/login/?next=/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
Cookie: __utma=162530492.1677577446.1442505958.1442505958.1442515406.2; __utmz=162530492.1442505958.1.1.utmcsr=(direct)|utmccn=(direct)|
utmcmd=(none); _vulnerable_session=JlXcvMQ38Tx1fbTD3VIpomnZtRnn2QYB; remember_token=1|
317ae4390a37e7ac78bd4bfb083e6482e068cc9d9a1077ed23df1c3df92fbf1d0503ee435ab52fba09d4a4f53c469b9b938104ff5010bdf56d30b4e56dfd8c42;
session=683be987ca49acd97e4097bd402e281830050593gAJKEwwxVkdB1YxC0yqiFn1xAVUHX2NzcmZ0X3ECWCgAAAA4MzI0YzYxMGViMGI4MTFlMGM3NGFkZDY5ZGJjZTYyZmYwMjI0YjI5cQ
Nzh3EELg==; csrftoken=JmfbGeRGsWv3XGjdIEYjBUYDL4BcJsm3
referrer=http%3A%2F%2F1.0.0.6%3A8010%2F&csrfmiddlewaretoken=JmfbGeRGsWv3XGjdIEYjBUYDL4BcJsm3&username=james&password=12345678
Aggrega;ng agent informa;on
•  I	touched	upon	this	earlier,	detec0ng	if	“james”	is	logging	in	from	all	
over	the	world.	Here,	a	RASP	can	provide	benefits	above	and	beyond	
anything	today’s	WAFs	can	do.	
•  When	does	a	RASP	call	home?	
•  What	informa0on	does	a	RASP	send	home?	
•  Anything	sensi0ve?	The	RASP	vendor	must	be	trustworthy
Aggrega;ng agent informa;on
•  RASPs	need	to	know	more	than	the	traffic	they	are	seeing!
Aggrega;ng agent informa;on
•  An	agent	can’t	do	much	outside	of	its	instance,	if	the	server	has	more	
than	one	instance	this	is	problema0c.	(We	already	saw	that	a	WAF	
doesn’t	even	know	who	“james”	is)	
•  In	our	diagram,	all	a	RASP	sees	is	“james”	logging	in	from	1.1.1.1,	and	
this	is	fine	from	a	RASPs	point	of	view.	
•  In	our	diagram,	if	we	run	100	instances,	and	“james”	fails	to	log	into	
100	of	them,	this	is	fine	from	a	RASPs	point	of	view;	each	agent	sees	
but	one	failed	login.	
•  This	is	shit
Aggrega;ng agent informa;on
•  Solu0on,	send	“interes0ng”	events	to	a	backend.		
•  In	the	backend,	something	can	spot	what	really	happened!	
•  User	account	“james”	failed	to	login	100	0mes	in	5	seconds,	lets	do	
something!	
•  In	comes	a:ack	mi0ga0on,	captchas	or	delays	whatever.	
•  This	is	not	WAF	specific	or	a	RASP-only	feature,	this	is	web	security	
done	right.
Actual example
•  Lets	take	the	latest	Acune0x	
•  And	lets	scan	an	applica0on	with,	and	then	without	a	RASP	
•  First	“shootout”,	open	source	Python	h:ps://github.com/Pylons/shootout	
•  Turn	on	RASP	with	full	blocking/mi0ga0on	
•  A{er	one	minute	you	will	see	this
Actual example – Fully protected
Actual example
•  Turns	out	that	was	too	easy,	the	RASP	immediately	spo:ed	requests	
from	Acune0x,	and	blocked	them.	So	turns	out,	if	we	want	to	have	a	
meaningful	comparison,	we	need	to	dumb-down	the	RASP…	
•  Turn	off	Acune0x	detec0on,	and	re-scan	just	as	before	
•  This	0me	it	takes	6	minutes	and	results	in	16	thousand	requests,	as	
opposed	to	the	6000	requests	blocked	in	the	previous	scan.	
•  So	with	more	of	the	applica0on	visible	to	Acune0x,	it	can	run	its	
magic	in	some	more	places	and	we	can	see	SQLi	a:empts,	as	well	as	
File	access	a:empts,	on	shootout.
Actual example – Disable Acune;x Detec;on
Actual example
•  OK,	but	this	0me	lets	redo	the	same	exercise	using	an	applica0on	
with	all	sorts	of	vulnerabili0es.	
•  This	is	such	an	app,	it’s	in	ruby,	and	it	has	pre:y	much	everything	
wrong	with	it.	
•  So	again,	same	scanner	sePngs	for	both	scans,	same	login,	first	with	
every	mi0ga0on	and	blocking	feature	enabled…
Actual example – Fully protected
Actual example – Not protected
Actual example – Not protected
•  There	are	big	differences.	
•  27	more	alerts	without	RASP	protec0ng	web	applica0on	
•  Plus	this	blind	remote	code	execu0on	
GET	/file/popen?filter=&nslookup	{domain}&'"`0&nslookup	{domain}&`'	HTTP/1.1	
Host:	1.0.0.6:8082	
Generated	by	this	request:	
["ls	-l	|	grep	'&nslookup	dns.ce.006796.15-5.15.26c7a.1.bxss.me&'"`0&nslookup	dns.ce.006796.15-5.15.26c7a.
1.bxss.me&`'';"]	
•  URL	Redirec0on	
•  XSS	
•  Directory	Traversal	
•  Login	page	password-guessing	a:ack
Login page password-guessing aXack
•  Interes0ng,	what	did	it	do	there…	
•  Lets	go	try	to	login	a{er	the	scan	is	complete
Login page password-guessing aXack
•  As	I	men0oned	when	we	discussed	cross-site	scrip0ng,		
•  Detec0ng	and	aler0ng	is	good…	
•  Blocking	is	terrific…	
•  But	as	with	XSS,	when	the	RASP	properly	encoded	for	us	the	dynamic	
inputs,	here	it	detected	10	failed	logins	as	performed	by	Acune0x	
(using	“sample@email.tst”	when	it	runs	its	script	to	check	for	the	
“Login	page	password-guessing	a:ack”),	and	the	RASP	flagged	the	
client	IP	as	bad	and	redirected	to	a	Google	CAPTCHA.	
•  And	that,	as	with	XSS,	without	a	single	code	change	or	new	API	call	by	
a	developer!
Final note on F+’s
•  RASP	and	WAFs	will	have	F+	
•  Meaning	they	will	both	require	whitelis0ng	
•  So	are	you	telling	me	a	RASP	whitelist	“one-ups”	a	WAF	whitelist?	
•  Oh	yes…lets	spot	the	pa:ern
WAF Whitelis;ng
WAF Whitelis;ng
WAF Whitelis;ng
RASP Whitelis;ng
RASP in a SDLC?
•  We	saw	that	the	informa0on	available	for	whitelis0ng	a	XSS	alert	in	a	
RASP	is	very	detailed,	and	specific.	
•  What	if	in	addi0on	to	a	site	administrator,	a	developer	was	able	to	
see	this	data?	Why	not!
RASP in a SDLC, sure!
•  Given	the	following	exposed	jinja2	code
RASP in a SDLC, sure!
•  We	can	provide	XSS	details	so	precise,	a	developer	can	benefit	!!
Links
•  LUA	:	h:p://www.lua.org/about.html	
•  LUPA	:	h:ps://pypi.python.org/pypi/lupa	
•  LUAJIT:	h:p://luajit.org/	
•  RASP:	h:ps://docs.immun.io/	
•  RASP	Ar0cle:	
h:p://www.networkworld.com/ar0cle/2365739/security0/will-
perimeter-firewalls-give-way-to-rasp.html		
•  Monkey	patching:	h:ps://en.wikipedia.org/wiki/Monkey_patch
The END
Thank	you!

More Related Content

HackFest 2015 - Rasp vs waf

  • 2. Who am I •  Professional Penetra0on Tester/Applica0on Security Analyst •  h:ps://ca.linkedin.com/in/0utlaw •  h:ps://twi:er.com/gymfigh0ng •  Mario@immun.io •  CEH, MCSD, CCP, ACP, CCNA, CISSP, GWAPT, GXPN, GCUX •  Currently at Montreal Security startup IMMUNIO
  • 3. WTF is a RASP? •  PuPng security smarts inside an app •  Not around-it •  Not outside-of-it •  Let me show you code! •  h:ps://github.com/webarmor (different agents) •  h:ps://github.com/webarmor/agent-python/blob/master/immunio/ plugins/plugin_fileio.py ( Python hooks) •  h:ps://github.com/webarmor/agent-ruby/blob/master/lib/immunio/ plugins/io.rb (Ruby hooks)
  • 4. WTF is a RASP? •  No0ce we had 3 different agents/plaZorm •  Python •  Java •  Ruby •  Customers have access to all of the client code •  No0ce the similari0es •  They all need to get up early! •  Python example, “import RASP.start” in a run.py… •  Java example, “java RASP.jar server.jar” on the command line… •  Ruby not as bad
  • 5. WTF is a RASP? •  No0ce the similari0es •  They all need “hooking” •  Easy in Python “os.open = my_open” •  Easy in Ruby (“alias_method” and “extend”) •  Java Instrumenta0on API, Transformers, and premain() •  IO example, in Ruby •  Kernel.send :alias_method, :backtick_without_immunio, :` And •  IO.extend Immunio::IOClassHooks
  • 6. WTF is a RASP? •  It is not your mom’s func0on-pointer-replacing (remember GetProcAddress!), DLL-shimming (remember IAT Import Address Table) header. •  These are run0me languages. •  These run0me language support dynamic replacement of a:ributes at run0me, you may know this as “monkey patching”. •  A way in which we can modify or extend the execu?on of code at run?me.
  • 7. RASP – 2 Concerns •  Code reuse •  Lua (don’t want to rewrite algorithms each 0me) •  Database language drivers (dbapi2 (python), mysql-connector-java, Ac0ve Record (ruby)) for SQLi (always specifics to write code for) •  Templates (Django and jinja2 (Python), Ac0on View (Rails), Jasper (Java)) for XSS (a RASP is not stack agnos0c, it’s stack expert) •  Performance •  Lua/LuaJIT •  LPeg •  Lua is used in embedded systems, games, size of 400KB. LuaJIT compiles it to very fast machine code, and LPeg is its fast pa:ern-matching library.
  • 8. RASP – 2 Concerns •  Code reuse example - Python >>> import lupa >>> from lupa import LuaRuntime >>> lua = LuaRuntime(unpack_returned_tuples=True) >>> lua.eval('1+1') 2
  • 9. Run;me App Self-Protec;on •  New technology to solve an old problem. •  Not tackled prior to 2014, why? •  Requires per-plaZorm code •  Meaning per-plaZorm dev teams, QA, etc.. •  Market money going to WAF like products and solu0ons, < 1% of security used today is based on RASP •  In fact, if you Google “RASP” you have to get to page 4 for any security related hits. •  But now, there is •  HP Applica0on Defender •  Checkmarx •  Contrast Security •  Prevoty
  • 10. How does it work? (xss example) •  At a high level a RASP can do xss protec0on the “right” way, from within the template rendering mechanism. The algorithm goes something like: •  Look at the html page rendered •  Note each dynamic parameter’s loca0on and context •  Depending on the context, encode accordingly •  Why is this “right”? •  No more cat-and-mouse regular expression game (WAFs) •  Source of input values are unimportant, may be something other than the request •  Developers need not proac0vely call the proper encoding APIs
  • 11. How does it work? (xss example) •  Rendering hooks fire •  Dynamic variables in output are determined •  Determine context (code reuse, LUA) •  Mark each variable with meta-data, including context •  Encode for proper context during rendering
  • 12. How does it work? (xss example) •  Easy <html> Welcome to Hackfest {value} </html> •  Not so easy <html> <head> <title>Hackfest 2015</title> <style type="text/css"> body { background-color: {value} } </style> </head>
  • 13. What your WAF sees GET / HTTP/1.1 Host: 1.0.0.6:5000 Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ 46.0.2490.80 Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-GB,en-US;q=0.8,en;q=0.6 Cookie: __utma=foo; __utmz=162530492.1442505958.1.1.utmcsr=(direct)|utmccn=(direct)| utmcmd=(none); csrftoken=bar; remember_token=1| 317ae4390a37e7ac78bd4bfb083e6482e068cc9d9a1077ed23df1c3df92fbf1d0503ee435ab52fba09d4a4f53c 469b9b938104ff5010bdf56d30b4e56dfd8c42; session=eyJfZnJlc2giOmZhbHNlLCJjc3JmX3Rva2VuIjp7IiBiIjoiTW1JNFpXUTJPR0V4TkdZMU5HSTJPREJqWT JKa01HUmhNV1F4TlRsbVl6WXdNemhpTjJRd05RPT0ifSwidXNlcl9pZCI6IjEifQ.CRKNJw.OJL9399JCUzaUWoFBj 7sTjNI20s
  • 14. But what didn’t it see… •  Is that a real session, or an anonymous one? •  Is that session an actual, valid value? •  Who if anyone is logged in? What’s their username!? •  Is that CSRF token real or bogus?
  • 15. What your WAF sees POST /accounts/login/?next=/ HTTP/1.1 Host: 1.0.0.6:8010 Content-Length: 125 Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Origin: http://1.0.0.6:8010 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36 Content-Type: application/x-www-form-urlencoded Referer: http://1.0.0.6:8010/accounts/login/?next=/ Accept-Encoding: gzip, deflate Accept-Language: en-GB,en-US;q=0.8,en;q=0.6 Cookie: __utma=162530492.1677577446.1442505958.1442505958.1442515406.2; __utmz=162530492.1442505958.1.1.utmcsr=(direct)|utmccn=(direct)| utmcmd=(none); _vulnerable_session=JlXcvMQ38Tx1fbTD3VIpomnZtRnn2QYB; remember_token=1| 317ae4390a37e7ac78bd4bfb083e6482e068cc9d9a1077ed23df1c3df92fbf1d0503ee435ab52fba09d4a4f53c469b9b938104ff5010bdf56d30b4e56dfd8c42; session=683be987ca49acd97e4097bd402e281830050593gAJKEwwxVkdB1YxC0yqiFn1xAVUHX2NzcmZ0X3ECWCgAAAA4MzI0YzYxMGViMGI4MTFlMGM3NGFkZDY5ZGJjZTYyZmYwMjI0YjI5cQ Nzh3EELg==; csrftoken=JmfbGeRGsWv3XGjdIEYjBUYDL4BcJsm3 referrer=http%3A%2F%2F1.0.0.6%3A8010%2F&csrfmiddlewaretoken=JmfbGeRGsWv3XGjdIEYjBUYDL4BcJsm3&username=james&password=12345678
  • 16. But what didn’t it see… •  That was a login a:empt, and not simply a POST •  How many 0mes did this user “james” a:empt logins? Is this the first, or the 101st? •  Was the login successful, or not? •  Has “james” logged in from different IPs? What region did these logins occur from? Was “james” using a Tor node? •  Lets take a real app h:ps://github.com/miguelgrinberg/microblog
  • 17. What your WAF sees POST / HTTP/1.1 Host: 1.0.0.6:5000 Content-Length: 102 Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Origin: http://1.0.0.6:5000 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36 Content-Type: application/x-www-form-urlencoded Referer: http://1.0.0.6:5000/ Accept-Encoding: gzip, deflate Accept-Language: en-GB,en-US;q=0.8,en;q=0.6 Cookie: __utma=162530492.1677577446.1442505958.1442505958.1442515406.2; __utmz=162530492.1442505958.1.1.utmcsr=(direct)| utmccn=(direct)|utmcmd=(none); _vulnerable_session=JlXcvMQ38Tx1fbTD3VIpomnZtRnn2QYB; csrftoken=JmfbGeRGsWv3XGjdIEYjBUYDL4BcJsm3; remember_token=1| 317ae4390a37e7ac78bd4bfb083e6482e068cc9d9a1077ed23df1c3df92fbf1d0503ee435ab52fba09d4a4f53c469b9b938104ff5010bdf56d30b4e56df d8c42; session=eyJfZnJlc2giOmZhbHNlLCJjc3JmX3Rva2VuIjp7IiBiIjoiTW1JNFpXUTJPR0V4TkdZMU5HSTJPREJqWTJKa01HUmhNV1F4TlRsbVl6WXdNemhpTjJ Rd05RPT0ifSwidXNlcl9pZCI6IjEifQ.CRKNZw.22a8XCyVPcy5nYrf6LM4wcIwagQ csrf_token=1446054390.9%23%23d6030368991a5da453071f0747682fe2d01dcbef&post=%3CH1%3EHackfest%3C%2FH1%3E
  • 18. What a RASP sees instead…the real jinja2 template From: h:ps://github.com/miguelgrinberg/microblog/blob/master/app/templates/post.html <table class="table table-hover"> {% autoescape false %} <tr> <td width="70px"><a href="{{ url_for('user', nickname=post.author.nickname) }}"><img src="{{ post.author.avatar(70) }}" /></a></td> <td> <p>{{ _('%(nickname)s said %(when)s:', nickname='<a href="%s">%s</a>' % (url_for('user', nickname=post.author.nickname), post.author.nickname), when=momentjs(post.0mestamp).fromNow()) }}</p> <p><strong><span id="post{{ post.id }}">{{ post.body }}</span></strong></p> {% if post.language != None and post.language != '' and post.language != g.locale %} <div> <span id="transla0on{{ post.id }}"> <a href="javascript:translate('{{ post.language }}', '{{ g.locale }}', '#post{{ post.id }}', '#transla0on{{ post.id }}', '#loading{{ post.id }}');">{{ _('Translate') }}</a> </span> <img id="loading{{ post.id }}" style="display: none" src="/sta0c/img/loading.gif"> </div> {% endif %} {% if post.author.id == g.user.id %} <div><a href="{{ url_for('delete', id = post.id) }}">{{ _('Delete') }}</a></div> {% endif %} </td> </tr> {% endautoescape %} </table>
  • 19. Which do you think stands the best chance of catching you…
  • 20. Which do you think stands the best chance of catching you… •  Even IFF a WAF had world-class unbeatable string parsing with no false posi0ves for any language for any scenario such that it blocks •  =%3CH1%3EHackfest%3C%2FH1%3E •  That’s it? So if the a:ack payload doesn’t come via a request we lose? We tell developers to call the ESAPI the right way in the right place? •  RASPs here really shine. Not only could they block at the request level, but what they can do, is take care of encoding since they have all the informa0on needed. •  No developer interven0on, no code changes, no more XSS.
  • 21. If we try our typical <script>alert(0)</script> •  RASP encoding enabled, results with this page in your browser. No API calls: <p><a href="/user/IMMUNIO">IMMUNIO</a> said <script> document.write(moment("2015-10-28T19:11:07 Z").fromNow()); </script>:</p> <p><strong><span id="post1">&lt;script&gt;alert(0)&lt;&#47;script&gt;</span></ strong></p> •  Turning off RASP encoding, results are as expected: <p><a href="/user/IMMUNIO">IMMUNIO</a> said <script> document.write(moment("2015-10-28T19:11:07 Z").fromNow()); </script>:</p> <p><strong><span id="post1"><script>alert(0)</script></ span></strong></p>
  • 22. Agents are great, but we can do more! •  We’ve seen low-level hooks for files and html, and we’ve seen how this gives a RASP powerful protec0on for file access and cross-site scrip0ng. •  But what if agents added smarts so that ac0ons can be taken on the meta-informa0on? •  Lets go back to “james” logging into the app…
  • 23. What your WAF sees POST /accounts/login/?next=/ HTTP/1.1 Host: 1.0.0.6:8010 Content-Length: 125 Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Origin: http://1.0.0.6:8010 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36 Content-Type: application/x-www-form-urlencoded Referer: http://1.0.0.6:8010/accounts/login/?next=/ Accept-Encoding: gzip, deflate Accept-Language: en-GB,en-US;q=0.8,en;q=0.6 Cookie: __utma=162530492.1677577446.1442505958.1442505958.1442515406.2; __utmz=162530492.1442505958.1.1.utmcsr=(direct)|utmccn=(direct)| utmcmd=(none); _vulnerable_session=JlXcvMQ38Tx1fbTD3VIpomnZtRnn2QYB; remember_token=1| 317ae4390a37e7ac78bd4bfb083e6482e068cc9d9a1077ed23df1c3df92fbf1d0503ee435ab52fba09d4a4f53c469b9b938104ff5010bdf56d30b4e56dfd8c42; session=683be987ca49acd97e4097bd402e281830050593gAJKEwwxVkdB1YxC0yqiFn1xAVUHX2NzcmZ0X3ECWCgAAAA4MzI0YzYxMGViMGI4MTFlMGM3NGFkZDY5ZGJjZTYyZmYwMjI0YjI5cQ Nzh3EELg==; csrftoken=JmfbGeRGsWv3XGjdIEYjBUYDL4BcJsm3 referrer=http%3A%2F%2F1.0.0.6%3A8010%2F&csrfmiddlewaretoken=JmfbGeRGsWv3XGjdIEYjBUYDL4BcJsm3&username=james&password=12345678
  • 24. Aggrega;ng agent informa;on •  I touched upon this earlier, detec0ng if “james” is logging in from all over the world. Here, a RASP can provide benefits above and beyond anything today’s WAFs can do. •  When does a RASP call home? •  What informa0on does a RASP send home? •  Anything sensi0ve? The RASP vendor must be trustworthy
  • 25. Aggrega;ng agent informa;on •  RASPs need to know more than the traffic they are seeing!
  • 26. Aggrega;ng agent informa;on •  An agent can’t do much outside of its instance, if the server has more than one instance this is problema0c. (We already saw that a WAF doesn’t even know who “james” is) •  In our diagram, all a RASP sees is “james” logging in from 1.1.1.1, and this is fine from a RASPs point of view. •  In our diagram, if we run 100 instances, and “james” fails to log into 100 of them, this is fine from a RASPs point of view; each agent sees but one failed login. •  This is shit
  • 27. Aggrega;ng agent informa;on •  Solu0on, send “interes0ng” events to a backend. •  In the backend, something can spot what really happened! •  User account “james” failed to login 100 0mes in 5 seconds, lets do something! •  In comes a:ack mi0ga0on, captchas or delays whatever. •  This is not WAF specific or a RASP-only feature, this is web security done right.
  • 28. Actual example •  Lets take the latest Acune0x •  And lets scan an applica0on with, and then without a RASP •  First “shootout”, open source Python h:ps://github.com/Pylons/shootout •  Turn on RASP with full blocking/mi0ga0on •  A{er one minute you will see this
  • 29. Actual example – Fully protected
  • 30. Actual example •  Turns out that was too easy, the RASP immediately spo:ed requests from Acune0x, and blocked them. So turns out, if we want to have a meaningful comparison, we need to dumb-down the RASP… •  Turn off Acune0x detec0on, and re-scan just as before •  This 0me it takes 6 minutes and results in 16 thousand requests, as opposed to the 6000 requests blocked in the previous scan. •  So with more of the applica0on visible to Acune0x, it can run its magic in some more places and we can see SQLi a:empts, as well as File access a:empts, on shootout.
  • 31. Actual example – Disable Acune;x Detec;on
  • 32. Actual example •  OK, but this 0me lets redo the same exercise using an applica0on with all sorts of vulnerabili0es. •  This is such an app, it’s in ruby, and it has pre:y much everything wrong with it. •  So again, same scanner sePngs for both scans, same login, first with every mi0ga0on and blocking feature enabled…
  • 33. Actual example – Fully protected
  • 34. Actual example – Not protected
  • 35. Actual example – Not protected •  There are big differences. •  27 more alerts without RASP protec0ng web applica0on •  Plus this blind remote code execu0on GET /file/popen?filter=&nslookup {domain}&'"`0&nslookup {domain}&`' HTTP/1.1 Host: 1.0.0.6:8082 Generated by this request: ["ls -l | grep '&nslookup dns.ce.006796.15-5.15.26c7a.1.bxss.me&'"`0&nslookup dns.ce.006796.15-5.15.26c7a. 1.bxss.me&`'';"] •  URL Redirec0on •  XSS •  Directory Traversal •  Login page password-guessing a:ack
  • 36. Login page password-guessing aXack •  Interes0ng, what did it do there… •  Lets go try to login a{er the scan is complete
  • 37. Login page password-guessing aXack •  As I men0oned when we discussed cross-site scrip0ng, •  Detec0ng and aler0ng is good… •  Blocking is terrific… •  But as with XSS, when the RASP properly encoded for us the dynamic inputs, here it detected 10 failed logins as performed by Acune0x (using “sample@email.tst” when it runs its script to check for the “Login page password-guessing a:ack”), and the RASP flagged the client IP as bad and redirected to a Google CAPTCHA. •  And that, as with XSS, without a single code change or new API call by a developer!
  • 38. Final note on F+’s •  RASP and WAFs will have F+ •  Meaning they will both require whitelis0ng •  So are you telling me a RASP whitelist “one-ups” a WAF whitelist? •  Oh yes…lets spot the pa:ern
  • 43. RASP in a SDLC? •  We saw that the informa0on available for whitelis0ng a XSS alert in a RASP is very detailed, and specific. •  What if in addi0on to a site administrator, a developer was able to see this data? Why not!
  • 44. RASP in a SDLC, sure! •  Given the following exposed jinja2 code
  • 45. RASP in a SDLC, sure! •  We can provide XSS details so precise, a developer can benefit !!
  • 46. Links •  LUA : h:p://www.lua.org/about.html •  LUPA : h:ps://pypi.python.org/pypi/lupa •  LUAJIT: h:p://luajit.org/ •  RASP: h:ps://docs.immun.io/ •  RASP Ar0cle: h:p://www.networkworld.com/ar0cle/2365739/security0/will- perimeter-firewalls-give-way-to-rasp.html •  Monkey patching: h:ps://en.wikipedia.org/wiki/Monkey_patch