# MediaChunks

chunk_id: 162_chunk_15
chunk_text:
that is often missed 709.25s - 711.33s | is the provider's responsibility 711.33s - 714.57s | in how they encourage these insecure defaults. 715.33s - 718.85s | So for example, tokens are really, really easy to use. 718.85s - 721.03s | Have you ever thought about how easy it is 721.03s - 723.19s | to use a token in your code? 723.19s - 726.41s | And that's how it can get leaked in the first place. 726.41s - 728.49s | Now, Fortune 500 companies might have 728.49s - 731.51s | those standard secure development lifecycle practices 731.51s - 732.97s | where they can avoid this, 732.97s - 736.53s | but in reality, a lot of small to medium-sized businesses 736.53s - 738.17s | might not understand this nuance 738.17s - 744.09s | or be able to apply it uniform across their organization. 744.09s - 746.53s | Now, this is something we're gonna talk about later, 747.21s - 748.77s | but I want you to keep it in mind. 748.77s - 752.69s | Remember, even though it's a cloud customer vulnerability, 752.69s - 754.45s | there's incentives that lead to them 754.45s - 756.09s | being created in the first place. 757.21s - 759.85s | So let's talk about the traditional security mindset. 761.01s - 763.65s | Traditional bugs discovery is often centered 763.65s - 765.33s | around a specific target. 765.33s - 766.85s | You know, if I'm looking for vulnerabilities, 766.85s - 769.25s | I might go reverse engineer an application, 769.25s - 771.17s | and with dangling domains, 771.17s - 774.37s | one of the earliest approaches was going first, 774.37s - 776.65s | enumerating the subdomains of my target, 776.65s - 779.29s | and then enumerating the cloud provider IP pools 779.29s - 782.05s | in order to identify dangling resources. 782.05s - 785.39s | Now, for secrets, again, we start with a specific target, 785.39s - 787.29s | whether that be a single repository 787.29s - 789.45s | or a single platform like GitHub. 790.45s - 792.21s | And what I really started to think about 792.21s - 794.29s | as I looked into this further and further 794.29s - 795.97s | was whether there's an opportunity 795.97s - 799.13s | for some vulnerabilities to be approached differently. 799.13s - 802.99s | For example, were we really facing tunnel vision here? 802.99s - 805.71s | Why


chunk_id: 162_chunk_16
chunk_text:
757.21s - 759.85s | So let's talk about the traditional security mindset. 761.01s - 763.65s | Traditional bugs discovery is often centered 763.65s - 765.33s | around a specific target. 765.33s - 766.85s | You know, if I'm looking for vulnerabilities, 766.85s - 769.25s | I might go reverse engineer an application, 769.25s - 771.17s | and with dangling domains, 771.17s - 774.37s | one of the earliest approaches was going first, 774.37s - 776.65s | enumerating the subdomains of my target, 776.65s - 779.29s | and then enumerating the cloud provider IP pools 779.29s - 782.05s | in order to identify dangling resources. 782.05s - 785.39s | Now, for secrets, again, we start with a specific target, 785.39s - 787.29s | whether that be a single repository 787.29s - 789.45s | or a single platform like GitHub. 790.45s - 792.21s | And what I really started to think about 792.21s - 794.29s | as I looked into this further and further 794.29s - 795.97s | was whether there's an opportunity 795.97s - 799.13s | for some vulnerabilities to be approached differently. 799.13s - 802.99s | For example, were we really facing tunnel vision here? 802.99s - 805.71s | Why do we need to start with a specific target? 806.55s - 808.27s | It's almost as if, you know, 808.27s - 809.95s | there is a lack of focus in the industry 809.95s - 811.71s | against finding bugs at scale, 811.71s - 814.87s | and rather finding bugs in individual areas. 814.87s - 816.55s | And that's what I really wanted to focus on 816.55s - 817.81s | with this research is, 817.81s - 820.81s | can we find these vulnerabilities at scale? 821.97s - 824.47s | So to expand on this, with dangling resources, 824.47s - 827.35s | the traditional mindset might include start with a target 827.35s - 829.39s | and then capture vulnerable assets. 829.39s - 831.31s | But as we've seen with past work, 831.31s - 834.07s | it can often be a lot larger than that too. 834.07s - 836.03s | For example, the security at scale approach 836.03s - 837.11s | to dangling domains would be 837.11s - 840.03s | to capture dangling assets first, 840.03s - 842.23s | and then check if there's any DNS records 842.23s - 845.65s | still pointing at them using passive DNS replication data. 846.55s - 848.71s


chunk_id: 162_chunk_17
chunk_text:
do we need to start with a specific target? 806.55s - 808.27s | It's almost as if, you know, 808.27s - 809.95s | there is a lack of focus in the industry 809.95s - 811.71s | against finding bugs at scale, 811.71s - 814.87s | and rather finding bugs in individual areas. 814.87s - 816.55s | And that's what I really wanted to focus on 816.55s - 817.81s | with this research is, 817.81s - 820.81s | can we find these vulnerabilities at scale? 821.97s - 824.47s | So to expand on this, with dangling resources, 824.47s - 827.35s | the traditional mindset might include start with a target 827.35s - 829.39s | and then capture vulnerable assets. 829.39s - 831.31s | But as we've seen with past work, 831.31s - 834.07s | it can often be a lot larger than that too. 834.07s - 836.03s | For example, the security at scale approach 836.03s - 837.11s | to dangling domains would be 837.11s - 840.03s | to capture dangling assets first, 840.03s - 842.23s | and then check if there's any DNS records 842.23s - 845.65s | still pointing at them using passive DNS replication data. 846.55s - 848.71s | Now, here's where it gets interesting. 848.71s - 851.21s | For leak secrets, there's no such equivalent. 852.03s - 855.27s | You know, we have approaches to scan limited scopes 855.27s - 856.93s | for these secret patterns, 856.93s - 860.55s | but when it comes to that security at scale mindset, 860.55s - 863.99s | it still goes around a very limited target. 863.99s - 867.95s | You know, we start with a repository, a folder, a file, 867.95s - 870.27s | instead of starting with a diverse data source 870.27s - 877.64s | that allows us to look for these secrets in a broad manner. 877.64s - 879.88s | So this is what I really want you to take away 879.88s - 881.40s | from this talk from a high level, 881.40s - 883.12s | is that there's an untapped potential 883.12s - 885.38s | to use unconventional data sources 885.38s - 887.36s | to find these vulnerabilities. 887.36s - 888.90s | We're about to go through some examples, 888.90s - 890.74s | but what I really want you to think about 890.74s - 891.96s | is not just, you know, 891.96s - 894.36s | here's how


chunk_id: 162_chunk_18
chunk_text:
| Now, here's where it gets interesting. 848.71s - 851.21s | For leak secrets, there's no such equivalent. 852.03s - 855.27s | You know, we have approaches to scan limited scopes 855.27s - 856.93s | for these secret patterns, 856.93s - 860.55s | but when it comes to that security at scale mindset, 860.55s - 863.99s | it still goes around a very limited target. 863.99s - 867.95s | You know, we start with a repository, a folder, a file, 867.95s - 870.27s | instead of starting with a diverse data source 870.27s - 877.64s | that allows us to look for these secrets in a broad manner. 877.64s - 879.88s | So this is what I really want you to take away 879.88s - 881.40s | from this talk from a high level, 881.40s - 883.12s | is that there's an untapped potential 883.12s - 885.38s | to use unconventional data sources 885.38s - 887.36s | to find these vulnerabilities. 887.36s - 888.90s | We're about to go through some examples, 888.90s - 890.74s | but what I really want you to think about 890.74s - 891.96s | is not just, you know, 891.96s - 894.36s | here's how Bill applied it to dangling domains 895.08s - 895.92s | and leak secrets, 895.92s - 897.12s | but rather how you can apply it 897.12s - 899.92s | to other types of vulnerability classes as well. 899.92s - 902.56s | This is not just about these two vulnerability classes. 902.56s - 904.60s | These two vulnerability classes are examples 904.60s - 908.58s | that you can apply to your own work. 908.58s - 910.90s | So let's talk about how we would actually implement this 910.90s - 912.62s | in practice. 912.62s - 913.50s | From a high level, 913.50s - 916.66s | we start with the vulnerability, not the target. 916.66s - 918.10s | So, and then we work backwards 918.10s - 920.50s | by using creative data sources. 920.50s - 922.42s | Remember, for dangling resources, 922.42s - 924.18s | we already have a playbook. 924.66s - 927.10s | You know a DNS record is dangling 927.10s - 928.66s | if it points at an IP address 928.66s - 931.26s | that the customer no longer controls. 931.26s - 933.88s | How do you know if an IP is no longer controlled 933.88s - 934.94s | by a


chunk_id: 162_chunk_19
chunk_text:
Bill applied it to dangling domains 895.08s - 895.92s | and leak secrets, 895.92s - 897.12s | but rather how you can apply it 897.12s - 899.92s | to other types of vulnerability classes as well. 899.92s - 902.56s | This is not just about these two vulnerability classes. 902.56s - 904.60s | These two vulnerability classes are examples 904.60s - 908.58s | that you can apply to your own work. 908.58s - 910.90s | So let's talk about how we would actually implement this 910.90s - 912.62s | in practice. 912.62s - 913.50s | From a high level, 913.50s - 916.66s | we start with the vulnerability, not the target. 916.66s - 918.10s | So, and then we work backwards 918.10s - 920.50s | by using creative data sources. 920.50s - 922.42s | Remember, for dangling resources, 922.42s - 924.18s | we already have a playbook. 924.66s - 927.10s | You know a DNS record is dangling 927.10s - 928.66s | if it points at an IP address 928.66s - 931.26s | that the customer no longer controls. 931.26s - 933.88s | How do you know if an IP is no longer controlled 933.88s - 934.94s | by a customer? 934.94s - 936.98s | Well, we can enumerate the cloud IP pool 936.98s - 940.42s | and determine every IP that we get in our attacker account 940.42s - 942.86s | is likely something that no other customer controls 942.86s - 945.42s | because that IP is assigned to us. 945.42s - 946.94s | But how do we know if it's dangling? 946.94s - 949.82s | Well, again, that passive DNS replication data. 949.82s - 951.00s | And if you're not familiar with this, 951.00s - 953.78s | how it works is that threat intelligence providers 954.46s - 956.26s | will work with DNS providers 956.26s - 960.14s | to sell this aggregate DNS traffic data. 960.14s - 963.14s | For example, you can give these threat intel providers 963.14s - 965.14s | an IP address and they'll give you 965.14s - 969.84s | every single DNS record that points at it. 969.84s - 973.52s | Now, again, we can capture assets first with DNS records 973.52s - 975.60s | instead of starting with a target. 975.60s - 978.48s | What we'll do is we'll go through a cloud provider pool 978.48s - 981.14s | and we'll go and


chunk_id: 162_chunk_20
chunk_text:
customer? 934.94s - 936.98s | Well, we can enumerate the cloud IP pool 936.98s - 940.42s | and determine every IP that we get in our attacker account 940.42s - 942.86s | is likely something that no other customer controls 942.86s - 945.42s | because that IP is assigned to us. 945.42s - 946.94s | But how do we know if it's dangling? 946.94s - 949.82s | Well, again, that passive DNS replication data. 949.82s - 951.00s | And if you're not familiar with this, 951.00s - 953.78s | how it works is that threat intelligence providers 954.46s - 956.26s | will work with DNS providers 956.26s - 960.14s | to sell this aggregate DNS traffic data. 960.14s - 963.14s | For example, you can give these threat intel providers 963.14s - 965.14s | an IP address and they'll give you 965.14s - 969.84s | every single DNS record that points at it. 969.84s - 973.52s | Now, again, we can capture assets first with DNS records 973.52s - 975.60s | instead of starting with a target. 975.60s - 978.48s | What we'll do is we'll go through a cloud provider pool 978.48s - 981.14s | and we'll go and enumerate every IP address 981.14s - 982.28s | that we're able to get 982.28s - 985.16s | and look for DNS records that point at it. 985.20s - 986.60s | What we're gonna do in the next section 986.60s - 989.76s | is apply this generic technique we've seen in past work 989.76s - 992.10s | against modern deterrence. 993.76s - 995.52s | But what about secret scanning? 995.52s - 996.68s | So this is the interesting one. 996.68s - 1001.10s | This is one that we still have a lot of research to do in. 1001.10s - 1003.12s | We have passive DNS replication data 1003.12s - 1007.04s | for dangling resources, but what about leaked secrets? 1007.04s - 1009.32s | From a high level, the ideal data source 1009.32s - 1012.56s | needs to be diverse, needs to be sufficient in volume, 1012.60s - 1017.28s | and it needs to include a diverse set of websites, 1017.28s - 1020.68s | executables, not just open source applications, 1020.68s - 1024.36s | but we need to include closed source applications too. 1024.36s - 1026.16s | And we need to make sure that this is done 1026.16s - 1027.56s | in


chunk_id: 162_chunk_21
chunk_text:
enumerate every IP address 981.14s - 982.28s | that we're able to get 982.28s - 985.16s | and look for DNS records that point at it. 985.20s - 986.60s | What we're gonna do in the next section 986.60s - 989.76s | is apply this generic technique we've seen in past work 989.76s - 992.10s | against modern deterrence. 993.76s - 995.52s | But what about secret scanning? 995.52s - 996.68s | So this is the interesting one. 996.68s - 1001.10s | This is one that we still have a lot of research to do in. 1001.10s - 1003.12s | We have passive DNS replication data 1003.12s - 1007.04s | for dangling resources, but what about leaked secrets? 1007.04s - 1009.32s | From a high level, the ideal data source 1009.32s - 1012.56s | needs to be diverse, needs to be sufficient in volume, 1012.60s - 1017.28s | and it needs to include a diverse set of websites, 1017.28s - 1020.68s | executables, not just open source applications, 1020.68s - 1024.36s | but we need to include closed source applications too. 1024.36s - 1026.16s | And we need to make sure that this is done 1026.16s - 1027.56s | in a feasible way. 1027.56s - 1030.92s | For example, even if we have a large data set 1030.92s - 1033.56s | of these files, we need to make sure we can scan it 1033.56s - 1034.84s | in a practical manner. 1035.80s - 1038.00s | So where can we find this large collection 1038.00s - 1039.98s | of apps and scripts? 1039.98s - 1043.84s | So what about virus scanning platforms? 1045.38s - 1047.62s | This is where it's gonna get really interesting. 1047.62s - 1050.38s | So what we've seen with past work 1050.38s - 1053.30s | is a lot of people focusing on these platforms 1053.30s - 1055.38s | with limited diversity. 1055.38s - 1057.42s | You know, we look at GitHub, it's really gonna only be 1057.42s - 1060.18s | open source repositories that are being scanned 1060.18s - 1062.58s | and automatically revoking keys. 1062.58s - 1064.18s | You know, we look at these tools, 1064.18s - 1067.30s | they all focus on scanning individual targets 1067.30s - 1070.34s | like folders, specific repos, et cetera, 1070.34s - 1072.72s | but what we're missing is that diverse data source, 1072.72s - 1075.70s | and that's what


chunk_id: 162_chunk_22
chunk_text:
a feasible way. 1027.56s - 1030.92s | For example, even if we have a large data set 1030.92s - 1033.56s | of these files, we need to make sure we can scan it 1033.56s - 1034.84s | in a practical manner. 1035.80s - 1038.00s | So where can we find this large collection 1038.00s - 1039.98s | of apps and scripts? 1039.98s - 1043.84s | So what about virus scanning platforms? 1045.38s - 1047.62s | This is where it's gonna get really interesting. 1047.62s - 1050.38s | So what we've seen with past work 1050.38s - 1053.30s | is a lot of people focusing on these platforms 1053.30s - 1055.38s | with limited diversity. 1055.38s - 1057.42s | You know, we look at GitHub, it's really gonna only be 1057.42s - 1060.18s | open source repositories that are being scanned 1060.18s - 1062.58s | and automatically revoking keys. 1062.58s - 1064.18s | You know, we look at these tools, 1064.18s - 1067.30s | they all focus on scanning individual targets 1067.30s - 1070.34s | like folders, specific repos, et cetera, 1070.34s - 1072.72s | but what we're missing is that diverse data source, 1072.72s - 1075.70s | and that's what I really focused on in this research. 1075.70s - 1078.46s | What I found was that virus scanning platforms 1078.46s - 1080.72s | were actually a really interesting target 1080.72s - 1083.34s | because think about it, think about all the stuff 1083.34s - 1086.22s | that people upload to virus scanning platforms. 1086.22s - 1087.92s | You know, think about all the websites 1087.92s - 1090.50s | that are automatically scanned, all the applications, 1090.50s - 1092.84s | all the mobile apps that are included 1092.84s - 1094.98s | in this virus total data source, 1094.98s - 1096.88s | and as well as other platforms. 1097.94s - 1100.10s | Now, with these scanning platforms, 1100.10s - 1102.90s | it would be infeasible to go ahead and, you know, 1102.90s - 1105.82s | download what, a billion, nine billion files 1105.82s - 1108.18s | and scan each of them individually, 1108.18s - 1109.30s | but we don't need to do that 1109.30s - 1112.38s | because we can use the tools that they already provide us. 1112.38s - 1116.42s | Nearly every virus scanning platform lets you search 1116.42s - 1119.26s | for specific patterns, specific strings, 1119.26s - 1121.18s


chunk_id: 162_chunk_23
chunk_text:
I really focused on in this research. 1075.70s - 1078.46s | What I found was that virus scanning platforms 1078.46s - 1080.72s | were actually a really interesting target 1080.72s - 1083.34s | because think about it, think about all the stuff 1083.34s - 1086.22s | that people upload to virus scanning platforms. 1086.22s - 1087.92s | You know, think about all the websites 1087.92s - 1090.50s | that are automatically scanned, all the applications, 1090.50s - 1092.84s | all the mobile apps that are included 1092.84s - 1094.98s | in this virus total data source, 1094.98s - 1096.88s | and as well as other platforms. 1097.94s - 1100.10s | Now, with these scanning platforms, 1100.10s - 1102.90s | it would be infeasible to go ahead and, you know, 1102.90s - 1105.82s | download what, a billion, nine billion files 1105.82s - 1108.18s | and scan each of them individually, 1108.18s - 1109.30s | but we don't need to do that 1109.30s - 1112.38s | because we can use the tools that they already provide us. 1112.38s - 1116.42s | Nearly every virus scanning platform lets you search 1116.42s - 1119.26s | for specific patterns, specific strings, 1119.26s - 1121.18s | like they're literally spoon feeding us 1121.18s - 1122.86s | to perfect data source here. 1122.86s - 1125.50s | And traditionally, what we've used this data source for 1125.50s - 1128.90s | is to find malware, you know, find malicious use, et cetera, 1128.90s - 1131.30s | but what's really interesting about them is that 1131.30s - 1133.22s | what if we use secret patterns 1133.22s - 1135.34s | instead of malicious patterns? 1135.34s - 1136.98s | What if instead of looking for malware, 1136.98s - 1138.78s | we look for secrets instead? 1140.34s - 1142.20s | And with virus total, this is retro hunt, 1142.20s - 1143.44s | but seriously, if you look at 1143.44s - 1145.80s | nearly every other virus scanning platform, 1145.80s - 1149.46s | what you'll find is that they have a similar future, 1149.46s - 1151.06s | at least if you have an account. 1152.50s - 1157.64s | So let's apply this in practice. 1157.64s - 1160.88s | So with secret scanning, the plan is from a high level. 1160.88s - 1164.04s | We wanna make sure that we look for secret patterns. 1164.04s - 1165.44s | And what that really means is,


chunk_id: 162_chunk_24
chunk_text:
| like they're literally spoon feeding us 1121.18s - 1122.86s | to perfect data source here. 1122.86s - 1125.50s | And traditionally, what we've used this data source for 1125.50s - 1128.90s | is to find malware, you know, find malicious use, et cetera, 1128.90s - 1131.30s | but what's really interesting about them is that 1131.30s - 1133.22s | what if we use secret patterns 1133.22s - 1135.34s | instead of malicious patterns? 1135.34s - 1136.98s | What if instead of looking for malware, 1136.98s - 1138.78s | we look for secrets instead? 1140.34s - 1142.20s | And with virus total, this is retro hunt, 1142.20s - 1143.44s | but seriously, if you look at 1143.44s - 1145.80s | nearly every other virus scanning platform, 1145.80s - 1149.46s | what you'll find is that they have a similar future, 1149.46s - 1151.06s | at least if you have an account. 1152.50s - 1157.64s | So let's apply this in practice. 1157.64s - 1160.88s | So with secret scanning, the plan is from a high level. 1160.88s - 1164.04s | We wanna make sure that we look for secret patterns. 1164.04s - 1165.44s | And what that really means is, 1165.44s - 1168.48s | think about your AWS access key. 1168.48s - 1169.40s | I don't know if you've noticed, 1169.40s - 1172.36s | but it'll often start with A-K-I-A. 1172.36s - 1174.88s | And what we can do is we can create these regex strings 1174.88s - 1177.52s | for identifying these secrets, 1177.52s - 1180.24s | and we can look for them using the same tools 1180.24s - 1182.72s | we have available for malware hunting. 1182.72s - 1186.80s | So most virus platforms allow you to search by a Yara rule. 1186.80s - 1189.60s | And so what we can do is we can create a Yara rule 1189.60s - 1191.64s | for these secret patterns, 1191.64s - 1194.76s | and then we can search samples uploaded to the platform 1194.76s - 1197.64s | for whether these patterns exist in them. 1197.64s - 1200.00s | Now, one thing interesting that I did in this research 1200.00s - 1202.96s | was also focused on validating these secrets. 1202.96s - 1205.46s | So I've looked at a lot of past work into leaked secrets, 1205.46s - 1208.44s | and what I've found is there's a lot of theoretical research


chunk_id: 162_chunk_25
chunk_text:
1165.44s - 1168.48s | think about your AWS access key. 1168.48s - 1169.40s | I don't know if you've noticed, 1169.40s - 1172.36s | but it'll often start with A-K-I-A. 1172.36s - 1174.88s | And what we can do is we can create these regex strings 1174.88s - 1177.52s | for identifying these secrets, 1177.52s - 1180.24s | and we can look for them using the same tools 1180.24s - 1182.72s | we have available for malware hunting. 1182.72s - 1186.80s | So most virus platforms allow you to search by a Yara rule. 1186.80s - 1189.60s | And so what we can do is we can create a Yara rule 1189.60s - 1191.64s | for these secret patterns, 1191.64s - 1194.76s | and then we can search samples uploaded to the platform 1194.76s - 1197.64s | for whether these patterns exist in them. 1197.64s - 1200.00s | Now, one thing interesting that I did in this research 1200.00s - 1202.96s | was also focused on validating these secrets. 1202.96s - 1205.46s | So I've looked at a lot of past work into leaked secrets, 1205.46s - 1208.44s | and what I've found is there's a lot of theoretical research 1208.44s - 1210.12s | that discusses things like, 1210.12s - 1212.32s | oh, we looked for these secret patterns, 1212.32s - 1214.76s | and we found these unique keys, 1214.76s - 1216.48s | but you read into it a little deeper, 1217.16s - 1219.24s | and they didn't even check if those keys are legitimate. 1219.24s - 1221.48s | That's something that didn't really make sense to me. 1221.48s - 1223.32s | There's gonna be thousands and thousands 1223.32s - 1226.48s | and tens of thousands of keys that match a specific pattern 1226.48s - 1229.08s | but are not active in practice. 1229.08s - 1232.32s | And so what we did was that I used a platform 1232.32s - 1233.82s | to actually validate these keys, 1233.82s - 1235.36s | at least with basic metadata, 1235.36s - 1239.36s | and validate that they're legitimate for our use case. 1239.36s - 1241.68s | Now, some patterns are gonna be really noisy, 1241.68s - 1244.80s | but if the provider doesn't make it easy 1244.80s - 1246.56s | to identify their secrets, 1246.56s - 1248.04s | you're gonna find that you're gonna have to scan 1248.04s - 1251.00s | thousands and


chunk_id: 162_chunk_26
chunk_text:
1208.44s - 1210.12s | that discusses things like, 1210.12s - 1212.32s | oh, we looked for these secret patterns, 1212.32s - 1214.76s | and we found these unique keys, 1214.76s - 1216.48s | but you read into it a little deeper, 1217.16s - 1219.24s | and they didn't even check if those keys are legitimate. 1219.24s - 1221.48s | That's something that didn't really make sense to me. 1221.48s - 1223.32s | There's gonna be thousands and thousands 1223.32s - 1226.48s | and tens of thousands of keys that match a specific pattern 1226.48s - 1229.08s | but are not active in practice. 1229.08s - 1232.32s | And so what we did was that I used a platform 1232.32s - 1233.82s | to actually validate these keys, 1233.82s - 1235.36s | at least with basic metadata, 1235.36s - 1239.36s | and validate that they're legitimate for our use case. 1239.36s - 1241.68s | Now, some patterns are gonna be really noisy, 1241.68s - 1244.80s | but if the provider doesn't make it easy 1244.80s - 1246.56s | to identify their secrets, 1246.56s - 1248.04s | you're gonna find that you're gonna have to scan 1248.04s - 1251.00s | thousands and thousands of secret patterns 1251.00s - 1253.36s | in thousands of thousands of files. 1253.36s - 1255.98s | So how do we deal with this large volume? 1255.98s - 1257.88s | Well, what I did to do it on my budget, 1257.88s - 1260.20s | remember, I'm doing this everything out of pocket, 1260.20s - 1262.48s | was leverage serverless computing. 1262.48s - 1267.48s | So I needed a capacity of having several physical server racks 1267.60s - 1271.56s | but I don't have money to buy several physical server racks. 1271.56s - 1273.96s | Instead, I can rent them using the cloud, 1273.96s - 1277.64s | and what that really means is I made a serverless function 1277.64s - 1280.60s | in order to scan these files, 1280.60s - 1282.28s | and I also made a serverless function 1282.28s - 1284.86s | to validate the keys that were found. 1284.86s - 1287.84s | And this way, I don't actually have to pay that much 1287.84s - 1289.88s | because I only pay for what I use. 1289.88s - 1292.08s | In practice, my costs were actually 1292.08s - 1293.92s | fairly reasonable for an individual. 1295.44s - 1296.80s |


chunk_id: 162_chunk_27
chunk_text:
thousands of secret patterns 1251.00s - 1253.36s | in thousands of thousands of files. 1253.36s - 1255.98s | So how do we deal with this large volume? 1255.98s - 1257.88s | Well, what I did to do it on my budget, 1257.88s - 1260.20s | remember, I'm doing this everything out of pocket, 1260.20s - 1262.48s | was leverage serverless computing. 1262.48s - 1267.48s | So I needed a capacity of having several physical server racks 1267.60s - 1271.56s | but I don't have money to buy several physical server racks. 1271.56s - 1273.96s | Instead, I can rent them using the cloud, 1273.96s - 1277.64s | and what that really means is I made a serverless function 1277.64s - 1280.60s | in order to scan these files, 1280.60s - 1282.28s | and I also made a serverless function 1282.28s - 1284.86s | to validate the keys that were found. 1284.86s - 1287.84s | And this way, I don't actually have to pay that much 1287.84s - 1289.88s | because I only pay for what I use. 1289.88s - 1292.08s | In practice, my costs were actually 1292.08s - 1293.92s | fairly reasonable for an individual. 1295.44s - 1296.80s | Now, for dangling resources, 1296.80s - 1298.80s | again, the methodology from a high level 1298.80s - 1302.84s | was to reallocate resources over and over and over again. 1302.88s - 1304.28s | And then it was to cross-check them 1304.28s - 1307.00s | with passive DNS replication data. 1307.00s - 1309.38s | Remember, this isn't necessarily new, 1309.38s - 1312.46s | but what's interesting about them is that 1312.46s - 1315.88s | we're gonna be talking about bypassing modern deterrents. 1315.88s - 1317.90s | And what I mean by that is a lot of cloud providers 1317.90s - 1320.72s | have implemented these mitigations to make it harder 1320.72s - 1323.68s | to do this dangling DNS record enumeration, 1323.68s - 1327.04s | and we're gonna bypass them. 1327.04s - 1329.08s | So from a high level, 1329.08s - 1331.84s | one thing I wanna call out is that earlier no. 1331.84s - 1334.72s | Remember, it would appear that AWS began 1334.72s - 1339.08s | serving Elastic IPs from a small, specific pool 1339.08s - 1340.76s | similar to GCP. 1341.60s - 1345.12s | This severely limits the diversity of addresses received. 1345.12s - 1348.20s | And so


chunk_id: 162_chunk_28
chunk_text:
Now, for dangling resources, 1296.80s - 1298.80s | again, the methodology from a high level 1298.80s - 1302.84s | was to reallocate resources over and over and over again. 1302.88s - 1304.28s | And then it was to cross-check them 1304.28s - 1307.00s | with passive DNS replication data. 1307.00s - 1309.38s | Remember, this isn't necessarily new, 1309.38s - 1312.46s | but what's interesting about them is that 1312.46s - 1315.88s | we're gonna be talking about bypassing modern deterrents. 1315.88s - 1317.90s | And what I mean by that is a lot of cloud providers 1317.90s - 1320.72s | have implemented these mitigations to make it harder 1320.72s - 1323.68s | to do this dangling DNS record enumeration, 1323.68s - 1327.04s | and we're gonna bypass them. 1327.04s - 1329.08s | So from a high level, 1329.08s - 1331.84s | one thing I wanna call out is that earlier no. 1331.84s - 1334.72s | Remember, it would appear that AWS began 1334.72s - 1339.08s | serving Elastic IPs from a small, specific pool 1339.08s - 1340.76s | similar to GCP. 1341.60s - 1345.12s | This severely limits the diversity of addresses received. 1345.12s - 1348.20s | And so let me tell you what this really means in practice. 1348.20s - 1351.52s | So what's going on here is that AWS and GCP 1351.52s - 1354.96s | have a mitigation where when you are asked 1354.96s - 1357.00s | to assign me an IP address, 1357.00s - 1359.96s | whether that be an Elastic IP or in GCP case, 1359.96s - 1362.74s | nearly every resource that you can go ahead and allocate 1362.74s - 1364.24s | that needs an IP, 1364.24s - 1366.30s | these cloud providers will only give you 1366.30s - 1371.00s | a specific set of IPs assigned to a shared pool 1371.00s - 1374.40s | that's limited to your account and maybe a few others. 1374.40s - 1378.92s | And for AWS, this is gonna be largely Elastic IP sharing. 1378.92s - 1382.68s | So that means whenever you ask for a dedicated Elastic IP, 1382.68s - 1385.16s | you'll notice if you free an Elastic IP 1385.16s - 1386.32s | and allocate another one, 1386.32s - 1388.64s | you're gonna be assigned the same one over and over again, 1388.64s - 1389.70s | or in general. 1390.44s - 1391.66s | It's really hard


chunk_id: 162_chunk_29
chunk_text:
let me tell you what this really means in practice. 1348.20s - 1351.52s | So what's going on here is that AWS and GCP 1351.52s - 1354.96s | have a mitigation where when you are asked 1354.96s - 1357.00s | to assign me an IP address, 1357.00s - 1359.96s | whether that be an Elastic IP or in GCP case, 1359.96s - 1362.74s | nearly every resource that you can go ahead and allocate 1362.74s - 1364.24s | that needs an IP, 1364.24s - 1366.30s | these cloud providers will only give you 1366.30s - 1371.00s | a specific set of IPs assigned to a shared pool 1371.00s - 1374.40s | that's limited to your account and maybe a few others. 1374.40s - 1378.92s | And for AWS, this is gonna be largely Elastic IP sharing. 1378.92s - 1382.68s | So that means whenever you ask for a dedicated Elastic IP, 1382.68s - 1385.16s | you'll notice if you free an Elastic IP 1385.16s - 1386.32s | and allocate another one, 1386.32s - 1388.64s | you're gonna be assigned the same one over and over again, 1388.64s - 1389.70s | or in general. 1390.44s - 1391.66s | It's really hard to actually enumerate that pool 1391.66s - 1393.28s | using Elastic IPs alone. 1394.52s - 1397.98s | Now with AWS, they also introduced a mitigation. 1397.98s - 1399.10s | I don't know if it's intentionally 1399.10s - 1401.50s | to go against dangling DNS enumeration, 1401.50s - 1404.42s | but they did introduce a mitigation in 2024 1404.42s - 1406.58s | where every IP address you received 1406.58s - 1410.02s | was actually had an increased surcharge. 1410.02s - 1413.46s | So now every IP you got allocated costs you extra money. 1413.46s - 1416.54s | And this deters attacks by making it more expensive 1416.54s - 1418.62s | to enumerate their public IP pools 1418.62s - 1423.50s | and capture these dangling DNS records. 1423.50s - 1425.58s | Now for Google Cloud, it's interesting. 1425.58s - 1428.14s | They actually had quite a lot more than I expected. 1428.14s - 1430.02s | So for project levels, 1430.02s - 1433.62s | so every account can have about 10 to 15 projects 1433.62s - 1434.78s | assigned to them. 1434.78s - 1436.58s | By default, you can request an increase, 1436.58s - 1438.20s | but you need justification. 1438.20s - 1442.50s


chunk_id: 162_chunk_30
chunk_text:
to actually enumerate that pool 1391.66s - 1393.28s | using Elastic IPs alone. 1394.52s - 1397.98s | Now with AWS, they also introduced a mitigation. 1397.98s - 1399.10s | I don't know if it's intentionally 1399.10s - 1401.50s | to go against dangling DNS enumeration, 1401.50s - 1404.42s | but they did introduce a mitigation in 2024 1404.42s - 1406.58s | where every IP address you received 1406.58s - 1410.02s | was actually had an increased surcharge. 1410.02s - 1413.46s | So now every IP you got allocated costs you extra money. 1413.46s - 1416.54s | And this deters attacks by making it more expensive 1416.54s - 1418.62s | to enumerate their public IP pools 1418.62s - 1423.50s | and capture these dangling DNS records. 1423.50s - 1425.58s | Now for Google Cloud, it's interesting. 1425.58s - 1428.14s | They actually had quite a lot more than I expected. 1428.14s - 1430.02s | So for project levels, 1430.02s - 1433.62s | so every account can have about 10 to 15 projects 1433.62s - 1434.78s | assigned to them. 1434.78s - 1436.58s | By default, you can request an increase, 1436.58s - 1438.20s | but you need justification. 1438.20s - 1442.50s | Now IPs are again assigned from a small pool just like AWS. 1442.50s - 1445.26s | You only have eight IPs you can use by default 1445.26s - 1446.86s | in per region and globally. 1447.74s - 1449.34s | And with these accounts, 1449.34s - 1452.42s | you also had something called a billing account restriction. 1452.42s - 1454.06s | So with Google Cloud, 1454.06s - 1457.54s | every credit card can be created into a billing account. 1457.54s - 1459.18s | Now you can create a few billing accounts 1459.18s - 1460.88s | based off of one credit card, 1460.88s - 1462.78s | but if you try to create more than a few, 1462.78s - 1465.06s | you'll automatically hit their suspension 1465.06s - 1466.42s | and you'll have to go justify 1466.42s - 1469.94s | why are you creating a 50th credit card account 1469.94s - 1472.14s | or billing account with one credit card. 1472.14s - 1475.30s | And so all these deterrents really make it difficult 1475.30s - 1478.38s | for attackers to enumerate these dangling domains. 1478.38s - 1480.02s | In fact, with Google Cloud, 1480.02s - 1482.74s | while managed DNS enumeration was


chunk_id: 162_chunk_31
chunk_text:
| Now IPs are again assigned from a small pool just like AWS. 1442.50s - 1445.26s | You only have eight IPs you can use by default 1445.26s - 1446.86s | in per region and globally. 1447.74s - 1449.34s | And with these accounts, 1449.34s - 1452.42s | you also had something called a billing account restriction. 1452.42s - 1454.06s | So with Google Cloud, 1454.06s - 1457.54s | every credit card can be created into a billing account. 1457.54s - 1459.18s | Now you can create a few billing accounts 1459.18s - 1460.88s | based off of one credit card, 1460.88s - 1462.78s | but if you try to create more than a few, 1462.78s - 1465.06s | you'll automatically hit their suspension 1465.06s - 1466.42s | and you'll have to go justify 1466.42s - 1469.94s | why are you creating a 50th credit card account 1469.94s - 1472.14s | or billing account with one credit card. 1472.14s - 1475.30s | And so all these deterrents really make it difficult 1475.30s - 1478.38s | for attackers to enumerate these dangling domains. 1478.38s - 1480.02s | In fact, with Google Cloud, 1480.02s - 1482.74s | while managed DNS enumeration was always a thing 1482.74s - 1484.60s | and has been for the past few years, 1484.60s - 1486.78s | attackers haven't been able to enumerate 1486.78s - 1490.50s | Google Cloud's public IP pools for quite some time, 1490.50s - 1495.16s | at least none researched that I could find online. 1495.16s - 1497.26s | So with those AWS mitigations, 1497.26s - 1499.14s | they're actually pretty simple to bypass. 1499.14s - 1500.98s | Instead of allocating elastic IPs, 1500.98s - 1505.26s | we can just restart EC2 instances with ephemeral IPs 1505.26s - 1508.10s | and we can perform the enumeration by just restarting, 1508.66s - 1513.66s | restarting, and my IP address that my EC2 instances assigned 1514.06s - 1518.02s | will generally rotate a lot faster through unique IPs 1518.02s - 1520.98s | than if you tried with elastic IPs. 1520.98s - 1523.30s | In fact, I actually was able to enumerate 1523.30s - 1526.26s | nearly 2.4 million unique IP addresses 1526.26s - 1529.62s | in a span of six months by using this methodology. 1530.50s - 1532.26s | Now with Google Cloud, again, 1532.26s - 1535.18s | they had a harder set of mitigations, 1535.18s


chunk_id: 162_chunk_32
chunk_text:
always a thing 1482.74s - 1484.60s | and has been for the past few years, 1484.60s - 1486.78s | attackers haven't been able to enumerate 1486.78s - 1490.50s | Google Cloud's public IP pools for quite some time, 1490.50s - 1495.16s | at least none researched that I could find online. 1495.16s - 1497.26s | So with those AWS mitigations, 1497.26s - 1499.14s | they're actually pretty simple to bypass. 1499.14s - 1500.98s | Instead of allocating elastic IPs, 1500.98s - 1505.26s | we can just restart EC2 instances with ephemeral IPs 1505.26s - 1508.10s | and we can perform the enumeration by just restarting, 1508.66s - 1513.66s | restarting, and my IP address that my EC2 instances assigned 1514.06s - 1518.02s | will generally rotate a lot faster through unique IPs 1518.02s - 1520.98s | than if you tried with elastic IPs. 1520.98s - 1523.30s | In fact, I actually was able to enumerate 1523.30s - 1526.26s | nearly 2.4 million unique IP addresses 1526.26s - 1529.62s | in a span of six months by using this methodology. 1530.50s - 1532.26s | Now with Google Cloud, again, 1532.26s - 1535.18s | they had a harder set of mitigations, 1535.18s - 1538.50s | but those mitigations were deterrence. 1538.50s - 1541.78s | So how it worked was that I used a backend bucket 1541.78s - 1544.54s | with a load balancer in order to assign IP addresses 1544.54s - 1545.78s | to my resources. 1545.78s - 1547.74s | But this still didn't let me get past 1547.74s - 1549.62s | these cloud resource restrictions. 1549.62s - 1551.14s | How do we do that? 1551.14s - 1553.10s | Well, once we have this primitive 1553.10s - 1555.16s | for enumerating cloud IPs, 1555.16s - 1557.16s | we can talk about those limitations. 1557.16s - 1559.62s | But for high level information, 1559.62s - 1562.46s | where we used forwarding rules instead of virtual machines 1562.46s - 1564.42s | in order to enumerate these IPs. 1566.10s - 1569.18s | So with Google Cloud, remember all those restrictions? 1569.18s - 1572.02s | Well, we can actually bypass all of them fairly cheaply. 1572.86s - 1575.18s | So number one, with a billing account, 1575.18s - 1576.38s | one interesting thing I found 1576.38s - 1577.98s | was that you can assign billing accounts 1577.98s - 1579.74s | across Google accounts. 1579.74s - 1580.94s


chunk_id: 162_chunk_33
chunk_text:
- 1538.50s | but those mitigations were deterrence. 1538.50s - 1541.78s | So how it worked was that I used a backend bucket 1541.78s - 1544.54s | with a load balancer in order to assign IP addresses 1544.54s - 1545.78s | to my resources. 1545.78s - 1547.74s | But this still didn't let me get past 1547.74s - 1549.62s | these cloud resource restrictions. 1549.62s - 1551.14s | How do we do that? 1551.14s - 1553.10s | Well, once we have this primitive 1553.10s - 1555.16s | for enumerating cloud IPs, 1555.16s - 1557.16s | we can talk about those limitations. 1557.16s - 1559.62s | But for high level information, 1559.62s - 1562.46s | where we used forwarding rules instead of virtual machines 1562.46s - 1564.42s | in order to enumerate these IPs. 1566.10s - 1569.18s | So with Google Cloud, remember all those restrictions? 1569.18s - 1572.02s | Well, we can actually bypass all of them fairly cheaply. 1572.86s - 1575.18s | So number one, with a billing account, 1575.18s - 1576.38s | one interesting thing I found 1576.38s - 1577.98s | was that you can assign billing accounts 1577.98s - 1579.74s | across Google accounts. 1579.74s - 1580.94s | This was a useful primitive 1580.94s - 1583.62s | where if I could create a billing account in one account, 1583.62s - 1585.88s | I can actually assign it across several accounts. 1585.88s - 1587.94s | And the reason this is interesting is, 1587.94s - 1589.96s | well, what about those quotas? 1589.96s - 1591.50s | Well, with account quotas, 1591.50s - 1594.06s | remember you can only create a certain amount of projects. 1594.06s - 1596.54s | Now again, you can request an increase in this limit, 1596.54s - 1599.10s | but you don't wanna have to do this justification. 1599.10s - 1600.58s | I felt that it would be inappropriate 1600.58s - 1601.68s | to assume that an attacker 1601.68s - 1603.78s | would be able to get this quota increase. 1603.78s - 1604.74s | What I found was though, 1604.74s - 1607.12s | you can create a Google Workspace environment. 1607.12s - 1610.32s | So what that means is I can create a fakebusiness.com, 1610.32s - 1612.62s | I can create Google Workspace environment for it, 1612.62s - 1615.70s | and I can create practically as many Google accounts 1615.70s - 1620.26s | as I want


chunk_id: 162_chunk_34
chunk_text:
| This was a useful primitive 1580.94s - 1583.62s | where if I could create a billing account in one account, 1583.62s - 1585.88s | I can actually assign it across several accounts. 1585.88s - 1587.94s | And the reason this is interesting is, 1587.94s - 1589.96s | well, what about those quotas? 1589.96s - 1591.50s | Well, with account quotas, 1591.50s - 1594.06s | remember you can only create a certain amount of projects. 1594.06s - 1596.54s | Now again, you can request an increase in this limit, 1596.54s - 1599.10s | but you don't wanna have to do this justification. 1599.10s - 1600.58s | I felt that it would be inappropriate 1600.58s - 1601.68s | to assume that an attacker 1601.68s - 1603.78s | would be able to get this quota increase. 1603.78s - 1604.74s | What I found was though, 1604.74s - 1607.12s | you can create a Google Workspace environment. 1607.12s - 1610.32s | So what that means is I can create a fakebusiness.com, 1610.32s - 1612.62s | I can create Google Workspace environment for it, 1612.62s - 1615.70s | and I can create practically as many Google accounts 1615.70s - 1620.26s | as I want for about $6 per account per month. 1620.26s - 1622.62s | And this way, each of those accounts 1622.62s - 1624.58s | gets a dedicated quota limit 1624.58s - 1627.10s | and allows you to bypass these quota limits 1627.10s - 1629.46s | by creating, for example, 10 accounts. 1629.46s - 1633.78s | Now that's $60, but now your quota has been 10-timed. 1633.78s - 1636.54s | And finally, to bypass billing account restrictions, 1636.54s - 1638.52s | remember those credit card restrictions, 1638.52s - 1640.16s | billing accounts can only be associated 1640.16s - 1642.46s | with a certain number of projects. 1642.46s - 1645.62s | Well, we can instead then use virtual credit cards. 1645.62s - 1648.58s | And I use privacy.com, that's not a recommendation, 1648.58s - 1651.06s | it's just one of the easiest that worked for me. 1651.06s - 1653.26s | And what really this means is 1653.26s - 1655.98s | it's not like they're bypassing KYC practices, 1655.98s - 1657.74s | they verified my identity, 1657.74s - 1659.40s | but it still allows me to create 1659.40s - 1661.66s | as many credit card numbers as I want 1661.66s - 1663.98s | and be


chunk_id: 162_chunk_35
chunk_text:
for about $6 per account per month. 1620.26s - 1622.62s | And this way, each of those accounts 1622.62s - 1624.58s | gets a dedicated quota limit 1624.58s - 1627.10s | and allows you to bypass these quota limits 1627.10s - 1629.46s | by creating, for example, 10 accounts. 1629.46s - 1633.78s | Now that's $60, but now your quota has been 10-timed. 1633.78s - 1636.54s | And finally, to bypass billing account restrictions, 1636.54s - 1638.52s | remember those credit card restrictions, 1638.52s - 1640.16s | billing accounts can only be associated 1640.16s - 1642.46s | with a certain number of projects. 1642.46s - 1645.62s | Well, we can instead then use virtual credit cards. 1645.62s - 1648.58s | And I use privacy.com, that's not a recommendation, 1648.58s - 1651.06s | it's just one of the easiest that worked for me. 1651.06s - 1653.26s | And what really this means is 1653.26s - 1655.98s | it's not like they're bypassing KYC practices, 1655.98s - 1657.74s | they verified my identity, 1657.74s - 1659.40s | but it still allows me to create 1659.40s - 1661.66s | as many credit card numbers as I want 1661.66s - 1663.98s | and be able to create as many billing accounts as I want 1663.98s - 1666.04s | to be able to bypass every single restriction 1666.04s - 1668.22s | we discussed with Google Cloud. 1668.22s - 1670.46s | And so this is what I really wanna mention 1670.46s - 1671.42s | from a high level, 1671.42s - 1673.56s | is Google Cloud implemented all these deterrents 1673.56s - 1675.94s | to try to make sure you can't enumerate 1675.94s - 1678.42s | their dangling IPs, 1678.46s - 1679.70s | but in practice, 1679.70s - 1682.30s | these deterrents weren't addressing the root cause, 1682.30s - 1684.74s | which was the fact that the dangling IPs 1684.74s - 1691.30s | still existed in the first place. 1691.30s - 1694.60s | So let's talk about a little bit of the discovery process 1694.60s - 1698.32s | and what I was able to find with these techniques. 1699.94s - 1702.70s | So with dangling resources, 1702.70s - 1705.30s | I was able to enumerate over 2 million IP addresses 1705.30s - 1707.18s | for Google Cloud and AWS. 1707.18s - 1709.10s | These are unique IP addresses 1709.10s - 1711.48s | and they're mostly primitive resources.


chunk_id: 162_chunk_36
chunk_text:
able to create as many billing accounts as I want 1663.98s - 1666.04s | to be able to bypass every single restriction 1666.04s - 1668.22s | we discussed with Google Cloud. 1668.22s - 1670.46s | And so this is what I really wanna mention 1670.46s - 1671.42s | from a high level, 1671.42s - 1673.56s | is Google Cloud implemented all these deterrents 1673.56s - 1675.94s | to try to make sure you can't enumerate 1675.94s - 1678.42s | their dangling IPs, 1678.46s - 1679.70s | but in practice, 1679.70s - 1682.30s | these deterrents weren't addressing the root cause, 1682.30s - 1684.74s | which was the fact that the dangling IPs 1684.74s - 1691.30s | still existed in the first place. 1691.30s - 1694.60s | So let's talk about a little bit of the discovery process 1694.60s - 1698.32s | and what I was able to find with these techniques. 1699.94s - 1702.70s | So with dangling resources, 1702.70s - 1705.30s | I was able to enumerate over 2 million IP addresses 1705.30s - 1707.18s | for Google Cloud and AWS. 1707.18s - 1709.10s | These are unique IP addresses 1709.10s - 1711.48s | and they're mostly primitive resources. 1711.48s - 1713.60s | So these IPs were created by, 1713.60s - 1716.96s | remember, restarting an EC2 instance 1716.96s - 1719.82s | or creating forwarding rules over and over again. 1720.80s - 1721.64s | As far as I'm aware, 1721.64s - 1723.00s | this is one of the first methodologies 1723.00s - 1726.54s | to successfully bypass every single Google Cloud deterrent 1726.54s - 1728.98s | that is intended to stop this type of attack 1728.98s - 1730.54s | in the first place. 1730.54s - 1735.54s | I captured over 60,000 unique fully qualified domain names. 1735.84s - 1738.52s | And this reflects past research into this area 1738.52s - 1742.10s | where researchers found that these FQDNs, 1742.10s - 1743.68s | there are a lot of different A records 1743.68s - 1747.52s | that pointed at IPs that were no longer being controlled. 1747.52s - 1750.28s | Now out of these 60,000 FQDNs, 1750.28s - 1753.88s | there are about 54,000 unique second level domains. 1753.88s - 1754.92s | And what that really means 1754.92s - 1756.96s | is that once you take away the subdomain, 1756.96s - 1759.04s | let's say a.b.com, 1759.04s - 1761.60s | we're


chunk_id: 162_chunk_37
chunk_text:
1711.48s - 1713.60s | So these IPs were created by, 1713.60s - 1716.96s | remember, restarting an EC2 instance 1716.96s - 1719.82s | or creating forwarding rules over and over again. 1720.80s - 1721.64s | As far as I'm aware, 1721.64s - 1723.00s | this is one of the first methodologies 1723.00s - 1726.54s | to successfully bypass every single Google Cloud deterrent 1726.54s - 1728.98s | that is intended to stop this type of attack 1728.98s - 1730.54s | in the first place. 1730.54s - 1735.54s | I captured over 60,000 unique fully qualified domain names. 1735.84s - 1738.52s | And this reflects past research into this area 1738.52s - 1742.10s | where researchers found that these FQDNs, 1742.10s - 1743.68s | there are a lot of different A records 1743.68s - 1747.52s | that pointed at IPs that were no longer being controlled. 1747.52s - 1750.28s | Now out of these 60,000 FQDNs, 1750.28s - 1753.88s | there are about 54,000 unique second level domains. 1753.88s - 1754.92s | And what that really means 1754.92s - 1756.96s | is that once you take away the subdomain, 1756.96s - 1759.04s | let's say a.b.com, 1759.04s - 1761.60s | we're just focusing on the unique number of APEX 1761.60s - 1763.60s | or second level domains. 1763.60s - 1766.64s | Well, that was over 54,000. 1766.64s - 1770.40s | And finally, over 5,000 of the domains 1770.40s - 1771.80s | that I was able to capture 1772.84s - 1775.56s | were included in the Tranco top 1 million list. 1775.56s - 1778.76s | So Tranco is a listing of every domain 1778.76s - 1781.76s | that they're aware of within a certain ranking. 1781.76s - 1783.64s | And it allows you to compare 1783.64s - 1786.02s | what is supposed to be an objective metric 1786.02s - 1789.30s | for ranking of the domain based on DNS data. 1789.30s - 1793.00s | Now, there are a lot of Fortune 500 companies impacted. 1793.00s - 1796.22s | And what I found really interesting was that with AWS, 1796.94s - 1799.14s | we had a roughly 25, 1799.14s - 1802.98s | a rate of 25 dangling domains per 1,000 IPs. 1802.98s - 1806.74s | But with Google Cloud, it was nearly 36. 1806.74s - 1811.06s | And so what I suspect this discrepancy is as a result of 1811.06s - 1814.02s |


chunk_id: 162_chunk_38
chunk_text:
just focusing on the unique number of APEX 1761.60s - 1763.60s | or second level domains. 1763.60s - 1766.64s | Well, that was over 54,000. 1766.64s - 1770.40s | And finally, over 5,000 of the domains 1770.40s - 1771.80s | that I was able to capture 1772.84s - 1775.56s | were included in the Tranco top 1 million list. 1775.56s - 1778.76s | So Tranco is a listing of every domain 1778.76s - 1781.76s | that they're aware of within a certain ranking. 1781.76s - 1783.64s | And it allows you to compare 1783.64s - 1786.02s | what is supposed to be an objective metric 1786.02s - 1789.30s | for ranking of the domain based on DNS data. 1789.30s - 1793.00s | Now, there are a lot of Fortune 500 companies impacted. 1793.00s - 1796.22s | And what I found really interesting was that with AWS, 1796.94s - 1799.14s | we had a roughly 25, 1799.14s - 1802.98s | a rate of 25 dangling domains per 1,000 IPs. 1802.98s - 1806.74s | But with Google Cloud, it was nearly 36. 1806.74s - 1811.06s | And so what I suspect this discrepancy is as a result of 1811.06s - 1814.02s | is that Google Cloud hasn't been able to been enumerated 1814.02s - 1817.72s | for quite a few years. 1817.72s - 1819.40s | Now, this talk isn't gonna focus 1819.40s - 1822.32s | on the actual impact against customers 1822.32s - 1824.08s | because I promised DEF CON review board 1824.08s - 1825.82s | I wouldn't get stuck on it. 1825.82s - 1827.94s | But you can see that I was able to compromise 1827.94s - 1830.14s | some of the world's largest organizations, 1830.14s - 1834.60s | including the Western District Court of Texas, 1834.60s - 1836.46s | the New York Times, 1836.46s - 1841.10s | the State Government of California, and Dior. 1841.10s - 1843.52s | And yeah, it was a pretty fun time. 1843.52s - 1844.94s | There was a lot more examples here. 1844.94s - 1847.30s | Again, this isn't intended to cover it. 1847.30s - 1849.74s | That's on a separate blog post as well. 1849.74s - 1852.58s | I really go into detail about the impact. 1852.58s - 1854.34s | And for a secret scanning, 1854.34s - 1855.94s | again, what was really interesting 1855.94s - 1860.26s | was that I scanned over 5


chunk_id: 162_chunk_39
chunk_text:
is that Google Cloud hasn't been able to been enumerated 1814.02s - 1817.72s | for quite a few years. 1817.72s - 1819.40s | Now, this talk isn't gonna focus 1819.40s - 1822.32s | on the actual impact against customers 1822.32s - 1824.08s | because I promised DEF CON review board 1824.08s - 1825.82s | I wouldn't get stuck on it. 1825.82s - 1827.94s | But you can see that I was able to compromise 1827.94s - 1830.14s | some of the world's largest organizations, 1830.14s - 1834.60s | including the Western District Court of Texas, 1834.60s - 1836.46s | the New York Times, 1836.46s - 1841.10s | the State Government of California, and Dior. 1841.10s - 1843.52s | And yeah, it was a pretty fun time. 1843.52s - 1844.94s | There was a lot more examples here. 1844.94s - 1847.30s | Again, this isn't intended to cover it. 1847.30s - 1849.74s | That's on a separate blog post as well. 1849.74s - 1852.58s | I really go into detail about the impact. 1852.58s - 1854.34s | And for a secret scanning, 1854.34s - 1855.94s | again, what was really interesting 1855.94s - 1860.26s | was that I scanned over 5 million unique files 1860.26s - 1862.30s | from various platforms, not just VirusTotal. 1862.30s - 1863.86s | That was just one of them. 1863.86s - 1867.62s | And I discovered over 15,000 validated secrets. 1867.62s - 1868.96s | And out of these secrets, 1868.96s - 1872.90s | they included over 2,500 unique, again, validated. 1872.90s - 1875.20s | These aren't just, you know, may match a pattern. 1875.20s - 1876.42s | These are validated. 1876.42s - 1878.98s | To over 2,500 validated secrets, 1878.98s - 1881.98s | over 2,400 unique AWS keys, 1881.98s - 1884.78s | over 2,200 GitHub personal access tokens 1884.78s - 1886.52s | and fine-grained tokens, 1886.52s - 1889.76s | over 600 Google's cloud service accounts, 1889.76s - 1892.38s | over 460 Stripe accounts, 1892.38s - 1895.54s | and the rest are largely from miscellaneous providers 1895.54s - 1896.70s | added up together 1896.70s - 1899.34s | that I didn't feel the need to include in this slide. 1900.30s - 1912.12s | And again, there will be a blog to recap this, 1912.12s - 1913.92s | but from a high level, 1913.92s - 1915.64s | it's some of the largest organizations 1915.64s - 1917.00s | in the


chunk_id: 162_chunk_40
chunk_text:
million unique files 1860.26s - 1862.30s | from various platforms, not just VirusTotal. 1862.30s - 1863.86s | That was just one of them. 1863.86s - 1867.62s | And I discovered over 15,000 validated secrets. 1867.62s - 1868.96s | And out of these secrets, 1868.96s - 1872.90s | they included over 2,500 unique, again, validated. 1872.90s - 1875.20s | These aren't just, you know, may match a pattern. 1875.20s - 1876.42s | These are validated. 1876.42s - 1878.98s | To over 2,500 validated secrets, 1878.98s - 1881.98s | over 2,400 unique AWS keys, 1881.98s - 1884.78s | over 2,200 GitHub personal access tokens 1884.78s - 1886.52s | and fine-grained tokens, 1886.52s - 1889.76s | over 600 Google's cloud service accounts, 1889.76s - 1892.38s | over 460 Stripe accounts, 1892.38s - 1895.54s | and the rest are largely from miscellaneous providers 1895.54s - 1896.70s | added up together 1896.70s - 1899.34s | that I didn't feel the need to include in this slide. 1900.30s - 1912.12s | And again, there will be a blog to recap this, 1912.12s - 1913.92s | but from a high level, 1913.92s - 1915.64s | it's some of the largest organizations 1915.64s - 1917.00s | in the world were impacted. 1917.00s - 1918.82s | You know, just a fun example a few months ago 1918.82s - 1923.00s | was Slack, Stanford's entire Slack workspace, 1924.18s - 1926.98s | Samsung's workspace for Bixby. 1926.98s - 1928.96s | I was able to get a bot token 1928.96s - 1931.42s | for this Samsung Bixby tenant, 1931.42s - 1933.48s | and which allowed me to read messages 1933.48s - 1935.06s | from nearly every channel, 1935.06s - 1937.62s | every single channel that the bot had access to 1937.62s - 1940.68s | because of a default scope that was quite broad. 1940.68s - 1941.94s | You know, some other interesting things 1941.94s - 1944.54s | included the Supreme Court of Nebraska. 1944.54s - 1945.58s | That was a fun one, 1945.58s - 1948.58s | where they uploaded a password list to VirusTotal 1949.32s - 1951.38s | with like 300 credentials from different, 1951.38s - 1954.18s | like, I don't know, different AWS providers, 1954.18s - 1955.22s | different cloud providers, 1955.22s - 1957.36s | their security solutions, et cetera. 1957.36s - 1959.02s | That was a really fun one. 1959.02s - 1960.72s | You know, there are database backups 1960.72s


chunk_id: 162_chunk_41
chunk_text:
world were impacted. 1917.00s - 1918.82s | You know, just a fun example a few months ago 1918.82s - 1923.00s | was Slack, Stanford's entire Slack workspace, 1924.18s - 1926.98s | Samsung's workspace for Bixby. 1926.98s - 1928.96s | I was able to get a bot token 1928.96s - 1931.42s | for this Samsung Bixby tenant, 1931.42s - 1933.48s | and which allowed me to read messages 1933.48s - 1935.06s | from nearly every channel, 1935.06s - 1937.62s | every single channel that the bot had access to 1937.62s - 1940.68s | because of a default scope that was quite broad. 1940.68s - 1941.94s | You know, some other interesting things 1941.94s - 1944.54s | included the Supreme Court of Nebraska. 1944.54s - 1945.58s | That was a fun one, 1945.58s - 1948.58s | where they uploaded a password list to VirusTotal 1949.32s - 1951.38s | with like 300 credentials from different, 1951.38s - 1954.18s | like, I don't know, different AWS providers, 1954.18s - 1955.22s | different cloud providers, 1955.22s - 1957.36s | their security solutions, et cetera. 1957.36s - 1959.02s | That was a really fun one. 1959.02s - 1960.72s | You know, there are database backups 1960.72s - 1962.54s | with a lot of these AWS keys 1962.54s - 1965.10s | that had broad access to S3 buckets. 1965.10s - 1967.38s | Anyways, you'll be able to read a lot more about this 1967.38s - 1968.54s | this following week. 1969.70s - 1972.74s | So by leveraging a security at scale mindset, 1972.74s - 1975.14s | we can help protect thousands of organizations 1975.14s - 1977.14s | far beyond a limited scope. 1977.98s - 1980.98s | Remember, instead of starting with a specific target, 1980.98s - 1983.02s | by starting with a diverse dataset, 1983.02s - 1985.58s | we were able to have a much wider impact 1985.58s - 1988.48s | than any of past work into leaked secrets. 1989.42s - 1991.30s | You can read more about some of this impact 1991.30s - 1995.14s | in an article that should be released right now 1995.14s - 1997.06s | by Matt Burgess from Wired. 1997.06s - 1999.34s | And I'll be releasing a detailed technical blog 1999.34s - 2000.58s | later this week, 2000.58s - 2003.36s | once I figure out whether a certain cloud provider 2003.36s - 2007.62s | can actually revoke some of these keys


chunk_id: 162_chunk_42
chunk_text:
- 1962.54s | with a lot of these AWS keys 1962.54s - 1965.10s | that had broad access to S3 buckets. 1965.10s - 1967.38s | Anyways, you'll be able to read a lot more about this 1967.38s - 1968.54s | this following week. 1969.70s - 1972.74s | So by leveraging a security at scale mindset, 1972.74s - 1975.14s | we can help protect thousands of organizations 1975.14s - 1977.14s | far beyond a limited scope. 1977.98s - 1980.98s | Remember, instead of starting with a specific target, 1980.98s - 1983.02s | by starting with a diverse dataset, 1983.02s - 1985.58s | we were able to have a much wider impact 1985.58s - 1988.48s | than any of past work into leaked secrets. 1989.42s - 1991.30s | You can read more about some of this impact 1991.30s - 1995.14s | in an article that should be released right now 1995.14s - 1997.06s | by Matt Burgess from Wired. 1997.06s - 1999.34s | And I'll be releasing a detailed technical blog 1999.34s - 2000.58s | later this week, 2000.58s - 2003.36s | once I figure out whether a certain cloud provider 2003.36s - 2007.62s | can actually revoke some of these keys or not. 2007.62s - 2012.70s | So bringing it all together. 2012.70s - 2016.18s | Hard coding secrets is the path of least resistance. 2016.18s - 2019.10s | So remember, these are customer vulnerabilities, 2019.10s - 2024.10s | but what enables them is these bad incentives. 2024.16s - 2025.00s | Think about it. 2025.00s - 2026.38s | Think about how easy it is to go ahead 2026.38s - 2028.58s | and generate an AWS access key 2028.58s - 2031.10s | or generate a Google Cloud Service account 2031.10s - 2033.86s | and then put that into your executable directly. 2033.86s - 2036.80s | You know, the libraries for these different providers 2036.80s - 2040.02s | allow this direct interface in the first place. 2041.52s - 2043.28s | Now, the reason this is really important 2043.28s - 2044.68s | is because a lot of developers 2044.68s - 2047.82s | are gonna follow the path of least resistance, 2047.82s - 2050.54s | especially from smaller to mid-cap businesses. 2051.46s - 2054.88s | And with dangling DNS records, the same problem exists. 2054.88s - 2057.12s | It's the path of least resistance. 2057.12s - 2059.80s | I created an AWS EC2 instance, 2059.80s


chunk_id: 162_chunk_43
chunk_text:
or not. 2007.62s - 2012.70s | So bringing it all together. 2012.70s - 2016.18s | Hard coding secrets is the path of least resistance. 2016.18s - 2019.10s | So remember, these are customer vulnerabilities, 2019.10s - 2024.10s | but what enables them is these bad incentives. 2024.16s - 2025.00s | Think about it. 2025.00s - 2026.38s | Think about how easy it is to go ahead 2026.38s - 2028.58s | and generate an AWS access key 2028.58s - 2031.10s | or generate a Google Cloud Service account 2031.10s - 2033.86s | and then put that into your executable directly. 2033.86s - 2036.80s | You know, the libraries for these different providers 2036.80s - 2040.02s | allow this direct interface in the first place. 2041.52s - 2043.28s | Now, the reason this is really important 2043.28s - 2044.68s | is because a lot of developers 2044.68s - 2047.82s | are gonna follow the path of least resistance, 2047.82s - 2050.54s | especially from smaller to mid-cap businesses. 2051.46s - 2054.88s | And with dangling DNS records, the same problem exists. 2054.88s - 2057.12s | It's the path of least resistance. 2057.12s - 2059.80s | I created an AWS EC2 instance, 2059.80s - 2063.44s | I put my DNS record pointing at that AWS EC2 instance, 2063.44s - 2065.52s | and the path of least resistance 2065.52s - 2068.56s | is leaving that DNS record even if I deallocate it. 2069.44s - 2071.56s | And what I think we need to really focus on 2071.56s - 2074.28s | is making sure that the path of least resistance 2074.28s - 2076.12s | is the secure path. 2076.12s - 2080.48s | And what this really means is with dangling resources, 2080.48s - 2082.64s | I think we need to have better ownership 2082.64s - 2086.84s | of cloud resources and DNS records, better association. 2086.84s - 2088.60s | So for example, some cloud providers 2088.60s - 2092.28s | have tried to associate their DNS services 2092.28s - 2095.72s | with their EC2 resources, as one example. 2095.72s - 2098.52s | And the problem with this is a lot of different customers 2098.52s - 2100.46s | are gonna use different DNS providers, 2100.46s - 2101.84s | different cloud providers. 2101.84s - 2104.52s | What we really need is an industry-wide solution 2104.52s - 2108.44s | of tracking DNS records and tracking cloud resources 2108.44s -


chunk_id: 162_chunk_44
chunk_text:
- 2063.44s | I put my DNS record pointing at that AWS EC2 instance, 2063.44s - 2065.52s | and the path of least resistance 2065.52s - 2068.56s | is leaving that DNS record even if I deallocate it. 2069.44s - 2071.56s | And what I think we need to really focus on 2071.56s - 2074.28s | is making sure that the path of least resistance 2074.28s - 2076.12s | is the secure path. 2076.12s - 2080.48s | And what this really means is with dangling resources, 2080.48s - 2082.64s | I think we need to have better ownership 2082.64s - 2086.84s | of cloud resources and DNS records, better association. 2086.84s - 2088.60s | So for example, some cloud providers 2088.60s - 2092.28s | have tried to associate their DNS services 2092.28s - 2095.72s | with their EC2 resources, as one example. 2095.72s - 2098.52s | And the problem with this is a lot of different customers 2098.52s - 2100.46s | are gonna use different DNS providers, 2100.46s - 2101.84s | different cloud providers. 2101.84s - 2104.52s | What we really need is an industry-wide solution 2104.52s - 2108.44s | of tracking DNS records and tracking cloud resources 2108.44s - 2112.96s | and putting them together. 2112.96s - 2115.92s | Now, for hard-coded secrets, 2115.92s - 2117.68s | what I really think we need to focus on 2117.68s - 2119.72s | is making sure that it's hard 2119.72s - 2122.32s | to include secrets in your code. 2122.32s - 2124.88s | So don't have short-access tokens 2124.88s - 2130.55s | that your library just blindly accepts from a string, 2130.55s - 2150.08s | but instead for, all right, thank you for that. 2150.08s - 2151.64s | That was a nice wake-up call. 2153.88s - 2156.16s | All right, anyways, so yeah, 2156.16s - 2157.48s | with these hard-coded secrets, 2157.48s - 2158.88s | what I really think we need to do 2158.88s - 2161.76s | is make sure to limit the secrets 2161.76s - 2164.40s | so that they can only be inserted from the environment 2164.40s - 2165.84s | or from a file on disk, 2165.84s - 2168.00s | and make it hard to hard-code these secrets 2168.00s - 2170.28s | inside of an executable in the first place. 2170.28s - 2171.88s | Now, again, you can have exceptions. 2171.88s - 2174.10s | You can have it so a


chunk_id: 162_chunk_45
chunk_text:
2112.96s | and putting them together. 2112.96s - 2115.92s | Now, for hard-coded secrets, 2115.92s - 2117.68s | what I really think we need to focus on 2117.68s - 2119.72s | is making sure that it's hard 2119.72s - 2122.32s | to include secrets in your code. 2122.32s - 2124.88s | So don't have short-access tokens 2124.88s - 2130.55s | that your library just blindly accepts from a string, 2130.55s - 2150.08s | but instead for, all right, thank you for that. 2150.08s - 2151.64s | That was a nice wake-up call. 2153.88s - 2156.16s | All right, anyways, so yeah, 2156.16s - 2157.48s | with these hard-coded secrets, 2157.48s - 2158.88s | what I really think we need to do 2158.88s - 2161.76s | is make sure to limit the secrets 2161.76s - 2164.40s | so that they can only be inserted from the environment 2164.40s - 2165.84s | or from a file on disk, 2165.84s - 2168.00s | and make it hard to hard-code these secrets 2168.00s - 2170.28s | inside of an executable in the first place. 2170.28s - 2171.88s | Now, again, you can have exceptions. 2171.88s - 2174.10s | You can have it so a customer can opt out 2174.10s - 2175.98s | from the secure default, 2175.98s - 2182.13s | but we need to make sure that the secret default is secure. 2182.13s - 2185.69s | So what about remediating these vulnerabilities? 2185.69s - 2188.53s | Well, remember, for dangling records at a high level, 2188.53s - 2191.37s | it's gonna be hard to contact every single host 2191.37s - 2193.89s | of every 60,000 dangling domain 2193.89s - 2195.69s | that I was able to discover. 2195.69s - 2199.49s | What we really need is a way to tie ownership to DNS records. 2200.25s - 2201.37s | And we need to do this across the industry 2201.37s - 2205.83s | because of that multi-cloud approach. 2205.83s - 2209.75s | Now, for secrets, this is where it gets really interesting. 2209.75s - 2212.33s | So I went ahead and asked a bunch of organizations 2212.33s - 2214.49s | that I found secrets for, including GitHub, 2214.49s - 2217.01s | including AWS, including OpenAI, 2217.01s - 2219.01s | whether I could report secrets to them 2219.01s - 2221.17s | and they could revoke them automatically. 2221.17s - 2223.97s | Now, GitHub has that program for


chunk_id: 162_chunk_46
chunk_text:
customer can opt out 2174.10s - 2175.98s | from the secure default, 2175.98s - 2182.13s | but we need to make sure that the secret default is secure. 2182.13s - 2185.69s | So what about remediating these vulnerabilities? 2185.69s - 2188.53s | Well, remember, for dangling records at a high level, 2188.53s - 2191.37s | it's gonna be hard to contact every single host 2191.37s - 2193.89s | of every 60,000 dangling domain 2193.89s - 2195.69s | that I was able to discover. 2195.69s - 2199.49s | What we really need is a way to tie ownership to DNS records. 2200.25s - 2201.37s | And we need to do this across the industry 2201.37s - 2205.83s | because of that multi-cloud approach. 2205.83s - 2209.75s | Now, for secrets, this is where it gets really interesting. 2209.75s - 2212.33s | So I went ahead and asked a bunch of organizations 2212.33s - 2214.49s | that I found secrets for, including GitHub, 2214.49s - 2217.01s | including AWS, including OpenAI, 2217.01s - 2219.01s | whether I could report secrets to them 2219.01s - 2221.17s | and they could revoke them automatically. 2221.17s - 2223.97s | Now, GitHub has that program for scanning secrets 2223.97s - 2225.85s | on their platform already. 2225.85s - 2228.07s | Remember, if you actually go ahead and post a, 2228.07s - 2231.85s | for example, OpenAI access key on a public repository, 2231.85s - 2235.43s | that access key will be revoked within a few minutes. 2235.43s - 2237.03s | And what I was curious was, hey, GitHub, 2237.03s - 2240.35s | can I please use this mechanism you already have? 2240.35s - 2242.75s | Well, unfortunately, they said no. 2242.75s - 2246.47s | And in fact, several providers said no, like AWS, 2246.47s - 2249.45s | despite the fact that they already had given this mechanism 2249.45s - 2251.47s | to GitHub and despite the fact 2251.47s - 2254.51s | that an attacker could access the mechanism 2254.51s - 2258.35s | by posting a public git or public commit. 2258.35s - 2260.75s | Now, one exception to this was OpenAI, 2260.75s - 2263.19s | who immediately responded with an endpoint 2263.19s - 2265.47s | for reporting these keys and allowed me 2265.47s - 2267.35s | to automatically revoke the keys 2267.35s - 2269.85s | that I discovered in the wild. 2269.85s - 2272.51s | But


chunk_id: 162_chunk_47
chunk_text:
scanning secrets 2223.97s - 2225.85s | on their platform already. 2225.85s - 2228.07s | Remember, if you actually go ahead and post a, 2228.07s - 2231.85s | for example, OpenAI access key on a public repository, 2231.85s - 2235.43s | that access key will be revoked within a few minutes. 2235.43s - 2237.03s | And what I was curious was, hey, GitHub, 2237.03s - 2240.35s | can I please use this mechanism you already have? 2240.35s - 2242.75s | Well, unfortunately, they said no. 2242.75s - 2246.47s | And in fact, several providers said no, like AWS, 2246.47s - 2249.45s | despite the fact that they already had given this mechanism 2249.45s - 2251.47s | to GitHub and despite the fact 2251.47s - 2254.51s | that an attacker could access the mechanism 2254.51s - 2258.35s | by posting a public git or public commit. 2258.35s - 2260.75s | Now, one exception to this was OpenAI, 2260.75s - 2263.19s | who immediately responded with an endpoint 2263.19s - 2265.47s | for reporting these keys and allowed me 2265.47s - 2267.35s | to automatically revoke the keys 2267.35s - 2269.85s | that I discovered in the wild. 2269.85s - 2272.51s | But what do we do about everyone else? 2272.51s - 2274.59s | So the problem with these secret keys 2274.59s - 2277.55s | is that the impact is far, far, far greater 2277.55s - 2279.59s | than dangling DNS records. 2279.59s - 2280.95s | In fact, we just saw some 2280.95s - 2282.55s | of the world's largest organizations 2282.55s - 2285.19s | and there were several more impacted. 2285.19s - 2287.07s | I didn't feel comfortable releasing this work 2287.07s - 2288.87s | without at least some stopgap 2288.87s - 2292.67s | until these cloud providers could take the secure default. 2292.67s - 2296.23s | So what I actually did was I developed a mechanism 2296.23s - 2299.45s | that used GitHub's mechanism anyway 2299.45s - 2303.41s | for revoking these secrets because they said no, 2303.41s - 2304.59s | but I don't care. 2305.63s - 2308.39s | But yeah, so what I did was I have this system now 2308.39s - 2311.23s | where whenever new secrets are discovered, 2311.23s - 2313.57s | I'll go ahead and create a gist 2313.57s - 2315.11s | and the way I create this gist 2315.11s - 2319.23s | is by automating the


chunk_id: 162_chunk_48
chunk_text:
what do we do about everyone else? 2272.51s - 2274.59s | So the problem with these secret keys 2274.59s - 2277.55s | is that the impact is far, far, far greater 2277.55s - 2279.59s | than dangling DNS records. 2279.59s - 2280.95s | In fact, we just saw some 2280.95s - 2282.55s | of the world's largest organizations 2282.55s - 2285.19s | and there were several more impacted. 2285.19s - 2287.07s | I didn't feel comfortable releasing this work 2287.07s - 2288.87s | without at least some stopgap 2288.87s - 2292.67s | until these cloud providers could take the secure default. 2292.67s - 2296.23s | So what I actually did was I developed a mechanism 2296.23s - 2299.45s | that used GitHub's mechanism anyway 2299.45s - 2303.41s | for revoking these secrets because they said no, 2303.41s - 2304.59s | but I don't care. 2305.63s - 2308.39s | But yeah, so what I did was I have this system now 2308.39s - 2311.23s | where whenever new secrets are discovered, 2311.23s - 2313.57s | I'll go ahead and create a gist 2313.57s - 2315.11s | and the way I create this gist 2315.11s - 2319.23s | is by automating the entire GitHub login process 2319.23s - 2321.55s | and then just am using an UI endpoint 2321.55s - 2322.99s | for creating a public gist. 2322.99s - 2325.59s | And this way, it'll actually trigger 2325.59s - 2327.55s | the GitHub secret scanning mechanism 2327.55s - 2330.03s | that they could have given me direct access to anyway. 2330.03s - 2337.37s | So yeah, anyways. 2337.37s - 2338.61s | Now, what's really cool about this 2338.61s - 2341.73s | is that almost every secret that you saw listed 2341.73s - 2343.17s | in the previous section, 2343.17s - 2345.01s | a lot of them are gonna be revoked. 2345.01s - 2347.05s | There's an exception to that though. 2347.05s - 2349.49s | One of the largest providers which did have leaked secrets 2349.49s - 2351.01s | was AWS. 2351.01s - 2353.67s | Now, AWS takes an interesting approach. 2353.67s - 2355.81s | When you post your AWS access key 2355.81s - 2358.99s | on a public GitHub commit or post, 2358.99s - 2362.53s | what they do is that they'll create a support case for you 2362.53s - 2366.09s | and restrict to write access using that key. 2366.09s -


chunk_id: 162_chunk_49
chunk_text:
entire GitHub login process 2319.23s - 2321.55s | and then just am using an UI endpoint 2321.55s - 2322.99s | for creating a public gist. 2322.99s - 2325.59s | And this way, it'll actually trigger 2325.59s - 2327.55s | the GitHub secret scanning mechanism 2327.55s - 2330.03s | that they could have given me direct access to anyway. 2330.03s - 2337.37s | So yeah, anyways. 2337.37s - 2338.61s | Now, what's really cool about this 2338.61s - 2341.73s | is that almost every secret that you saw listed 2341.73s - 2343.17s | in the previous section, 2343.17s - 2345.01s | a lot of them are gonna be revoked. 2345.01s - 2347.05s | There's an exception to that though. 2347.05s - 2349.49s | One of the largest providers which did have leaked secrets 2349.49s - 2351.01s | was AWS. 2351.01s - 2353.67s | Now, AWS takes an interesting approach. 2353.67s - 2355.81s | When you post your AWS access key 2355.81s - 2358.99s | on a public GitHub commit or post, 2358.99s - 2362.53s | what they do is that they'll create a support case for you 2362.53s - 2366.09s | and restrict to write access using that key. 2366.09s - 2367.13s | I found that kind of interesting. 2367.13s - 2369.81s | So what's really happening is AWS 2369.81s - 2371.49s | is aware of these secret keys, 2371.49s - 2374.71s | but they're choosing not to revoke them for some reason. 2375.73s - 2377.29s | Yeah, that's an interesting one. 2377.29s - 2381.25s | So effectively, if you find a leaked AWS access key 2381.25s - 2384.77s | on GitHub, you can still use that key to read S3 buckets, 2384.77s - 2389.33s | read RDS database data, to read download files from S3. 2389.33s - 2392.41s | You know, I remember I looked at a AWS key last weekend 2392.41s - 2395.01s | for a casino that was dealing, 2395.01s - 2400.01s | well, alleged to deal with over $1 billion of bets a month. 2400.57s - 2402.37s | And I was like, okay, wait a minute. 2402.37s - 2403.33s | Was this reported? 2403.33s - 2404.71s | We should get this revoked. 2405.41s - 2406.79s | But in reality, what happened was 2406.79s - 2409.23s | AWS created this support case. 2409.23s - 2410.75s | The customer never saw it 2410.75s - 2413.39s | because the support


chunk_id: 162_chunk_50
chunk_text:
2367.13s | I found that kind of interesting. 2367.13s - 2369.81s | So what's really happening is AWS 2369.81s - 2371.49s | is aware of these secret keys, 2371.49s - 2374.71s | but they're choosing not to revoke them for some reason. 2375.73s - 2377.29s | Yeah, that's an interesting one. 2377.29s - 2381.25s | So effectively, if you find a leaked AWS access key 2381.25s - 2384.77s | on GitHub, you can still use that key to read S3 buckets, 2384.77s - 2389.33s | read RDS database data, to read download files from S3. 2389.33s - 2392.41s | You know, I remember I looked at a AWS key last weekend 2392.41s - 2395.01s | for a casino that was dealing, 2395.01s - 2400.01s | well, alleged to deal with over $1 billion of bets a month. 2400.57s - 2402.37s | And I was like, okay, wait a minute. 2402.37s - 2403.33s | Was this reported? 2403.33s - 2404.71s | We should get this revoked. 2405.41s - 2406.79s | But in reality, what happened was 2406.79s - 2409.23s | AWS created this support case. 2409.23s - 2410.75s | The customer never saw it 2410.75s - 2413.39s | because the support email was sent 2413.39s - 2415.31s | to their generic billing account. 2415.31s - 2417.35s | You know, a lot of people, a lot of enterprises 2417.35s - 2420.59s | set up an AWS account and use a generic billing email 2420.59s - 2421.91s | that no one really looks at. 2421.91s - 2423.83s | And so the support case was ignored, 2423.83s - 2426.31s | and this key is still active today. 2426.31s - 2427.63s | You know, it's disappointing 2427.63s - 2430.15s | because I don't know what more I can do for my shoes. 2430.15s - 2431.31s | You know, I've created a mechanism 2431.31s - 2433.87s | that can help automatically revoke most of these keys. 2433.87s - 2435.75s | But what do we do about keys 2435.75s - 2438.51s | that the provider doesn't take action on? 2438.51s - 2439.91s | And so this is where I really think 2439.91s - 2441.75s | providers need to switch up is, 2441.75s - 2444.83s | number one, if someone's secret key, 2444.83s - 2447.39s | you have both components, is on the internet 2447.39s - 2451.31s | and you know about it, you need to revoke that


chunk_id: 162_chunk_51
chunk_text:
email was sent 2413.39s - 2415.31s | to their generic billing account. 2415.31s - 2417.35s | You know, a lot of people, a lot of enterprises 2417.35s - 2420.59s | set up an AWS account and use a generic billing email 2420.59s - 2421.91s | that no one really looks at. 2421.91s - 2423.83s | And so the support case was ignored, 2423.83s - 2426.31s | and this key is still active today. 2426.31s - 2427.63s | You know, it's disappointing 2427.63s - 2430.15s | because I don't know what more I can do for my shoes. 2430.15s - 2431.31s | You know, I've created a mechanism 2431.31s - 2433.87s | that can help automatically revoke most of these keys. 2433.87s - 2435.75s | But what do we do about keys 2435.75s - 2438.51s | that the provider doesn't take action on? 2438.51s - 2439.91s | And so this is where I really think 2439.91s - 2441.75s | providers need to switch up is, 2441.75s - 2444.83s | number one, if someone's secret key, 2444.83s - 2447.39s | you have both components, is on the internet 2447.39s - 2451.31s | and you know about it, you need to revoke that immediately. 2451.31s - 2453.75s | I mean, it's crazy to me to think that even on GitHub, 2453.75s - 2455.59s | if you post your AWS access key, 2455.59s - 2457.51s | that's not gonna be automatically revoked. 2457.51s - 2460.31s | Every other provider I looked at does automatically revoke. 2460.31s - 2464.23s | Google Cloud revokes, Slack revokes, OpenAI revokes. 2464.23s - 2470.49s | The largest cloud provider by market share does not revoke. 2470.49s - 2473.89s | Now, if you're interested in starting this sort of research 2473.89s - 2477.05s | yourself, what I'd focus on is breaking down 2477.05s - 2479.37s | the traditional methods of finding vulnerabilities. 2479.37s - 2481.77s | So with dangling domains, that was checking 2481.77s - 2483.93s | if the DNS record is actually pointing 2483.93s - 2486.53s | at a uncaptured IP address. 2486.53s - 2489.85s | And with secrets, it was trying to find 2489.85s - 2493.05s | those secret patterns in a diverse data source. 2494.01s - 2496.57s | So in this case, we used virus scanning platforms, 2496.57s - 2498.93s | but you can use a similar methodology 2498.93s - 2503.37s | against a larger set of


chunk_id: 162_chunk_52
chunk_text:
immediately. 2451.31s - 2453.75s | I mean, it's crazy to me to think that even on GitHub, 2453.75s - 2455.59s | if you post your AWS access key, 2455.59s - 2457.51s | that's not gonna be automatically revoked. 2457.51s - 2460.31s | Every other provider I looked at does automatically revoke. 2460.31s - 2464.23s | Google Cloud revokes, Slack revokes, OpenAI revokes. 2464.23s - 2470.49s | The largest cloud provider by market share does not revoke. 2470.49s - 2473.89s | Now, if you're interested in starting this sort of research 2473.89s - 2477.05s | yourself, what I'd focus on is breaking down 2477.05s - 2479.37s | the traditional methods of finding vulnerabilities. 2479.37s - 2481.77s | So with dangling domains, that was checking 2481.77s - 2483.93s | if the DNS record is actually pointing 2483.93s - 2486.53s | at a uncaptured IP address. 2486.53s - 2489.85s | And with secrets, it was trying to find 2489.85s - 2493.05s | those secret patterns in a diverse data source. 2494.01s - 2496.57s | So in this case, we used virus scanning platforms, 2496.57s - 2498.93s | but you can use a similar methodology 2498.93s - 2503.37s | against a larger set of vulnerability classes. 2503.37s - 2505.69s | And what you really wanna do is correlate those steps 2505.69s - 2507.69s | with these large data sets, 2507.69s - 2509.69s | regardless of their intended usage. 2511.29s - 2513.73s | Thank you so much for coming out to this talk. 2513.73s - 2521.19s | What a fun time. 2521.19s - 2525.58s | We do have a few minute for questions. 2525.58s - 2530.03s | Oh, we apparently don't have microphones, that's... 2530.03s - 2531.39s | All right, yeah, if you have questions, 2531.39s - 2534.55s | feel free to come up and we can have a chat over on stage. 2534.55s - 2536.51s | Thank you so much for coming out to this talk. 2536.51s - 2537.35s | What a fun time. 2537.35s - 2539.87s | And yeah, I look forward to working with these providers 2539.87s - 2541.51s | to address these vulnerabilities.


chunk_id: 162_chunk_53
chunk_text:
vulnerability classes. 2503.37s - 2505.69s | And what you really wanna do is correlate those steps 2505.69s - 2507.69s | with these large data sets, 2507.69s - 2509.69s | regardless of their intended usage. 2511.29s - 2513.73s | Thank you so much for coming out to this talk. 2513.73s - 2521.19s | What a fun time. 2521.19s - 2525.58s | We do have a few minute for questions. 2525.58s - 2530.03s | Oh, we apparently don't have microphones, that's... 2530.03s - 2531.39s | All right, yeah, if you have questions, 2531.39s - 2534.55s | feel free to come up and we can have a chat over on stage. 2534.55s - 2536.51s | Thank you so much for coming out to this talk. 2536.51s - 2537.35s | What a fun time. 2537.35s - 2539.87s | And yeah, I look forward to working with these providers 2539.87s - 2541.51s | to address these vulnerabilities.


chunk_id: 163_chunk_0
chunk_text:
{ "webpage_url": "https://www.youtube.com/watch?v=uKvkBchZkA0", "title": "DEF CON 32 - Autos, alcohol, blood, sweat, & creative reversing obfuscated Car Modding tool - Atlas", "description": "reversing can feel uber powerful... like you hold God's honest truth within your hands... most humans don't understand what you can see and comprehend.\n\nuntil someone tries to hide the truth from you... limit your knowledge... keep you from your glorious purpose!\n\nobfuscated code can be a real downer.\n\nthis talk focuses on the story of how i took on an interesting obfuscated target (an automotive modder's tool with ability to flash firmware and tweak engines), in fun and exciting ways.\n\nwe'll discuss several problems with obfuscated code, an approach i took (and tooling), playing in the guts of machine code, and customizations to binary analysis tools that came out of the journey...\n\nthere will be much hex, disassembly, green on black, total carnage.\n\nyou will walk away with powerful ideas and new tools to help you in your pursuit of truth. you will be entertained, enriched, educated, and hopefully inspired. instead of thinking that \"atlas is smart\" my goal is you feeling, and being, more powerful.\n\ncome with Vivisect installed to follow along!", "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw", "duration": 2452, "channel": "DEFCONConference", "uploader": "DEFCONConference", "upload_date": "20241016" } 0.00s - 5.80s | This text was transcribed using whisper model: large-v2 Good morning, oh good afternoon DEF CON. Uh today we have a talk on automobiles, alcohol, 5.80s - 12.88s | blood, sweat, and creative revers- reversing of obfuscated car moding tool. And with our 12.88s - 17.88s | speaker Atlas. Thank you sir. Thank you Fals. I'm sorry True. Hi everyone, welcome. How 23.46s - 30.06s | many of you came because it had the word automotive in it? Alright, good. Uh obfuscation, 30.06s - 37.46s | who came because it said obfuscation? Excellent. Well thank you all. I don't care why you 37.46s - 42.10s | came, you're here. I'm very grateful for you. I hope that we have a lot of fun today. Uh as 42.10s - 47.30s | per usual if you've come to a talk of mine I've crammed in way too much stuff and we're 47.30s - 54.81s | gonna see just how well and how much we can fit in. And because of timing I'm going to 54.81s - 59.31s | probably just come out here and look at the slides that you're seeing cause I, yeah 59.31s - 64.31s | whatever.


chunk_id: 163_chunk_1
chunk_text:
0.00s - 5.80s | This text was transcribed using whisper model: large-v2 Good morning, oh good afternoon DEF CON. Uh today we have a talk on automobiles, alcohol, 5.80s - 12.88s | blood, sweat, and creative revers- reversing of obfuscated car moding tool. And with our 12.88s - 17.88s | speaker Atlas. Thank you sir. Thank you Fals. I'm sorry True. Hi everyone, welcome. How 23.46s - 30.06s | many of you came because it had the word automotive in it? Alright, good. Uh obfuscation, 30.06s - 37.46s | who came because it said obfuscation? Excellent. Well thank you all. I don't care why you 37.46s - 42.10s | came, you're here. I'm very grateful for you. I hope that we have a lot of fun today. Uh as 42.10s - 47.30s | per usual if you've come to a talk of mine I've crammed in way too much stuff and we're 47.30s - 54.81s | gonna see just how well and how much we can fit in. And because of timing I'm going to 54.81s - 59.31s | probably just come out here and look at the slides that you're seeing cause I, yeah 59.31s - 64.31s | whatever. So who is this Atlas dork? Hi. This is my home. I was created here at DEF CON in 66.65s - 71.65s | 2013. Um and this is my family. I'm a hacker of things, I ride a motorcycle, I've got three 77.25s - 86.90s | amazing daughters who have nothing to do with technology. If you dare there is a QR code 86.92s - 92.42s | that has all sorts of ways to get a hold of me. I'll leave that up for about ten more 92.42s - 103.43s | seconds. So I work in R&D and cyber physical systems for a company called Grim and Grim is 103.43s - 112.56s | represented, stand up. My dear friends down here wore huge Grim t-shirts, ask how many of 112.56s - 119.62s | them work for Grim. A lot of love here. Alright, so my job is to break into things and I'm 126.32s - 132.30s | I set many goals, some of them attainable in the near term, many of them long term goals, some 132.30s - 137.80s | of them like if I do these three projects that are year long then I'll achieve this thing. So 137.80s


chunk_id: 163_chunk_2
chunk_text:
So who is this Atlas dork? Hi. This is my home. I was created here at DEF CON in 66.65s - 71.65s | 2013. Um and this is my family. I'm a hacker of things, I ride a motorcycle, I've got three 77.25s - 86.90s | amazing daughters who have nothing to do with technology. If you dare there is a QR code 86.92s - 92.42s | that has all sorts of ways to get a hold of me. I'll leave that up for about ten more 92.42s - 103.43s | seconds. So I work in R&D and cyber physical systems for a company called Grim and Grim is 103.43s - 112.56s | represented, stand up. My dear friends down here wore huge Grim t-shirts, ask how many of 112.56s - 119.62s | them work for Grim. A lot of love here. Alright, so my job is to break into things and I'm 126.32s - 132.30s | I set many goals, some of them attainable in the near term, many of them long term goals, some 132.30s - 137.80s | of them like if I do these three projects that are year long then I'll achieve this thing. So 137.80s - 144.24s | I think in these many different ways. But my ultimate goal typically is remote code execution 144.24s - 149.26s | on a device thing in a running program. For cars and uh and particularly the small ECUs that 150.22s - 155.22s | run your cars. My favorite way to gain code execution on an ECU like your brake controller, 159.22s - 165.86s | your power steer, power steering controller is through the update process or diagnostics 165.86s - 170.86s | process. Your tool plugs in, I'm sorry, runs on Windows, there's some software, have a 171.86s - 176.86s | have a hardware tool plugs into the OBD2 port on your car and then talks over the the 181.00s - 186.00s | vehicle CAN network to tell the car things what to do. Now, for that, for the really cool 190.94s - 196.34s | stuff that we really like to do, there's an authentication mechanism so the tool says no, I'm 196.34s - 202.04s | not just some Joe Schmo, I'm I'm supposed to be doing this. Give me all the goods, let me do 202.06s - 206.16s | all the cool things. Now there are a couple


chunk_id: 163_chunk_3
chunk_text:
- 144.24s | I think in these many different ways. But my ultimate goal typically is remote code execution 144.24s - 149.26s | on a device thing in a running program. For cars and uh and particularly the small ECUs that 150.22s - 155.22s | run your cars. My favorite way to gain code execution on an ECU like your brake controller, 159.22s - 165.86s | your power steer, power steering controller is through the update process or diagnostics 165.86s - 170.86s | process. Your tool plugs in, I'm sorry, runs on Windows, there's some software, have a 171.86s - 176.86s | have a hardware tool plugs into the OBD2 port on your car and then talks over the the 181.00s - 186.00s | vehicle CAN network to tell the car things what to do. Now, for that, for the really cool 190.94s - 196.34s | stuff that we really like to do, there's an authentication mechanism so the tool says no, I'm 196.34s - 202.04s | not just some Joe Schmo, I'm I'm supposed to be doing this. Give me all the goods, let me do 202.06s - 206.16s | all the cool things. Now there are a couple different ways that this is done, well a number 206.16s - 210.50s | of different ways but two primary standards of the way that this is done. But it generally 210.50s - 215.30s | comes with some sort of back and forth, a seed key exchange or some sort of authentication 215.30s - 220.30s | mechanisms like what you might like. Um and then, well I won't get into exactly how I gain 222.88s - 228.69s | code execution at that point but there are many different cool things that you can do. Set 228.73s - 234.27s | diagnostics level is the uh is the way that you tell an ECU to go into a certain mode. 234.27s - 239.55s | Sometimes you can change parameters, sometimes you can update firmware. Um but then 239.55s - 245.35s | there's a security access uh hex 27 or an authentication hex 29, these are the service 245.35s - 251.83s | numbers that are that are used in the messages. And that sets up the back and forth 251.83s - 256.85s | authentication process. So it could be simple key uh seed key exchange and we just walked 260.41s - 270.30s | through


chunk_id: 163_chunk_4
chunk_text:
different ways that this is done, well a number 206.16s - 210.50s | of different ways but two primary standards of the way that this is done. But it generally 210.50s - 215.30s | comes with some sort of back and forth, a seed key exchange or some sort of authentication 215.30s - 220.30s | mechanisms like what you might like. Um and then, well I won't get into exactly how I gain 222.88s - 228.69s | code execution at that point but there are many different cool things that you can do. Set 228.73s - 234.27s | diagnostics level is the uh is the way that you tell an ECU to go into a certain mode. 234.27s - 239.55s | Sometimes you can change parameters, sometimes you can update firmware. Um but then 239.55s - 245.35s | there's a security access uh hex 27 or an authentication hex 29, these are the service 245.35s - 251.83s | numbers that are that are used in the messages. And that sets up the back and forth 251.83s - 256.85s | authentication process. So it could be simple key uh seed key exchange and we just walked 260.41s - 270.30s | through that basically. Moving right along. Alright so the goal for me in this project that 273.78s - 278.78s | I'm talking about is to gain access to the code that calculates the seed key exchange or the 281.28s - 285.92s | authentication mechanism. Uh there are many different things that that can go into that but I 285.92s - 290.86s | don't care. I want them all. Uh this this all started a couple years ago when one 290.86s - 297.54s | manufacturer that we already had access to added a new authentication mechanism that we didn't 297.54s - 302.94s | have access to and so it's like we gotta have this and then I made the I made the, I won't say 302.94s - 309.72s | mistake, I made the decision to use this as a mentoring tool. Instead of going hog wild after it, 309.72s - 314.46s | I leaned into other people who are very capable, very skilled, very passionate and I allowed 314.46s - 319.46s | them to think on it, stew on it and work with it with me. Um but it did slow things down quite a 321.46s - 330.31s | bit. So I


chunk_id: 163_chunk_5
chunk_text:
that basically. Moving right along. Alright so the goal for me in this project that 273.78s - 278.78s | I'm talking about is to gain access to the code that calculates the seed key exchange or the 281.28s - 285.92s | authentication mechanism. Uh there are many different things that that can go into that but I 285.92s - 290.86s | don't care. I want them all. Uh this this all started a couple years ago when one 290.86s - 297.54s | manufacturer that we already had access to added a new authentication mechanism that we didn't 297.54s - 302.94s | have access to and so it's like we gotta have this and then I made the I made the, I won't say 302.94s - 309.72s | mistake, I made the decision to use this as a mentoring tool. Instead of going hog wild after it, 309.72s - 314.46s | I leaned into other people who are very capable, very skilled, very passionate and I allowed 314.46s - 319.46s | them to think on it, stew on it and work with it with me. Um but it did slow things down quite a 321.46s - 330.31s | bit. So I don't know if you can see this. If you can't, I apologize. Basically this is showing 330.31s - 337.31s | an obfuscated program. So when you install this tool, I'm I'm not gonna mention who, the tool 337.31s - 344.05s | has one executable program on a Windows pro uh on a Wi- Windows system and as soon as you load 344.05s - 350.55s | it up in your favorite disassembler, the entry code does some weird stuff. It pushes a value 350.55s - 356.29s | onto the stack, it makes a call and then it has a return. Well that call is literally a return. 356.29s - 364.29s | It's a no op call. So what happens when you push something on the stack and then you return? 364.29s - 369.57s | Well that's a jump. It's very common to uh to it's a common thing to use to obfuscate what 369.59s - 375.49s | you're trying to do. Malware does this, uh software does this. And it's the makings of a very 375.49s - 382.51s | long day. Now there are a number of ways to deal with obfuscated programs. Uh more than I 382.51s - 386.85s |


chunk_id: 163_chunk_6
chunk_text:
don't know if you can see this. If you can't, I apologize. Basically this is showing 330.31s - 337.31s | an obfuscated program. So when you install this tool, I'm I'm not gonna mention who, the tool 337.31s - 344.05s | has one executable program on a Windows pro uh on a Wi- Windows system and as soon as you load 344.05s - 350.55s | it up in your favorite disassembler, the entry code does some weird stuff. It pushes a value 350.55s - 356.29s | onto the stack, it makes a call and then it has a return. Well that call is literally a return. 356.29s - 364.29s | It's a no op call. So what happens when you push something on the stack and then you return? 364.29s - 369.57s | Well that's a jump. It's very common to uh to it's a common thing to use to obfuscate what 369.59s - 375.49s | you're trying to do. Malware does this, uh software does this. And it's the makings of a very 375.49s - 382.51s | long day. Now there are a number of ways to deal with obfuscated programs. Uh more than I 382.51s - 386.85s | listed here but these are the two that hit my brain. They they tickle my fancy. I like to 386.85s - 392.05s | emulate through things and do analysis through emulation. You probably heard a talk or two from 392.05s - 396.65s | me on that. And what I'm calling snatch and grab and that's actually what we're gonna talk about 396.67s - 403.05s | here today. Uh from an emulator perspective you might spin up QMU. QMU allows you to do all 403.05s - 409.25s | sorts of cool emulation things and it builds in a GDB debugger component where you can halt 409.25s - 415.03s | something and do twiddle and and all sorts of fun stuff. Maybe kernel debugging if if if we 415.03s - 421.53s | ever get to a point where uh where anti-debugging is really good enough to stop me from using 421.55s - 426.99s | this type of uh uh this type of mechanism then kernel debugging will be another option. 426.99s - 431.63s | Vivisection has a lot of cool stuff. A tool that I that I released and and actually spoke 431.63s - 438.41s | about last week at Black Hat.


chunk_id: 163_chunk_7
chunk_text:
listed here but these are the two that hit my brain. They they tickle my fancy. I like to 386.85s - 392.05s | emulate through things and do analysis through emulation. You probably heard a talk or two from 392.05s - 396.65s | me on that. And what I'm calling snatch and grab and that's actually what we're gonna talk about 396.67s - 403.05s | here today. Uh from an emulator perspective you might spin up QMU. QMU allows you to do all 403.05s - 409.25s | sorts of cool emulation things and it builds in a GDB debugger component where you can halt 409.25s - 415.03s | something and do twiddle and and all sorts of fun stuff. Maybe kernel debugging if if if we 415.03s - 421.53s | ever get to a point where uh where anti-debugging is really good enough to stop me from using 421.55s - 426.99s | this type of uh uh this type of mechanism then kernel debugging will be another option. 426.99s - 431.63s | Vivisection has a lot of cool stuff. A tool that I that I released and and actually spoke 431.63s - 438.41s | about last week at Black Hat. But not this time. No emulation in the initial things anyway. 438.41s - 443.41s | Emulation plays into pretty much everything that I do but not for this. So snatch and grab. 443.53s - 448.53s | So snatch and grab. Basically you start up the program. You run it. You attach you you connect 452.27s - 458.01s | it to the vehicle. You get all the functionality that you're really into. And you make sure 458.01s - 463.01s | that it's all working. It's all obviously able to be executed. You attach with a debugger and 467.20s - 472.20s | there are issues that that go around this but uh uh anti-debugging who's heard of it? Anybody 472.32s - 477.32s | uh tried to get around anti-debugging techniques? Well we're not even gonna worry about it. We 481.50s - 486.30s | attach it is very difficult to make it so you can't attach. If you can't if you actually can't 486.30s - 491.30s | attach then kernel debugging becomes a thing. Then we grab all the data and we store it and 495.18s - 501.55s | analyze it. I mean it sounds simple right? So for this I used a


chunk_id: 163_chunk_8
chunk_text:
But not this time. No emulation in the initial things anyway. 438.41s - 443.41s | Emulation plays into pretty much everything that I do but not for this. So snatch and grab. 443.53s - 448.53s | So snatch and grab. Basically you start up the program. You run it. You attach you you connect 452.27s - 458.01s | it to the vehicle. You get all the functionality that you're really into. And you make sure 458.01s - 463.01s | that it's all working. It's all obviously able to be executed. You attach with a debugger and 467.20s - 472.20s | there are issues that that go around this but uh uh anti-debugging who's heard of it? Anybody 472.32s - 477.32s | uh tried to get around anti-debugging techniques? Well we're not even gonna worry about it. We 481.50s - 486.30s | attach it is very difficult to make it so you can't attach. If you can't if you actually can't 486.30s - 491.30s | attach then kernel debugging becomes a thing. Then we grab all the data and we store it and 495.18s - 501.55s | analyze it. I mean it sounds simple right? So for this I used a tool called Vivisect my 501.57s - 507.67s | favorite uh reversing tool. Vivisect has a built in vulnerability debugger. So we use VDB 507.67s - 514.45s | attached to the running program. Dump what the reason I wanted to use VDB is because VDB has a 514.45s - 519.45s | V snapshot. V plays into everything. It's kinda like V for Vendetta but Visigoth. Um and then 523.77s - 531.78s | magic happens. So here's a picture. If that's too much on my chart here's here's a closer 531.80s - 536.80s | picture. Basically it's just an attach and we say as soon as the attach is done run snapshot 540.44s - 545.94s | and it dumps all the memory maps out to a file including processor state and and so on so 545.94s - 554.20s | forth. So that we can easily analyze the full system state at that point. And here's the actual 554.20s - 559.22s | I had to zoom in yet again. So snapshot target dot vsnap. The next step was to import the data 565.18s - 570.18s | from the snapshot into a Vivisect workspace. Vivisect workspaces is basically holds all the 573.38s - 578.26s


chunk_id: 163_chunk_9
chunk_text:
tool called Vivisect my 501.57s - 507.67s | favorite uh reversing tool. Vivisect has a built in vulnerability debugger. So we use VDB 507.67s - 514.45s | attached to the running program. Dump what the reason I wanted to use VDB is because VDB has a 514.45s - 519.45s | V snapshot. V plays into everything. It's kinda like V for Vendetta but Visigoth. Um and then 523.77s - 531.78s | magic happens. So here's a picture. If that's too much on my chart here's here's a closer 531.80s - 536.80s | picture. Basically it's just an attach and we say as soon as the attach is done run snapshot 540.44s - 545.94s | and it dumps all the memory maps out to a file including processor state and and so on so 545.94s - 554.20s | forth. So that we can easily analyze the full system state at that point. And here's the actual 554.20s - 559.22s | I had to zoom in yet again. So snapshot target dot vsnap. The next step was to import the data 565.18s - 570.18s | from the snapshot into a Vivisect workspace. Vivisect workspaces is basically holds all the 573.38s - 578.26s | things that you're analyzing when working with Vivisect doing reverse engineering. And you can 578.26s - 582.96s | use this for many many things including symbolic analysis and emulation but we won't get there 582.96s - 587.96s | right now. Uh it's basically it was a manual process when I started this. Uh it's continued to 588.96s - 593.96s | take shape. This will be wrapped into uh this will be wrapped into Vivisection shortly. Like 597.98s - 604.77s | within a week or two. I will be releasing next week. So basically we copy all of the memory 607.41s - 612.41s | maps. Who? Show of hands. Who's done debugging before and understands what a memory map is? 613.41s - 618.41s | If you do like infill proc maps in GDB or cat in a Linux system with a proc file system, cat 623.15s - 628.15s | slash proc slash pid slash maps and it'll list. Here are the different memory maps that exist. 630.39s - 636.03s | These four or five are from this program or this library and whatnot and so forth. That's what 636.03s - 641.43s | I'm talking about. So we we just take


chunk_id: 163_chunk_10
chunk_text:
| things that you're analyzing when working with Vivisect doing reverse engineering. And you can 578.26s - 582.96s | use this for many many things including symbolic analysis and emulation but we won't get there 582.96s - 587.96s | right now. Uh it's basically it was a manual process when I started this. Uh it's continued to 588.96s - 593.96s | take shape. This will be wrapped into uh this will be wrapped into Vivisection shortly. Like 597.98s - 604.77s | within a week or two. I will be releasing next week. So basically we copy all of the memory 607.41s - 612.41s | maps. Who? Show of hands. Who's done debugging before and understands what a memory map is? 613.41s - 618.41s | If you do like infill proc maps in GDB or cat in a Linux system with a proc file system, cat 623.15s - 628.15s | slash proc slash pid slash maps and it'll list. Here are the different memory maps that exist. 630.39s - 636.03s | These four or five are from this program or this library and whatnot and so forth. That's what 636.03s - 641.43s | I'm talking about. So we we just take that's all been snapshotted away. We grab the snapshot 641.43s - 646.43s | memory maps. We copy them into a Vivisect workspace and then we do a little magic that says we 650.17s - 655.17s | have all the data. The PE that's been loaded into memory has all of its own data. Symbol data, 657.51s - 662.51s | names, things like that. And we tell the workspace to just steal that data. I'm giving you 662.51s - 667.51s | eye charts. We're skipping over quite a few slides here because at the end of the day, this was 675.99s - 680.99s | stolen from the built-in Vivisect parser. We just removed a few things that loaded the memory 683.69s - 688.59s | maps back in again. And that's the thing that I'm going to be wrapping into Vivisection. Reach 688.61s - 693.05s | out to me if you want it. You've got contact information for me on the slides. The slides 693.05s - 698.05s | should be available online. Okay. So there are a number of different ways that obfuscation is 701.79s - 706.79s | generally done. Any malware reverse engineers here? How about malware forward engineers? So 712.75s


chunk_id: 163_chunk_11
chunk_text:
that's all been snapshotted away. We grab the snapshot 641.43s - 646.43s | memory maps. We copy them into a Vivisect workspace and then we do a little magic that says we 650.17s - 655.17s | have all the data. The PE that's been loaded into memory has all of its own data. Symbol data, 657.51s - 662.51s | names, things like that. And we tell the workspace to just steal that data. I'm giving you 662.51s - 667.51s | eye charts. We're skipping over quite a few slides here because at the end of the day, this was 675.99s - 680.99s | stolen from the built-in Vivisect parser. We just removed a few things that loaded the memory 683.69s - 688.59s | maps back in again. And that's the thing that I'm going to be wrapping into Vivisection. Reach 688.61s - 693.05s | out to me if you want it. You've got contact information for me on the slides. The slides 693.05s - 698.05s | should be available online. Okay. So there are a number of different ways that obfuscation is 701.79s - 706.79s | generally done. Any malware reverse engineers here? How about malware forward engineers? So 712.75s - 717.83s | there are three primary ones that I run into when I've done malware reversing or 717.85s - 722.85s | obfuscation. The first one is unpack or decrypt in place. So the program runs, loads up, the 726.19s - 731.19s | loader creates these memory maps and the initial part of the code does a lot of really annoying 733.83s - 738.83s | things but then it gets to a point where it decrypts itself into the existing memory maps. So 742.13s - 746.41s | that's one thing to be looking for because we're always looking for what's important. What are 746.45s - 751.33s | we interested in? The next one is to unpack or decrypt into new memory maps. So it just calls 751.33s - 756.33s | basically give me a new memory map, I will shit my stuff into it and then we'll execute from 756.33s - 761.07s | there. So anonymous memory maps may be very interesting as well. You have, you have named 761.07s - 767.97s | memory maps, you have anonymous memory maps. And then process hollowing or some variation 767.97s - 773.49s | thereof. So let's say you've got your malware or


chunk_id: 163_chunk_12
chunk_text:
- 717.83s | there are three primary ones that I run into when I've done malware reversing or 717.85s - 722.85s | obfuscation. The first one is unpack or decrypt in place. So the program runs, loads up, the 726.19s - 731.19s | loader creates these memory maps and the initial part of the code does a lot of really annoying 733.83s - 738.83s | things but then it gets to a point where it decrypts itself into the existing memory maps. So 742.13s - 746.41s | that's one thing to be looking for because we're always looking for what's important. What are 746.45s - 751.33s | we interested in? The next one is to unpack or decrypt into new memory maps. So it just calls 751.33s - 756.33s | basically give me a new memory map, I will shit my stuff into it and then we'll execute from 756.33s - 761.07s | there. So anonymous memory maps may be very interesting as well. You have, you have named 761.07s - 767.97s | memory maps, you have anonymous memory maps. And then process hollowing or some variation 767.97s - 773.49s | thereof. So let's say you've got your malware or your, your obfuscated thing, starts another 773.49s - 778.51s | process and then decrypts its stuff across into that other process much like a debugger would. 781.01s - 786.01s | So these are all interesting things we're looking for. There are many variations on it. And 787.21s - 792.21s | determine very quickly by comparing what I had dumped into the vivisect workspace to what the 794.29s - 799.29s | original binary loaded in the vivisect workspace. And this was a decrypt in place binary. So 799.29s - 804.29s | that gives me an understanding of at least where I do need to focus. Maybe, maybe not 807.67s - 813.41s | cutting out where I don't. So let's go searching for things. Reversing, reverse engineering. 813.41s - 818.41s | You load a thing up into, into Ghidra or Ida or Binja and you want to do things, how do you, how 821.25s - 826.25s | do you do those things? I, I want to go find hex UDS things, hex 29, hex 27 as immediate 826.61s - 832.86s | constants. Uh oh. You see, we don't know anything about what we just dumped into the 836.30s - 842.28s | workspace.


chunk_id: 163_chunk_13
chunk_text:
your, your obfuscated thing, starts another 773.49s - 778.51s | process and then decrypts its stuff across into that other process much like a debugger would. 781.01s - 786.01s | So these are all interesting things we're looking for. There are many variations on it. And 787.21s - 792.21s | determine very quickly by comparing what I had dumped into the vivisect workspace to what the 794.29s - 799.29s | original binary loaded in the vivisect workspace. And this was a decrypt in place binary. So 799.29s - 804.29s | that gives me an understanding of at least where I do need to focus. Maybe, maybe not 807.67s - 813.41s | cutting out where I don't. So let's go searching for things. Reversing, reverse engineering. 813.41s - 818.41s | You load a thing up into, into Ghidra or Ida or Binja and you want to do things, how do you, how 821.25s - 826.25s | do you do those things? I, I want to go find hex UDS things, hex 29, hex 27 as immediate 826.61s - 832.86s | constants. Uh oh. You see, we don't know anything about what we just dumped into the 836.30s - 842.28s | workspace. There's no code that's been identified. There are no strings that have been 842.28s - 847.28s | identified. Like you can, you can manually go, manually go through the like the 30 meg of 848.72s - 853.72s | memory maps and manually look for strings but yeah, I don't have that kind of time. So here 854.24s - 862.41s | actually is, is a picture of vivisect where I'm looking at a string that I want to find. But 864.83s - 871.11s | it's not identified as a string. In fact, nothing is except stuff that the loader told me was a 872.81s - 880.14s | string by going through the magic that we did before. So here's a different view of it. Maybe 881.48s - 886.48s | you, maybe you prefer this view. And of course my laser pointer cannot show up on the screen. 886.50s - 893.49s | So on the right hand side, if you can see this slide and you have great eyes, uh, you can see 895.03s - 900.63s | near the bottom, there starts to be some ASCII string looking things. Okay, really nifty. 900.63s - 905.51s | Including security array. I'm very interested


chunk_id: 163_chunk_14
chunk_text:
There's no code that's been identified. There are no strings that have been 842.28s - 847.28s | identified. Like you can, you can manually go, manually go through the like the 30 meg of 848.72s - 853.72s | memory maps and manually look for strings but yeah, I don't have that kind of time. So here 854.24s - 862.41s | actually is, is a picture of vivisect where I'm looking at a string that I want to find. But 864.83s - 871.11s | it's not identified as a string. In fact, nothing is except stuff that the loader told me was a 872.81s - 880.14s | string by going through the magic that we did before. So here's a different view of it. Maybe 881.48s - 886.48s | you, maybe you prefer this view. And of course my laser pointer cannot show up on the screen. 886.50s - 893.49s | So on the right hand side, if you can see this slide and you have great eyes, uh, you can see 895.03s - 900.63s | near the bottom, there starts to be some ASCII string looking things. Okay, really nifty. 900.63s - 905.51s | Including security array. I'm very interested in security array. Anything that starts in 905.51s - 911.65s | security is very um, uh, interesting to me. But unfortunately, viv doesn't know that that's a 911.65s - 918.63s | string yet. When I first did this, I actually just saved the workspace out and the workspace 918.65s - 923.65s | is unencrypted. And I just ran strings literally on the workspace to get an idea of what was 925.19s - 930.19s | there. Because they were decrypted. They were de-obfuscated. And when I found an interesting 931.33s - 936.33s | thing, and there are millions of strings. When I found an interesting thing, I went back into 937.53s - 942.53s | vivisect and found, hi there. I held down the wrong button. Are we back? No, not yet. What? Of 942.65s - 979.49s | course it is. I probably see it just as easily too. New pointer. I apologize. Not used to it yet. 1009.26s - 1022.67s | Okay. It does go fast though. So once I found a string that was interesting, I'd go into the 1022.67s - 1026.51s | vivisect CLI. There's a command line at the bottom and I just type search and I look


chunk_id: 163_chunk_15
chunk_text:
in security array. Anything that starts in 905.51s - 911.65s | security is very um, uh, interesting to me. But unfortunately, viv doesn't know that that's a 911.65s - 918.63s | string yet. When I first did this, I actually just saved the workspace out and the workspace 918.65s - 923.65s | is unencrypted. And I just ran strings literally on the workspace to get an idea of what was 925.19s - 930.19s | there. Because they were decrypted. They were de-obfuscated. And when I found an interesting 931.33s - 936.33s | thing, and there are millions of strings. When I found an interesting thing, I went back into 937.53s - 942.53s | vivisect and found, hi there. I held down the wrong button. Are we back? No, not yet. What? Of 942.65s - 979.49s | course it is. I probably see it just as easily too. New pointer. I apologize. Not used to it yet. 1009.26s - 1022.67s | Okay. It does go fast though. So once I found a string that was interesting, I'd go into the 1022.67s - 1026.51s | vivisect CLI. There's a command line at the bottom and I just type search and I look for that 1026.51s - 1035.26s | string. It shows up and I can start turning it into strings by pressing S. All right, about a 1035.26s - 1040.26s | week ago I wrote a vivisection plugin component that allows me just to do that and make that 1040.94s - 1047.76s | available to you guys as well. The vivisection scan for strings. It brings up a starting memory 1049.20s - 1054.04s | map, an ending memory map, and if that's not granular enough, a starting address and an ending 1054.04s - 1058.84s | address, do you want to apply the strings when you find them? Like shove them into the 1058.84s - 1063.84s | workspace? And I said no. Because it turns out strings captures a whole bunch of binary 1064.50s - 1069.50s | code that just kind of happens to be alphanumeric. So let's take a look at this. I'm 1072.14s - 1077.82s | looking for ASCII strings. I can look for unicode and it allows you to set the minimum size 1077.82s - 1084.28s | defaults to five characters. That's generally good for me. So when we're done, if you can see 1084.28s - 1092.17s | this over


chunk_id: 163_chunk_16
chunk_text:
for that 1026.51s - 1035.26s | string. It shows up and I can start turning it into strings by pressing S. All right, about a 1035.26s - 1040.26s | week ago I wrote a vivisection plugin component that allows me just to do that and make that 1040.94s - 1047.76s | available to you guys as well. The vivisection scan for strings. It brings up a starting memory 1049.20s - 1054.04s | map, an ending memory map, and if that's not granular enough, a starting address and an ending 1054.04s - 1058.84s | address, do you want to apply the strings when you find them? Like shove them into the 1058.84s - 1063.84s | workspace? And I said no. Because it turns out strings captures a whole bunch of binary 1064.50s - 1069.50s | code that just kind of happens to be alphanumeric. So let's take a look at this. I'm 1072.14s - 1077.82s | looking for ASCII strings. I can look for unicode and it allows you to set the minimum size 1077.82s - 1084.28s | defaults to five characters. That's generally good for me. So when we're done, if you can see 1084.28s - 1092.17s | this over here, because I told it not to apply the strings, it popped up a GUI, a widget that 1092.17s - 1096.59s | just printed out. Here's the location. Here's the strings. I did not make it so that you 1096.59s - 1102.13s | could click on the uh on the location yet. Uh that's coming next week. It's been very busy. 1102.13s - 1108.37s | Um so I get an idea and I'm able to scroll through and go oh this chunk of code is actually or 1108.37s - 1117.76s | this chunk of strings is really not strings. So I don't want all the strings so I zero in on a 1117.76s - 1123.36s | memory address range where I'm confident that those strings are what I want and they are real 1123.40s - 1132.53s | strings. So now I have strings. Look security access is right there. DPF soot PC uh automotive 1135.41s - 1141.45s | stuff. If that makes you happy that makes you happy. Um but I see some interesting things that 1141.45s - 1149.09s | aren't strings and I'm I'm curious about them. We'll come back to it. X86 32 or 64 bit doesn't 1149.09s


chunk_id: 163_chunk_17
chunk_text:
here, because I told it not to apply the strings, it popped up a GUI, a widget that 1092.17s - 1096.59s | just printed out. Here's the location. Here's the strings. I did not make it so that you 1096.59s - 1102.13s | could click on the uh on the location yet. Uh that's coming next week. It's been very busy. 1102.13s - 1108.37s | Um so I get an idea and I'm able to scroll through and go oh this chunk of code is actually or 1108.37s - 1117.76s | this chunk of strings is really not strings. So I don't want all the strings so I zero in on a 1117.76s - 1123.36s | memory address range where I'm confident that those strings are what I want and they are real 1123.40s - 1132.53s | strings. So now I have strings. Look security access is right there. DPF soot PC uh automotive 1135.41s - 1141.45s | stuff. If that makes you happy that makes you happy. Um but I see some interesting things that 1141.45s - 1149.09s | aren't strings and I'm I'm curious about them. We'll come back to it. X86 32 or 64 bit doesn't 1149.09s - 1154.09s | matter. It's a variable length instruction set and it's really important that we get it right so 1154.83s - 1159.83s | that when we call something code it is code indeed. So if you get off by one byte you can tank 1164.61s - 1171.24s | an entire understanding of a segment of code. So how do we accurately identify code? Well it 1174.72s - 1179.72s | turns out there are 12 stack areas. Alright I gave you a hint. Actually I'm taking hands. How do 1179.72s - 1184.72s | I identify known good code? Yell it out. Look do you know how many things are good op codes 1195.01s - 1206.44s | that are not real? What's that? Ding ding ding give Travis a big hug. I'll get you later. Um 1209.28s - 1214.28s | yes. So with the hint he didn't need it. Uh we have 12 stacks identified. One for each thread 1215.14s - 1220.14s | that's running in the program in the system. Each one has its own stack. In the stack what's 1223.62s - 1228.62s | stored there? Return pointers. And a whole bunch of other fucking pointers that are very 1230.72s


chunk_id: 163_chunk_18
chunk_text:
- 1154.09s | matter. It's a variable length instruction set and it's really important that we get it right so 1154.83s - 1159.83s | that when we call something code it is code indeed. So if you get off by one byte you can tank 1164.61s - 1171.24s | an entire understanding of a segment of code. So how do we accurately identify code? Well it 1174.72s - 1179.72s | turns out there are 12 stack areas. Alright I gave you a hint. Actually I'm taking hands. How do 1179.72s - 1184.72s | I identify known good code? Yell it out. Look do you know how many things are good op codes 1195.01s - 1206.44s | that are not real? What's that? Ding ding ding give Travis a big hug. I'll get you later. Um 1209.28s - 1214.28s | yes. So with the hint he didn't need it. Uh we have 12 stacks identified. One for each thread 1215.14s - 1220.14s | that's running in the program in the system. Each one has its own stack. In the stack what's 1223.62s - 1228.62s | stored there? Return pointers. And a whole bunch of other fucking pointers that are very 1230.72s - 1235.72s | annoying and they're all large but it's a great teaching thing. How do I know if a pointer is a 1236.08s - 1241.08s | return? Well first of all we go to the pointer. And on the top you see a 32 bit representation 1246.52s - 1251.52s | of stuff around the stack. At this address 3F7FDD4 we see a an address 5143A6. It's blue 1255.86s - 1262.33s | because that's a valid memory address. Then we back up. Two bytes. And see if it disassembles. 1262.45s - 1267.45s | And now we're into what you're saying but it's we're into what you were saying a second ago but 1269.59s - 1274.79s | there's more to it. So sorry if I if I should shut you down too quickly. So we back up two 1274.79s - 1279.79s | bytes. Why? Because the smallest the smallest call in x86 is two bytes long. The longest call 1281.57s - 1286.57s | is like eight bytes. So we back up two bytes. Does it disassemble into a call? Yes! Okay 1286.85s - 1291.85s | cool. Now wait. Does that call stop? Because everyone's got its own size. Does it stop


chunk_id: 163_chunk_19
chunk_text:
- 1235.72s | annoying and they're all large but it's a great teaching thing. How do I know if a pointer is a 1236.08s - 1241.08s | return? Well first of all we go to the pointer. And on the top you see a 32 bit representation 1246.52s - 1251.52s | of stuff around the stack. At this address 3F7FDD4 we see a an address 5143A6. It's blue 1255.86s - 1262.33s | because that's a valid memory address. Then we back up. Two bytes. And see if it disassembles. 1262.45s - 1267.45s | And now we're into what you're saying but it's we're into what you were saying a second ago but 1269.59s - 1274.79s | there's more to it. So sorry if I if I should shut you down too quickly. So we back up two 1274.79s - 1279.79s | bytes. Why? Because the smallest the smallest call in x86 is two bytes long. The longest call 1281.57s - 1286.57s | is like eight bytes. So we back up two bytes. Does it disassemble into a call? Yes! Okay 1286.85s - 1291.85s | cool. Now wait. Does that call stop? Because everyone's got its own size. Does it stop at the 1296.79s - 1302.03s | pointer that we're trying to investigate? No. Shit. Go back. Okay. Three bytes. Four bytes. 1302.03s - 1307.03s | Five. Six bytes. Whatever. We get a call. The instruction itself ends at the boundary where the 1309.27s - 1314.57s | pointer is pointing. Because that's what the that's what a return call is is to go to the next 1314.61s - 1324.44s | thing. And that is a pretty good likelihood that that's a return pointer. So I go to that 1324.44s - 1329.44s | location and I say C to make code. And sure enough we have a call to this address which is also 1332.38s - 1337.38s | valid. We have a jump after that. And then basically a a drop down to a ret. So this is looking 1341.32s - 1346.32s | very much like very good code. But that is a fuck ton of work. And after less than a minute 1348.76s - 1353.76s | of putting my mentee uh stew on it for for a day, I gave her a script and said so here's a 1356.00s - 1360.10s | script that'll kind of do that manually for or


chunk_id: 163_chunk_20
chunk_text:
at the 1296.79s - 1302.03s | pointer that we're trying to investigate? No. Shit. Go back. Okay. Three bytes. Four bytes. 1302.03s - 1307.03s | Five. Six bytes. Whatever. We get a call. The instruction itself ends at the boundary where the 1309.27s - 1314.57s | pointer is pointing. Because that's what the that's what a return call is is to go to the next 1314.61s - 1324.44s | thing. And that is a pretty good likelihood that that's a return pointer. So I go to that 1324.44s - 1329.44s | location and I say C to make code. And sure enough we have a call to this address which is also 1332.38s - 1337.38s | valid. We have a jump after that. And then basically a a drop down to a ret. So this is looking 1341.32s - 1346.32s | very much like very good code. But that is a fuck ton of work. And after less than a minute 1348.76s - 1353.76s | of putting my mentee uh stew on it for for a day, I gave her a script and said so here's a 1356.00s - 1360.10s | script that'll kind of do that manually for or automatically for you. And that script I was 1360.10s - 1364.38s | going to include in the deck here I am not because I wrapped it into vivisection. You'll get 1364.38s - 1369.38s | to see that when I cut the next release. But whoops. Here's the problem. When I did that, code 1370.38s - 1375.38s | started getting identified. Cross references, strings, like magic was happening and then boom 1381.68s - 1391.04s | out of memory. I ended up uh analyzing this overnight on a machine where I gave myself an 80 1391.04s - 1396.04s | gig swap space just to see if it would work. Binja did the same thing. Barfed. And most of my 1397.00s - 1404.01s | work ended up being on a 500 plus megabyte workspace. Which I don't know about you or how 1408.01s - 1414.03s | how big your workspaces are but this takes 10 minutes to load. And if I'm doing it over a 1414.03s - 1419.67s | network because vivisect has a vivisect server and client mode, it takes 45 minutes to load. 1419.67s - 1424.67s | Okay. Need to work on this one. And we're in uncut territory here. That's


chunk_id: 163_chunk_21
chunk_text:
automatically for you. And that script I was 1360.10s - 1364.38s | going to include in the deck here I am not because I wrapped it into vivisection. You'll get 1364.38s - 1369.38s | to see that when I cut the next release. But whoops. Here's the problem. When I did that, code 1370.38s - 1375.38s | started getting identified. Cross references, strings, like magic was happening and then boom 1381.68s - 1391.04s | out of memory. I ended up uh analyzing this overnight on a machine where I gave myself an 80 1391.04s - 1396.04s | gig swap space just to see if it would work. Binja did the same thing. Barfed. And most of my 1397.00s - 1404.01s | work ended up being on a 500 plus megabyte workspace. Which I don't know about you or how 1408.01s - 1414.03s | how big your workspaces are but this takes 10 minutes to load. And if I'm doing it over a 1414.03s - 1419.67s | network because vivisect has a vivisect server and client mode, it takes 45 minutes to load. 1419.67s - 1424.67s | Okay. Need to work on this one. And we're in uncut territory here. That's fine I guess. So 1428.57s - 1434.57s | it also makes function recon completely useless. I don't know. I just released function 1434.57s - 1439.15s | recon in vivisection so you might not have had a chance to use it. But function recon basically 1439.15s - 1444.15s | straps in a specialized partial emulator into a function. And it follows every code path exactly 1448.39s - 1454.89s | once. And then every call it does that too and it keeps going and going and going until it runs 1454.91s - 1460.31s | out of code to hit. And it captures things like what strings did I run into? What function 1460.31s - 1466.61s | calls did I run to? What named functions did I call? Basically, reconnaissance on what a 1466.61s - 1473.29s | given subset of a program is going to do. Function recon is worthless on this binary. Or on 1473.29s - 1481.66s | this workspace. Because I analyzed all of NTDLL and user 32 and kernel 32 and all the things 1481.66s - 1486.42s | that I really don't give a shit about. Because it turns out we know what that is. That's not 1487.16s - 1492.64s


chunk_id: 163_chunk_22
chunk_text:
fine I guess. So 1428.57s - 1434.57s | it also makes function recon completely useless. I don't know. I just released function 1434.57s - 1439.15s | recon in vivisection so you might not have had a chance to use it. But function recon basically 1439.15s - 1444.15s | straps in a specialized partial emulator into a function. And it follows every code path exactly 1448.39s - 1454.89s | once. And then every call it does that too and it keeps going and going and going until it runs 1454.91s - 1460.31s | out of code to hit. And it captures things like what strings did I run into? What function 1460.31s - 1466.61s | calls did I run to? What named functions did I call? Basically, reconnaissance on what a 1466.61s - 1473.29s | given subset of a program is going to do. Function recon is worthless on this binary. Or on 1473.29s - 1481.66s | this workspace. Because I analyzed all of NTDLL and user 32 and kernel 32 and all the things 1481.66s - 1486.42s | that I really don't give a shit about. Because it turns out we know what that is. That's not 1487.16s - 1492.64s | obfuscated. That would be a really dirty trick. But I mean, I did check. This is legitimate 1492.64s - 1500.66s | NTDLL and whatnot. So sometime by next week I could probably get done with function recon. But I 1504.04s - 1510.04s | think I'd like to make a change and not do that. Oh and I broke the viv server. Didn't not just 1510.24s - 1516.24s | work, it literally broke it where it would not try to send the data over the network. So I ended 1521.58s - 1532.87s | up fixing that. That was months ago. So I did wrap this into vivisection because the goal of 1532.87s - 1539.13s | vivisection is to kill all tedium and brain drain. We need your brains to be able to chew on 1539.15s - 1545.15s | the more important things, not just do these tedious horrible things. And we focus on 1546.77s - 1553.69s | starting maps and ending maps for stack. So we look for the pointers here. And we can restrict 1553.69s - 1558.41s | where the pointers can point to that we care about. So that we can skip NTDLL. We can skip 1558.41s -


chunk_id: 163_chunk_23
chunk_text:
| obfuscated. That would be a really dirty trick. But I mean, I did check. This is legitimate 1492.64s - 1500.66s | NTDLL and whatnot. So sometime by next week I could probably get done with function recon. But I 1504.04s - 1510.04s | think I'd like to make a change and not do that. Oh and I broke the viv server. Didn't not just 1510.24s - 1516.24s | work, it literally broke it where it would not try to send the data over the network. So I ended 1521.58s - 1532.87s | up fixing that. That was months ago. So I did wrap this into vivisection because the goal of 1532.87s - 1539.13s | vivisection is to kill all tedium and brain drain. We need your brains to be able to chew on 1539.15s - 1545.15s | the more important things, not just do these tedious horrible things. And we focus on 1546.77s - 1553.69s | starting maps and ending maps for stack. So we look for the pointers here. And we can restrict 1553.69s - 1558.41s | where the pointers can point to that we care about. So that we can skip NTDLL. We can skip 1558.41s - 1564.41s | kernel 32 DLL. Then I have a pull request in for the vivisect proper to allow us to turn on 1569.45s - 1576.89s | what's called one library. So that when you analyze a function and it hits outside that library, 1576.89s - 1583.27s | it jumps or it calls into NTDLL for example. It just stops. Because the NTDLL is going to have a 1583.27s - 1593.43s | name and that's kind of how we do reversing, right? So next, once we found strings, we have 1593.43s - 1599.35s | this one problem. There's no cross references. So the idea is we go to a string and then we have 1599.37s - 1604.75s | code that references the string. And so the code is instantly interesting to me. Nothing is 1604.75s - 1611.63s | referring to these strings. We just told them that it was strings. Okay. Now what? Well, while 1611.63s - 1618.23s | doing this in this particular tool, I noticed that around these groupings of strings that were 1618.23s - 1623.65s | very interesting to me were a whole bunch of non-strings. And it didn't look like code either. 1623.83s - 1631.83s | I


chunk_id: 163_chunk_24
chunk_text:
1564.41s | kernel 32 DLL. Then I have a pull request in for the vivisect proper to allow us to turn on 1569.45s - 1576.89s | what's called one library. So that when you analyze a function and it hits outside that library, 1576.89s - 1583.27s | it jumps or it calls into NTDLL for example. It just stops. Because the NTDLL is going to have a 1583.27s - 1593.43s | name and that's kind of how we do reversing, right? So next, once we found strings, we have 1593.43s - 1599.35s | this one problem. There's no cross references. So the idea is we go to a string and then we have 1599.37s - 1604.75s | code that references the string. And so the code is instantly interesting to me. Nothing is 1604.75s - 1611.63s | referring to these strings. We just told them that it was strings. Okay. Now what? Well, while 1611.63s - 1618.23s | doing this in this particular tool, I noticed that around these groupings of strings that were 1618.23s - 1623.65s | very interesting to me were a whole bunch of non-strings. And it didn't look like code either. 1623.83s - 1631.83s | I started seeing a pattern in them. It was number, number, number, zero. Number, number, number, 1631.83s - 1643.83s | zero. Number, number, number, zero. And in this area of code, the address space is held within 1643.99s - 1653.99s | 24 bits. It is, look at the, the address is 0075D289. In fact, the target binary starts at 1653.99s - 1664.37s | 400,000 hex and ends at like 80A000. That was really interesting to me. And as you can see, 1664.37s - 1673.55s | these little byte groupings are valid pointers into this target binary address space. So I 1673.57s - 1678.45s | started going through and just hitting, going to one and hitting P. Make it a pointer. And 1678.45s - 1683.41s | suddenly that P goes through the analysis process for the pointer and it says, oh, suddenly I'm 1683.41s - 1689.75s | pointing at a function. Because it starts with the name sub. Oh, that's, that's curious. So I 1689.75s - 1696.01s | did that with a whole bunch of them. And they were all functions. So much so that I ended up 1696.01s - 1702.47s | writing a vivisection, actually no, I think I wrapped this


chunk_id: 163_chunk_25
chunk_text:
started seeing a pattern in them. It was number, number, number, zero. Number, number, number, 1631.83s - 1643.83s | zero. Number, number, number, zero. And in this area of code, the address space is held within 1643.99s - 1653.99s | 24 bits. It is, look at the, the address is 0075D289. In fact, the target binary starts at 1653.99s - 1664.37s | 400,000 hex and ends at like 80A000. That was really interesting to me. And as you can see, 1664.37s - 1673.55s | these little byte groupings are valid pointers into this target binary address space. So I 1673.57s - 1678.45s | started going through and just hitting, going to one and hitting P. Make it a pointer. And 1678.45s - 1683.41s | suddenly that P goes through the analysis process for the pointer and it says, oh, suddenly I'm 1683.41s - 1689.75s | pointing at a function. Because it starts with the name sub. Oh, that's, that's curious. So I 1689.75s - 1696.01s | did that with a whole bunch of them. And they were all functions. So much so that I ended up 1696.01s - 1702.47s | writing a vivisection, actually no, I think I wrapped this into vivisect itself. Writing code 1702.47s - 1705.67s | that just allows you to make pointers and you just say, here's the start, here's the stop. 1705.67s - 1716.10s | Just make them all pointers. Turns out there are vast arrays of pointers to a whole ton of 1716.10s - 1725.44s | code. They end up being virtual function tables for C++. Is that familiar with anyone? C++ 1725.44s - 1733.65s | reversing. Kudos to you. It's not fun. So we end up with these tables of functions that are 1733.65s - 1741.45s | used, so when you have the class object ball and you want to call the function bounce or get 1741.45s - 1748.53s | color or change color, they're just held in this table here and the code knows that bounce is 1748.53s - 1756.92s | offset four into this table. Make sense? And all of a sudden, while I'm digging through here 1756.92s - 1762.26s | making all sorts of cross, all sorts of pointers, I started seeing cross references to my 1762.26s - 1773.90s | strings. So now I know some code is referring to security array. I'm getting better. Getting 1773.90s - 1780.90s |


chunk_id: 163_chunk_26
chunk_text:
into vivisect itself. Writing code 1702.47s - 1705.67s | that just allows you to make pointers and you just say, here's the start, here's the stop. 1705.67s - 1716.10s | Just make them all pointers. Turns out there are vast arrays of pointers to a whole ton of 1716.10s - 1725.44s | code. They end up being virtual function tables for C++. Is that familiar with anyone? C++ 1725.44s - 1733.65s | reversing. Kudos to you. It's not fun. So we end up with these tables of functions that are 1733.65s - 1741.45s | used, so when you have the class object ball and you want to call the function bounce or get 1741.45s - 1748.53s | color or change color, they're just held in this table here and the code knows that bounce is 1748.53s - 1756.92s | offset four into this table. Make sense? And all of a sudden, while I'm digging through here 1756.92s - 1762.26s | making all sorts of cross, all sorts of pointers, I started seeing cross references to my 1762.26s - 1773.90s | strings. So now I know some code is referring to security array. I'm getting better. Getting 1773.90s - 1780.90s | happier. And then I made this, so here's the vivisect code or functionality to create a 1780.90s - 1786.44s | pointer array. Actually, if you just hold down shift and hit P, capital P is pointer array. 1786.44s - 1791.64s | Pops up a dialogue. Here's a starting address. Here's a stop address. Or if you'd rather this 1791.64s - 1796.64s | many, so you can put in a number into the count and it'll ignore the stop address. It'll just do 1796.64s - 1802.62s | that many. And then if we run into a null pointer, do we care and do we keep going or do we call 1802.62s - 1813.44s | that the end? So these are all useful to me, and so I put them in here. So the vtable entries, I 1813.44s - 1818.94s | don't know if you can see that, but the first entry in most virtual tables is called a 1818.94s - 1828.88s | destructor. C++ programmers? Again? Okay, a number of you. When you create a class, you write code 1828.88s - 1834.92s | for a constructor and a destructor. When you instantiate the object, it runs the constructor, 1834.92s - 1842.02s


chunk_id: 163_chunk_27
chunk_text:
happier. And then I made this, so here's the vivisect code or functionality to create a 1780.90s - 1786.44s | pointer array. Actually, if you just hold down shift and hit P, capital P is pointer array. 1786.44s - 1791.64s | Pops up a dialogue. Here's a starting address. Here's a stop address. Or if you'd rather this 1791.64s - 1796.64s | many, so you can put in a number into the count and it'll ignore the stop address. It'll just do 1796.64s - 1802.62s | that many. And then if we run into a null pointer, do we care and do we keep going or do we call 1802.62s - 1813.44s | that the end? So these are all useful to me, and so I put them in here. So the vtable entries, I 1813.44s - 1818.94s | don't know if you can see that, but the first entry in most virtual tables is called a 1818.94s - 1828.88s | destructor. C++ programmers? Again? Okay, a number of you. When you create a class, you write code 1828.88s - 1834.92s | for a constructor and a destructor. When you instantiate the object, it runs the constructor, 1834.92s - 1842.02s | which basically tells, it sets up the different data structures in place. Creates strings, 1842.02s - 1846.86s | creates subobjects, other things like that. A destructor is tasked with making sure that 1846.86s - 1852.82s | everything gets cleaned up appropriately. So if you have a C++ class that has a bunch of 1852.82s - 1859.46s | strings in it, your destructor will roll through and say, all right, do this destructor thing for 1859.46s - 1866.04s | the strings here, strings there, strings here and otherwise. Or other C++ objects that are 1866.04s - 1881.82s | wrapped in. So the destructor is a highly valuable resource. How much time do I have? I'm 1881.82s - 1890.64s | going faster than I thought. No blood dripping out of your ears? I'm doing good. All right. So 1890.64s - 1895.28s | when we get involved in C++ analysis, no, don't worry, I'm not going to take you too far down 1895.28s - 1901.68s | that road. I didn't warn you enough. And it is, actually, it's another talk. I need to give 1901.68s - 1908.76s | another talk on this particular thing. C++ objects, what creates them? It's really important


chunk_id: 163_chunk_28
chunk_text:
| which basically tells, it sets up the different data structures in place. Creates strings, 1842.02s - 1846.86s | creates subobjects, other things like that. A destructor is tasked with making sure that 1846.86s - 1852.82s | everything gets cleaned up appropriately. So if you have a C++ class that has a bunch of 1852.82s - 1859.46s | strings in it, your destructor will roll through and say, all right, do this destructor thing for 1859.46s - 1866.04s | the strings here, strings there, strings here and otherwise. Or other C++ objects that are 1866.04s - 1881.82s | wrapped in. So the destructor is a highly valuable resource. How much time do I have? I'm 1881.82s - 1890.64s | going faster than I thought. No blood dripping out of your ears? I'm doing good. All right. So 1890.64s - 1895.28s | when we get involved in C++ analysis, no, don't worry, I'm not going to take you too far down 1895.28s - 1901.68s | that road. I didn't warn you enough. And it is, actually, it's another talk. I need to give 1901.68s - 1908.76s | another talk on this particular thing. C++ objects, what creates them? It's really important 1908.76s - 1913.80s | because once you create a C++ object, you just kind of tote it around. You know, I make the 1913.80s - 1921.16s | function call over here, here's a C++ object, and the C++ object, the goal for object-oriented 1921.16s - 1926.52s | programming is that that virtual function table maintains all the logic about how to do 1926.52s - 1932.16s | everything necessary with that object. So it's kind of self-contained. And then I just say, call 1932.16s - 1937.40s | this function on here's my ball, you know, or whatever the object is. And then that function 1937.40s - 1944.20s | says, I know that a ball can do a bounce. I don't have to know what that thing is, you know, what 1944.20s - 1949.88s | goes into bouncing that ball. I know that I can call bounce on that ball and it'll be good. So 1952.16s - 1959.20s | tracing V tables, very, very interesting. So about a dozen years ago, I spent some time writing 1959.20s - 1966.88s | symbolic analysis for structures and building in structure reconstitution, basically. Using a set 1966.88s - 1974.76s | of code and symbolic data


chunk_id: 163_chunk_29
chunk_text:
1908.76s - 1913.80s | because once you create a C++ object, you just kind of tote it around. You know, I make the 1913.80s - 1921.16s | function call over here, here's a C++ object, and the C++ object, the goal for object-oriented 1921.16s - 1926.52s | programming is that that virtual function table maintains all the logic about how to do 1926.52s - 1932.16s | everything necessary with that object. So it's kind of self-contained. And then I just say, call 1932.16s - 1937.40s | this function on here's my ball, you know, or whatever the object is. And then that function 1937.40s - 1944.20s | says, I know that a ball can do a bounce. I don't have to know what that thing is, you know, what 1944.20s - 1949.88s | goes into bouncing that ball. I know that I can call bounce on that ball and it'll be good. So 1952.16s - 1959.20s | tracing V tables, very, very interesting. So about a dozen years ago, I spent some time writing 1959.20s - 1966.88s | symbolic analysis for structures and building in structure reconstitution, basically. Using a set 1966.88s - 1974.76s | of code and symbolic data about what the code is doing. And it's a simple or difficult way of 1974.76s - 1984.40s | saying the symbolic data is this is this pointer plus 12. Instead of this pointer and then a bunch 1984.40s - 1990.72s | of instructions that modify what that register is doing. The symbolic analysis just traces that and 1990.72s - 2003.48s | makes it easy for me to say, oh, this is offset 12 into that structure, all golden. So the first 2003.48s - 2009.80s | thing that I'm wanting to do when I do C++ structure analysis is to go through all the functions in 2009.80s - 2014.96s | the V table, because the V table lists all functions that know how to do that thing with that 2014.96s - 2027.08s | ball. Or that diagnostics utility. I then analyze how this pointer is being accessed. And I can 2027.08s - 2033.28s | identify what things go where in memory. That becomes really important when I'm looking at other 2033.28s - 2046.97s | code so that I know what offset 12 really means. Other things. As I said, the destructor is very, 2046.97s - 2053.41s | very powerful. And I


chunk_id: 163_chunk_30
chunk_text:
about what the code is doing. And it's a simple or difficult way of 1974.76s - 1984.40s | saying the symbolic data is this is this pointer plus 12. Instead of this pointer and then a bunch 1984.40s - 1990.72s | of instructions that modify what that register is doing. The symbolic analysis just traces that and 1990.72s - 2003.48s | makes it easy for me to say, oh, this is offset 12 into that structure, all golden. So the first 2003.48s - 2009.80s | thing that I'm wanting to do when I do C++ structure analysis is to go through all the functions in 2009.80s - 2014.96s | the V table, because the V table lists all functions that know how to do that thing with that 2014.96s - 2027.08s | ball. Or that diagnostics utility. I then analyze how this pointer is being accessed. And I can 2027.08s - 2033.28s | identify what things go where in memory. That becomes really important when I'm looking at other 2033.28s - 2046.97s | code so that I know what offset 12 really means. Other things. As I said, the destructor is very, 2046.97s - 2053.41s | very powerful. And I don't know if you can see that. This is the first function in one of the V 2053.41s - 2060.41s | tables we looked at earlier. And it looks really simple. It calls free object. That's what I call 2060.41s - 2067.25s | it. This is sub underscore some number. So free object. This object. And I like to name things by 2067.25s - 2074.89s | the address of the virtual function table. And then down here, based on what's returned or 2075.25s - 2081.37s | based on the arg one, we decide whether or not to decrement and free that object. Okay. Seems 2081.37s - 2089.37s | simple enough. But free object is where all the really fun magic happens. So free object goes 2089.37s - 2097.05s | through whatever this class or this object is and does the real dirty magic. You'll notice here 2097.05s - 2104.09s | something that is often found in dealing with C++ code. At the top of this little box, there's a 2104.09s - 2113.77s | move D word. So ESI is being used as this pointer right now. And the very first the very first 2113.77s - 2120.69s | pointer in that


chunk_id: 163_chunk_31
chunk_text:
don't know if you can see that. This is the first function in one of the V 2053.41s - 2060.41s | tables we looked at earlier. And it looks really simple. It calls free object. That's what I call 2060.41s - 2067.25s | it. This is sub underscore some number. So free object. This object. And I like to name things by 2067.25s - 2074.89s | the address of the virtual function table. And then down here, based on what's returned or 2075.25s - 2081.37s | based on the arg one, we decide whether or not to decrement and free that object. Okay. Seems 2081.37s - 2089.37s | simple enough. But free object is where all the really fun magic happens. So free object goes 2089.37s - 2097.05s | through whatever this class or this object is and does the real dirty magic. You'll notice here 2097.05s - 2104.09s | something that is often found in dealing with C++ code. At the top of this little box, there's a 2104.09s - 2113.77s | move D word. So ESI is being used as this pointer right now. And the very first the very first 2113.77s - 2120.69s | pointer in that object is a pointer to a virtual function table. And one thing that you'll notice 2120.69s - 2128.69s | is that as C++ code is used in different ways. So, for example, we created the object the class 2128.77s - 2135.25s | ball. And we have a subclass that inherits from it called basketball. And then another one that 2135.25s - 2139.37s | is very different that inherits from ball called football. And if you don't know what the 2139.37s - 2145.05s | difference is there, try to bounce them both. So they both have their own bounce functions. But 2145.05s - 2151.65s | they're both a ball. So sometimes what we'll do is we'll say, yeah, no, I really want the ball 2151.65s - 2158.99s | version of bounce. I don't actually want the basketball to have this control. So oftentimes 2159.03s - 2165.95s | code will jam in the appropriate virtual function table for that when your when your code 2165.95s - 2172.95s | asks for that. So as we're going through this free object, ignore the top. It's basically just 2173.23s - 2179.63s | memory protection things. So we we jam in this virtual table. I just


chunk_id: 163_chunk_32
chunk_text:
object is a pointer to a virtual function table. And one thing that you'll notice 2120.69s - 2128.69s | is that as C++ code is used in different ways. So, for example, we created the object the class 2128.77s - 2135.25s | ball. And we have a subclass that inherits from it called basketball. And then another one that 2135.25s - 2139.37s | is very different that inherits from ball called football. And if you don't know what the 2139.37s - 2145.05s | difference is there, try to bounce them both. So they both have their own bounce functions. But 2145.05s - 2151.65s | they're both a ball. So sometimes what we'll do is we'll say, yeah, no, I really want the ball 2151.65s - 2158.99s | version of bounce. I don't actually want the basketball to have this control. So oftentimes 2159.03s - 2165.95s | code will jam in the appropriate virtual function table for that when your when your code 2165.95s - 2172.95s | asks for that. So as we're going through this free object, ignore the top. It's basically just 2173.23s - 2179.63s | memory protection things. So we we jam in this virtual table. I just call it six because I 2179.63s - 2185.87s | didn't know what to do with it at that point. We then move 16 into EDI. That'll be important 2185.87s - 2196.95s | very, very shortly. We compare EDI to this this plus 608, this six plus this 608 offset. I'll 2196.95s - 2202.83s | tell you in advance the spoilers. It's a string. It's a C++ string, which is not like your 2202.83s - 2212.56s | ASCII string. We then move seven into a local variable and move on. And based on whether or 2212.56s - 2221.68s | not this offset into that this string basically the size of the string is being compared 2221.68s - 2231.08s | against 16. If the string is 16 bytes or more, C++ will create a new object of the right size or 2231.08s - 2238.04s | something that's flexible and move the string into that. If the string is less than 16 bytes, 2238.04s - 2244.96s | then there's enough room in the C++ structure for a string to just house the string. So this 2244.96s - 2251.68s | is why I know this is a string. And that's a very common element


chunk_id: 163_chunk_33
chunk_text:
call it six because I 2179.63s - 2185.87s | didn't know what to do with it at that point. We then move 16 into EDI. That'll be important 2185.87s - 2196.95s | very, very shortly. We compare EDI to this this plus 608, this six plus this 608 offset. I'll 2196.95s - 2202.83s | tell you in advance the spoilers. It's a string. It's a C++ string, which is not like your 2202.83s - 2212.56s | ASCII string. We then move seven into a local variable and move on. And based on whether or 2212.56s - 2221.68s | not this offset into that this string basically the size of the string is being compared 2221.68s - 2231.08s | against 16. If the string is 16 bytes or more, C++ will create a new object of the right size or 2231.08s - 2238.04s | something that's flexible and move the string into that. If the string is less than 16 bytes, 2238.04s - 2244.96s | then there's enough room in the C++ structure for a string to just house the string. So this 2244.96s - 2251.68s | is why I know this is a string. And that's a very common element for C++ reversing. So we 2251.68s - 2257.72s | come down here. If it's greater if it's 16 bytes or greater, then I know that I have a 2257.72s - 2264.20s | pointer to the thing that actually holds the ASCII string. So I free that. And then I move 2264.20s - 2272.40s | down to the next thing. And I compare 15 or I move 15 into EBP. And I shove that all over to 2272.40s - 2278.60s | make sure that this string that we are in the process of deconstructing doesn't ever do that 2278.60s - 2285.00s | again. So it's as soon as we free that memory, we say it's okay, it's 15. That's not true. 2285.00s - 2290.24s | Actually, it's going to be zero. We're going to delete it. But as it moves down, compare EDI 2290.24s - 2298.16s | against another offset. So some other string. We go down because EDI is still 16. So we 2298.16s - 2310.62s | actually see in this particular object multiple points of clearly this is a string. In fact, we 2310.62s - 2316.62s | then run into another embedded object that's special. And we call some


chunk_id: 163_chunk_34
chunk_text:
for C++ reversing. So we 2251.68s - 2257.72s | come down here. If it's greater if it's 16 bytes or greater, then I know that I have a 2257.72s - 2264.20s | pointer to the thing that actually holds the ASCII string. So I free that. And then I move 2264.20s - 2272.40s | down to the next thing. And I compare 15 or I move 15 into EBP. And I shove that all over to 2272.40s - 2278.60s | make sure that this string that we are in the process of deconstructing doesn't ever do that 2278.60s - 2285.00s | again. So it's as soon as we free that memory, we say it's okay, it's 15. That's not true. 2285.00s - 2290.24s | Actually, it's going to be zero. We're going to delete it. But as it moves down, compare EDI 2290.24s - 2298.16s | against another offset. So some other string. We go down because EDI is still 16. So we 2298.16s - 2310.62s | actually see in this particular object multiple points of clearly this is a string. In fact, we 2310.62s - 2316.62s | then run into another embedded object that's special. And we call some code to clean it up. I 2316.62s - 2321.74s | won't go into right now. But then we do another thing. Hey, compare this thing against EDI. EDI 2321.74s - 2331.42s | is still 16. And if it's less than or if it's greater than 16, call decrement and free. And so 2331.42s - 2345.41s | on and so forth. So just to recap C++ reconstitution approach. Look for a whole bunch of 2345.41s - 2353.88s | function pointers. All grouped together. Look for cross references to the start of the branch. 2353.88s - 2360.24s | Is that the beginning of a bunch of pointers? Is that the beginning of a virtual function table? 2360.24s - 2369.16s | Very likely. Kind of investigation is the right key there. Analyze those functions for how they 2369.16s - 2374.80s | deal with the this pointer that's handed in. And every call and convention on every architecture 2374.80s - 2380.72s | has its own this pointer argument. Typically, it's the first one. On 32-bit, you see a lot of 2380.72s - 2386.64s | this call that's ECX. That's why you're seeing that here. So analyze the first function in the 2386.64s - 2394.95s


chunk_id: 163_chunk_35
chunk_text:
code to clean it up. I 2316.62s - 2321.74s | won't go into right now. But then we do another thing. Hey, compare this thing against EDI. EDI 2321.74s - 2331.42s | is still 16. And if it's less than or if it's greater than 16, call decrement and free. And so 2331.42s - 2345.41s | on and so forth. So just to recap C++ reconstitution approach. Look for a whole bunch of 2345.41s - 2353.88s | function pointers. All grouped together. Look for cross references to the start of the branch. 2353.88s - 2360.24s | Is that the beginning of a bunch of pointers? Is that the beginning of a virtual function table? 2360.24s - 2369.16s | Very likely. Kind of investigation is the right key there. Analyze those functions for how they 2369.16s - 2374.80s | deal with the this pointer that's handed in. And every call and convention on every architecture 2374.80s - 2380.72s | has its own this pointer argument. Typically, it's the first one. On 32-bit, you see a lot of 2380.72s - 2386.64s | this call that's ECX. That's why you're seeing that here. So analyze the first function in the 2386.64s - 2394.95s | virtual function table. If it's a destructor, it will tell you almost everything else that you 2394.95s - 2403.86s | really need to know. And then make good use of it. I hope you didn't come here expecting Oday. 2403.86s - 2410.18s | That wasn't my bent. I'm a mentor. Hopefully I've taught you how to fish. Go fish for 2410.18s - 2418.58s | yourself. So the real conclusion. Think outside the box. Make your tools do new things. If your 2418.58s - 2424.90s | tools are incapable of doing new things, make your own tools. Understand why things work the way 2424.90s - 2433.54s | they do. Because that leads you to be more powerful. Then go hunting. Figure out what you 2433.54s - 2441.94s | think the code or the behavior should look like. And use your brain to create new tooling. Use 2441.94s - 2448.58s | the existing tooling in creative new ways. Because you're the real power. Go forth and do 2448.58s - 2449.14s | great things.


chunk_id: 163_chunk_36
chunk_text:
| virtual function table. If it's a destructor, it will tell you almost everything else that you 2394.95s - 2403.86s | really need to know. And then make good use of it. I hope you didn't come here expecting Oday. 2403.86s - 2410.18s | That wasn't my bent. I'm a mentor. Hopefully I've taught you how to fish. Go fish for 2410.18s - 2418.58s | yourself. So the real conclusion. Think outside the box. Make your tools do new things. If your 2418.58s - 2424.90s | tools are incapable of doing new things, make your own tools. Understand why things work the way 2424.90s - 2433.54s | they do. Because that leads you to be more powerful. Then go hunting. Figure out what you 2433.54s - 2441.94s | think the code or the behavior should look like. And use your brain to create new tooling. Use 2441.94s - 2448.58s | the existing tooling in creative new ways. Because you're the real power. Go forth and do 2448.58s - 2449.14s | great things.


chunk_id: 164_chunk_0
chunk_text:
{ "webpage_url": "https://www.youtube.com/watch?v=tA7bpp8qXxI", "title": "DEF CON 32 - How To Keep IoT From Becoming An IoTrash - Roberts, Wysopal, Doctorow, Wheeler, Giese", "description": "In a world where technology and software are intertwined with our daily lives more than ever, a silent threat grows in the shadows.\n\nEnd-of-life devices\u2014abandoned by manufacturers - power our homes, hospitals, businesses and critical infrastructure. From the depths of the cyber underground, malicious software from cybercriminal and nation-state actors is seizing these forgotten devices and conscripting them into botnets and other malicious infrastructure.\n\nFor example, Black Lotus Labs revealed a chilling trend: 40,000 small office home office (SOHO) routers compromised and enrolled in the sinister 'Faceless' botnet - now powered by devices you own and thought were safe.\n\nAnd it's not just routers. Critical medical devices, essential security hardware\u2014smart home appliances. No gadget is safe. And, with the Internet of Things set to double in the next decade, billions of vulnerable devices marketed and sold to connect us risk robbing, dividing and defeating us in the years to come: a process one expert has termed \u201censhittification.\u201d\n\nAfter years of warnings from the cybersecurity community, alarms are finally sounding in the halls of power. But more is needed: a clarion call to reset, to redefine ownership and security in an age of smart, connected devices before it's too late.\n\nIn this panel you\u2019ll be enlisted to join the fight. You\u2019ll hear from experts working at the forefront of a fight to challenge the status quo and seek solutions to safeguard our digital futures.Are you ready to stand up for your right to a secure, connected world? The battle for control, for transparency- for a sustainable and resilient digital future begins now!", "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw", "duration": 2803, "channel": "DEFCONConference", "uploader": "DEFCONConference", "upload_date": "20241016" } 0.78s - 2.78s | This text was transcribed using whisper model: large-v2 Wow, whoo 6.88s - 8.28s | Blast off 8.28s - 9.68s | All right 9.68s - 14.96s | Thank you everyone for joining us here for our talk this afternoon 15.52s - 21.06s | Bricked and abandoned how to keep the IOT or the Internet of Things from becoming an Internet of trash 21.64s - 25.24s | My name is Paul Roberts, and I'm going to be moderating our discussion today 25.24s - 29.40s | I am the publisher and editor-in-chief at the security ledger 29.80s - 33.20s | I'm the head of editorial content at reversing labs


chunk_id: 164_chunk_1
chunk_text:
to reset, to redefine ownership and security in an age of smart, connected devices before it's too late.\n\nIn this panel you\u2019ll be enlisted to join the fight. You\u2019ll hear from experts working at the forefront of a fight to challenge the status quo and seek solutions to safeguard our digital futures.Are you ready to stand up for your right to a secure, connected world? The battle for control, for transparency- for a sustainable and resilient digital future begins now!", "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw", "duration": 2803, "channel": "DEFCONConference", "uploader": "DEFCONConference", "upload_date": "20241016" } 0.78s - 2.78s | This text was transcribed using whisper model: large-v2 Wow, whoo 6.88s - 8.28s | Blast off 8.28s - 9.68s | All right 9.68s - 14.96s | Thank you everyone for joining us here for our talk this afternoon 15.52s - 21.06s | Bricked and abandoned how to keep the IOT or the Internet of Things from becoming an Internet of trash 21.64s - 25.24s | My name is Paul Roberts, and I'm going to be moderating our discussion today 25.24s - 29.40s | I am the publisher and editor-in-chief at the security ledger 29.80s - 33.20s | I'm the head of editorial content at reversing labs 33.20s - 38.12s | And I'm also the founder of a new nonprofit called surf the secure resilient future foundation 38.12s - 40.12s | We're going to talk a little bit more about that later 40.24s - 45.28s | But our conversation today is going to focus on the problem of abandon where an end-of-life 45.64s - 50.72s | Devices the idea behind this panel really came out of work that I and others on this panel have done 51.24s - 54.80s | on the issue of the right to repair our stuff and 55.32s - 58.80s | Tara and Corey have both been involved in that movement and 59.52s - 64.80s | There that's a project that has shown had some real successes in the last few years 65.68s - 67.68s | Five states have enacted 68.28s - 69.48s | comprehensive 69.48s - 71.48s | electronics right to repair laws 71.52s - 73.52s | and yep in 75.24s - 76.88s | Including 76.88s - 78.68s | home appliances 78.68s - 82.44s | iPads iPhones and most recently in Colorado 83.04s - 88.88s | I'm sorry about that. I don't know what happened 89.60s - 97.88s | Most recently in


chunk_id: 164_chunk_2
chunk_text:
33.20s - 38.12s | And I'm also the founder of a new nonprofit called surf the secure resilient future foundation 38.12s - 40.12s | We're going to talk a little bit more about that later 40.24s - 45.28s | But our conversation today is going to focus on the problem of abandon where an end-of-life 45.64s - 50.72s | Devices the idea behind this panel really came out of work that I and others on this panel have done 51.24s - 54.80s | on the issue of the right to repair our stuff and 55.32s - 58.80s | Tara and Corey have both been involved in that movement and 59.52s - 64.80s | There that's a project that has shown had some real successes in the last few years 65.68s - 67.68s | Five states have enacted 68.28s - 69.48s | comprehensive 69.48s - 71.48s | electronics right to repair laws 71.52s - 73.52s | and yep in 75.24s - 76.88s | Including 76.88s - 78.68s | home appliances 78.68s - 82.44s | iPads iPhones and most recently in Colorado 83.04s - 88.88s | I'm sorry about that. I don't know what happened 89.60s - 97.88s | Most recently in Colorado agricultural devices farm equipment as well as b2b devices so Cisco routers and stuff that you sell to companies 98.88s - 104.68s | Lobbyists had done a good job getting carve-outs for that, but Colorado just passed a law that includes that so that's great 106.48s - 110.64s | Colorado Oregon band practices like part serialization and part pairing 111.04s - 118.08s | And that's wonderful, but even with the right to repair and this is kind of where this panel comes from we still have 118.84s - 120.84s | issues and 122.08s - 126.76s | Consumers businesses and communities are still finding themselves at the mercy of 127.48s - 131.96s | manufacturers and that's because our current mix or mess depending on how you look at it of 132.28s - 138.36s | IP and copyright laws and policies as well as decades of kind of a hands-off approach to 139.16s - 146.92s | market consolidation by our government give companies these days a pretty wide latitude when they sell a smart product to the 147.28s - 152.44s | public and I'll just kind of use the example that I and many others have used which is you might


chunk_id: 164_chunk_3
chunk_text:
Colorado agricultural devices farm equipment as well as b2b devices so Cisco routers and stuff that you sell to companies 98.88s - 104.68s | Lobbyists had done a good job getting carve-outs for that, but Colorado just passed a law that includes that so that's great 106.48s - 110.64s | Colorado Oregon band practices like part serialization and part pairing 111.04s - 118.08s | And that's wonderful, but even with the right to repair and this is kind of where this panel comes from we still have 118.84s - 120.84s | issues and 122.08s - 126.76s | Consumers businesses and communities are still finding themselves at the mercy of 127.48s - 131.96s | manufacturers and that's because our current mix or mess depending on how you look at it of 132.28s - 138.36s | IP and copyright laws and policies as well as decades of kind of a hands-off approach to 139.16s - 146.92s | market consolidation by our government give companies these days a pretty wide latitude when they sell a smart product to the 147.28s - 152.44s | public and I'll just kind of use the example that I and many others have used which is you might go out to 152.76s - 159.64s | Best Buy and buy a smart refrigerator with a touchscreen panel that hardware might have a useful life of a couple decades 160.20s - 161.64s | or more 161.64s - 166.68s | The software, you know, maybe they're gonna support it for three years five years something like that 166.76s - 174.52s | But that's the extent of their commitment to that product. So what's going on over there? 176.32s - 177.64s | So 177.64s - 183.12s | that's kind of the the gist or the heart of what we're gonna be talking about today and 183.80s - 189.64s | To get us started. I think it's a good idea to introduce our panelists. We got an amazing panel and 190.40s - 192.40s | let them I'm gonna 192.56s - 198.92s | Introduce them and then just let them say hi to you and then we'll get going so immediately to my left is mr 198.92s - 205.40s | Chris Weiss Opal Chris is the CTO of Veracode a provider of application security and testing technology 205.40s - 210.56s | He began his career as a vulnerability researcher and renowned hacker with the


chunk_id: 164_chunk_4
chunk_text:
go out to 152.76s - 159.64s | Best Buy and buy a smart refrigerator with a touchscreen panel that hardware might have a useful life of a couple decades 160.20s - 161.64s | or more 161.64s - 166.68s | The software, you know, maybe they're gonna support it for three years five years something like that 166.76s - 174.52s | But that's the extent of their commitment to that product. So what's going on over there? 176.32s - 177.64s | So 177.64s - 183.12s | that's kind of the the gist or the heart of what we're gonna be talking about today and 183.80s - 189.64s | To get us started. I think it's a good idea to introduce our panelists. We got an amazing panel and 190.40s - 192.40s | let them I'm gonna 192.56s - 198.92s | Introduce them and then just let them say hi to you and then we'll get going so immediately to my left is mr 198.92s - 205.40s | Chris Weiss Opal Chris is the CTO of Veracode a provider of application security and testing technology 205.40s - 210.56s | He began his career as a vulnerability researcher and renowned hacker with the loft in 211.32s - 216.96s | 1998 Chris and six of his loft colleagues including much who was talking in this room earlier today 217.52s - 222.12s | Testified before the US Senate on matters of US government cyber security and 222.68s - 224.24s | Chris welcome 224.24s - 226.24s | Thanks, Paul. Great to be here 226.48s - 232.25s | All right next to Chris. We have the amazing Tara Wheeler 232.77s - 240.09s | Tara is the founder and CEO of Red Queen Dynamics and a senior fellow in global global cyber policy at the Council of Foreign Relations 240.33s - 247.85s | And a well-known speaker and writer on topics that include cyber warfare security best practices future trends and more 247.93s - 249.49s | Tara 249.49s - 251.49s | Thank you so much. It's a pleasure to be here 254.08s - 256.52s | Next to Tara. We have Cory Doctorow 256.52s - 261.24s | I think all of us know Cory's a science fiction writer author activist and journalist and 261.44s - 266.28s | The author of many books most recently the bezel and the lost cause in 2020 266.28s - 272.52s | He was inducted


chunk_id: 164_chunk_5
chunk_text:
loft in 211.32s - 216.96s | 1998 Chris and six of his loft colleagues including much who was talking in this room earlier today 217.52s - 222.12s | Testified before the US Senate on matters of US government cyber security and 222.68s - 224.24s | Chris welcome 224.24s - 226.24s | Thanks, Paul. Great to be here 226.48s - 232.25s | All right next to Chris. We have the amazing Tara Wheeler 232.77s - 240.09s | Tara is the founder and CEO of Red Queen Dynamics and a senior fellow in global global cyber policy at the Council of Foreign Relations 240.33s - 247.85s | And a well-known speaker and writer on topics that include cyber warfare security best practices future trends and more 247.93s - 249.49s | Tara 249.49s - 251.49s | Thank you so much. It's a pleasure to be here 254.08s - 256.52s | Next to Tara. We have Cory Doctorow 256.52s - 261.24s | I think all of us know Cory's a science fiction writer author activist and journalist and 261.44s - 266.28s | The author of many books most recently the bezel and the lost cause in 2020 266.28s - 272.52s | He was inducted into the Canadian Science Fiction and Fantasy Hall of Fame. I probably missed a more recent book, but 276.96s - 279.88s | He you blow me away, yeah 283.76s - 290.76s | I'm blown away by how many how much you've written and next to Cory Dennis keys who is a researcher with a focus on 292.36s - 295.44s | The cyber security and privacy of Internet of Things devices 295.44s - 302.72s | he is best known for his research on these security of vacuum robots and method and 303.32s - 308.72s | Methods which we're going to talk about for liberating these devices and user data for manufacturer control Dennis 313.87s - 315.35s | Okay 315.35s - 321.41s | Hold on. How do I control this large? Okay. There we go 322.41s - 323.53s | so 323.53s - 329.37s | You know the backstory for this panel, right is we have an epidemic of end-of-life devices 329.37s - 334.89s | And it's an epidemic that is going to grow in proportion to the growth of the Internet of Things 335.85s - 339.77s | 29 billion IOT devices are projected by 2030 340.33s - 342.81s | They're probably more


chunk_id: 164_chunk_6
chunk_text:
into the Canadian Science Fiction and Fantasy Hall of Fame. I probably missed a more recent book, but 276.96s - 279.88s | He you blow me away, yeah 283.76s - 290.76s | I'm blown away by how many how much you've written and next to Cory Dennis keys who is a researcher with a focus on 292.36s - 295.44s | The cyber security and privacy of Internet of Things devices 295.44s - 302.72s | he is best known for his research on these security of vacuum robots and method and 303.32s - 308.72s | Methods which we're going to talk about for liberating these devices and user data for manufacturer control Dennis 313.87s - 315.35s | Okay 315.35s - 321.41s | Hold on. How do I control this large? Okay. There we go 322.41s - 323.53s | so 323.53s - 329.37s | You know the backstory for this panel, right is we have an epidemic of end-of-life devices 329.37s - 334.89s | And it's an epidemic that is going to grow in proportion to the growth of the Internet of Things 335.85s - 339.77s | 29 billion IOT devices are projected by 2030 340.33s - 342.81s | They're probably more than 20 billion now 343.33s - 346.49s | And as I said with the kind of smart refrigerator 346.49s - 354.05s | There's a divergence between the useful life of hardware measured in decades and software support may be measured in years maybe months 354.53s - 358.41s | And there are currently aren't any laws in the u.s 358.65s - 366.33s | Anyway that mandate periods of support so end-of-life decisions for devices are really driven by bottom-line concerns for the manufacturers 366.49s - 371.13s | You know the age of the product product, you know the profitability of the product the cost of maintenance 371.65s - 375.77s | Not informed by things that should matter like the useful life of the hardware 376.29s - 380.53s | the cost of replacement for the consumer who purchased the device or 381.17s - 387.65s | Even more importantly the cost to our planet of e-waste that ends up in landfills and poisons our environment 388.01s - 395.65s | As well as you know kind of the security risks of unsupported and end-of-life devices which are becoming a more prevalent issue 395.69s - 397.49s | More prevalent issue 397.49s - 403.93s | so


chunk_id: 164_chunk_7
chunk_text:
than 20 billion now 343.33s - 346.49s | And as I said with the kind of smart refrigerator 346.49s - 354.05s | There's a divergence between the useful life of hardware measured in decades and software support may be measured in years maybe months 354.53s - 358.41s | And there are currently aren't any laws in the u.s 358.65s - 366.33s | Anyway that mandate periods of support so end-of-life decisions for devices are really driven by bottom-line concerns for the manufacturers 366.49s - 371.13s | You know the age of the product product, you know the profitability of the product the cost of maintenance 371.65s - 375.77s | Not informed by things that should matter like the useful life of the hardware 376.29s - 380.53s | the cost of replacement for the consumer who purchased the device or 381.17s - 387.65s | Even more importantly the cost to our planet of e-waste that ends up in landfills and poisons our environment 388.01s - 395.65s | As well as you know kind of the security risks of unsupported and end-of-life devices which are becoming a more prevalent issue 395.69s - 397.49s | More prevalent issue 397.49s - 403.93s | so but behind all of this is this kind of bigger phenomena of what Corey has really 404.33s - 406.33s | wonderfully termed in shitification 407.89s - 409.33s | Which is a 409.33s - 415.05s | Phenomenon that is a growing phenomenon and I thought I'd just turn the mic over to Corey just Corey if you could just talk 415.05s - 417.85s | To the audience what is in shitification and you know? 455.65s - 457.65s | 60,000 people in 2023 457.65s - 459.65s | Another 100,000 this year 459.65s - 461.65s | Interesting concept this year 461.65s - 463.65s | It used to be that when the boss told you to make something garbage 463.65s - 465.65s | You could tell your boss to go fuck himself 465.65s - 467.65s | Cause some of them would give you a job 467.65s - 469.65s | And your boss could find someone else to do your job 469.65s - 477.65s | Well these days all of the sources of discipline that used to stop your boss from going to a shitification laboratory 477.65s - 479.65s | Making them have to go all the way to 100 479.65s - 481.65s | All


chunk_id: 164_chunk_8
chunk_text:
but behind all of this is this kind of bigger phenomena of what Corey has really 404.33s - 406.33s | wonderfully termed in shitification 407.89s - 409.33s | Which is a 409.33s - 415.05s | Phenomenon that is a growing phenomenon and I thought I'd just turn the mic over to Corey just Corey if you could just talk 415.05s - 417.85s | To the audience what is in shitification and you know? 455.65s - 457.65s | 60,000 people in 2023 457.65s - 459.65s | Another 100,000 this year 459.65s - 461.65s | Interesting concept this year 461.65s - 463.65s | It used to be that when the boss told you to make something garbage 463.65s - 465.65s | You could tell your boss to go fuck himself 465.65s - 467.65s | Cause some of them would give you a job 467.65s - 469.65s | And your boss could find someone else to do your job 469.65s - 477.65s | Well these days all of the sources of discipline that used to stop your boss from going to a shitification laboratory 477.65s - 479.65s | Making them have to go all the way to 100 479.65s - 481.65s | All of those courses he melts it away 481.65s - 483.65s | And so we have these platforms 483.65s - 485.65s | That are getting more and more politically worse 485.65s - 487.65s | I'm not shouting at this for a hundred hours 487.65s - 489.65s | But I need you to keep this word with your people 489.65s - 491.65s | Yeah 491.65s - 493.65s | That's right there's 493.65s - 495.65s | Put it on your calendar 495.65s - 497.65s | There's a much longer discussion of shitification 497.65s - 499.65s | But Corey thank you 499.65s - 501.65s | I think the other piece of this 501.65s - 503.65s | So is that 503.65s - 505.65s | These are not problems that are 505.65s - 507.65s | Specific I mean these are not 507.65s - 509.65s | This is not just a consumer rights issue 509.65s - 511.65s | Or a you know 511.65s - 513.65s | Access issue it's also increasingly 513.65s - 515.65s | As I said a cyber security issue 515.65s - 517.65s | We're at Defcon here 517.65s - 519.65s | It's a cyber security conference 519.65s - 521.65s | And so these issues


chunk_id: 164_chunk_9
chunk_text:
of those courses he melts it away 481.65s - 483.65s | And so we have these platforms 483.65s - 485.65s | That are getting more and more politically worse 485.65s - 487.65s | I'm not shouting at this for a hundred hours 487.65s - 489.65s | But I need you to keep this word with your people 489.65s - 491.65s | Yeah 491.65s - 493.65s | That's right there's 493.65s - 495.65s | Put it on your calendar 495.65s - 497.65s | There's a much longer discussion of shitification 497.65s - 499.65s | But Corey thank you 499.65s - 501.65s | I think the other piece of this 501.65s - 503.65s | So is that 503.65s - 505.65s | These are not problems that are 505.65s - 507.65s | Specific I mean these are not 507.65s - 509.65s | This is not just a consumer rights issue 509.65s - 511.65s | Or a you know 511.65s - 513.65s | Access issue it's also increasingly 513.65s - 515.65s | As I said a cyber security issue 515.65s - 517.65s | We're at Defcon here 517.65s - 519.65s | It's a cyber security conference 519.65s - 521.65s | And so these issues are you know 521.65s - 523.65s | Forefront in our mind 523.65s - 525.65s | Chris could you just talk about 525.65s - 527.65s | Kind of how the 527.65s - 529.65s | You know these issues with end of life 529.65s - 531.65s | And abandoned devices 531.65s - 533.65s | Impact cyber security not just for 533.65s - 535.65s | Consumers but for businesses as well 535.65s - 537.65s | Right so 537.65s - 539.65s | We all know that a lot of software is built 539.65s - 541.65s | Insecure by design right 541.65s - 543.65s | That's why we all find vulnerabilities 543.65s - 545.65s | In the stuff that's out in the field 545.65s - 547.65s | And there's lots of reasons for that 547.65s - 549.65s | It's basically a business decision 549.65s - 551.65s | That the manufacturers make 551.65s - 553.65s | Not to invest in security 553.65s - 555.65s | And there's no incentives for them 555.65s - 557.65s | To do that especially if it's like 557.65s - 559.65s | An off brand device or an inexpensive device 559.65s - 561.65s | You're going to get less security 561.65s -


chunk_id: 164_chunk_10
chunk_text:
are you know 521.65s - 523.65s | Forefront in our mind 523.65s - 525.65s | Chris could you just talk about 525.65s - 527.65s | Kind of how the 527.65s - 529.65s | You know these issues with end of life 529.65s - 531.65s | And abandoned devices 531.65s - 533.65s | Impact cyber security not just for 533.65s - 535.65s | Consumers but for businesses as well 535.65s - 537.65s | Right so 537.65s - 539.65s | We all know that a lot of software is built 539.65s - 541.65s | Insecure by design right 541.65s - 543.65s | That's why we all find vulnerabilities 543.65s - 545.65s | In the stuff that's out in the field 545.65s - 547.65s | And there's lots of reasons for that 547.65s - 549.65s | It's basically a business decision 549.65s - 551.65s | That the manufacturers make 551.65s - 553.65s | Not to invest in security 553.65s - 555.65s | And there's no incentives for them 555.65s - 557.65s | To do that especially if it's like 557.65s - 559.65s | An off brand device or an inexpensive device 559.65s - 561.65s | You're going to get less security 561.65s - 563.65s | But if it has an IP address 563.65s - 565.65s | And it's on the internet 565.65s - 567.65s | That's what attackers 567.65s - 569.65s | Like to use it for 569.65s - 571.65s | To maybe create a DDoS 571.65s - 573.65s | Botnet like we saw with Mirai 573.65s - 575.65s | Or more recently 575.65s - 577.65s | We've seen with the Volt Typhoon 577.65s - 579.65s | And the KV Botnet 579.65s - 581.65s | Where it was Soho routers 581.65s - 583.65s | That were end of life 583.65s - 585.65s | That were leveraged 585.65s - 587.65s | To hide 587.65s - 589.65s | Attacks it's actually 589.65s - 591.65s | A great way for attackers 591.65s - 593.65s | To hide where they're coming from 593.65s - 595.65s | Because they can appear to come from 595.65s - 597.65s | A network that's close 597.65s - 599.65s | To the target because 599.65s - 601.65s | These devices are everywhere 601.65s - 603.65s | And in Volt Typhoon it actually 603.65s - 605.65s | Was in Guam 605.65s - 607.65s | Chinese hackers hacked 607.65s - 609.65s | These Soho


chunk_id: 164_chunk_11
chunk_text:
563.65s | But if it has an IP address 563.65s - 565.65s | And it's on the internet 565.65s - 567.65s | That's what attackers 567.65s - 569.65s | Like to use it for 569.65s - 571.65s | To maybe create a DDoS 571.65s - 573.65s | Botnet like we saw with Mirai 573.65s - 575.65s | Or more recently 575.65s - 577.65s | We've seen with the Volt Typhoon 577.65s - 579.65s | And the KV Botnet 579.65s - 581.65s | Where it was Soho routers 581.65s - 583.65s | That were end of life 583.65s - 585.65s | That were leveraged 585.65s - 587.65s | To hide 587.65s - 589.65s | Attacks it's actually 589.65s - 591.65s | A great way for attackers 591.65s - 593.65s | To hide where they're coming from 593.65s - 595.65s | Because they can appear to come from 595.65s - 597.65s | A network that's close 597.65s - 599.65s | To the target because 599.65s - 601.65s | These devices are everywhere 601.65s - 603.65s | And in Volt Typhoon it actually 603.65s - 605.65s | Was in Guam 605.65s - 607.65s | Chinese hackers hacked 607.65s - 609.65s | These Soho routers 609.65s - 611.65s | And they were able to 611.65s - 613.65s | Appear like they were just coming from Guam 613.65s - 615.65s | Right so when they were attacking 615.65s - 617.65s | ICS infrastructure 617.65s - 619.65s | So that's just sort of 619.65s - 621.65s | A present threat that we get 621.65s - 623.65s | It's an environmental threat 623.65s - 625.65s | That harms the ecosystem 625.65s - 627.65s | That we all rely on 627.65s - 629.65s | If you're a defender 629.65s - 631.65s | It's harder to defend if it looks like 631.65s - 633.65s | It's coming from one of your employees 633.65s - 635.65s | Working from home right 635.65s - 637.65s | Because it's coming from a home router 637.65s - 639.65s | From a local isp 639.65s - 641.65s | So this effect where 641.65s - 643.65s | No incentives for these manufacturers 643.65s - 645.65s | To actually build security in 645.65s - 647.65s | And invest in doing that 647.65s - 649.65s | Leads to us all having 649.65s - 651.65s | Worse security 651.65s - 653.65s | The other reasons that they 653.65s


chunk_id: 164_chunk_12
chunk_text:
routers 609.65s - 611.65s | And they were able to 611.65s - 613.65s | Appear like they were just coming from Guam 613.65s - 615.65s | Right so when they were attacking 615.65s - 617.65s | ICS infrastructure 617.65s - 619.65s | So that's just sort of 619.65s - 621.65s | A present threat that we get 621.65s - 623.65s | It's an environmental threat 623.65s - 625.65s | That harms the ecosystem 625.65s - 627.65s | That we all rely on 627.65s - 629.65s | If you're a defender 629.65s - 631.65s | It's harder to defend if it looks like 631.65s - 633.65s | It's coming from one of your employees 633.65s - 635.65s | Working from home right 635.65s - 637.65s | Because it's coming from a home router 637.65s - 639.65s | From a local isp 639.65s - 641.65s | So this effect where 641.65s - 643.65s | No incentives for these manufacturers 643.65s - 645.65s | To actually build security in 645.65s - 647.65s | And invest in doing that 647.65s - 649.65s | Leads to us all having 649.65s - 651.65s | Worse security 651.65s - 653.65s | The other reasons that they 653.65s - 655.65s | Have a problem doing this is because 655.65s - 657.65s | Building secure software is hard 657.65s - 659.65s | Right it actually takes expertise 659.65s - 661.65s | It takes investing time 661.65s - 663.65s | And tooling and actually the tooling 663.65s - 665.65s | Isn't as good in the firmware space 665.65s - 667.65s | As it is in some of the general purpose 667.65s - 669.65s | Windows and Linux software 669.65s - 671.65s | Spaces when you're dealing with these 671.65s - 673.65s | Embedded devices the tooling's not as good 673.65s - 675.65s | You have to rely on manual 675.65s - 677.65s | Penetration testings and manual 677.65s - 679.65s | Code review more 679.65s - 681.65s | So these drive up the cost 681.65s - 683.65s | So there's less incentives to 683.65s - 685.65s | Spend the money 685.65s - 687.65s | The other thing i want to mention though is 687.65s - 689.65s | The cost of updating 689.65s - 691.65s | There's a cost to updating software 691.65s - 693.65s | And we know 693.65s - 695.65s | If you find vulnerabilities 695.65s - 697.65s |


chunk_id: 164_chunk_13
chunk_text:
- 655.65s | Have a problem doing this is because 655.65s - 657.65s | Building secure software is hard 657.65s - 659.65s | Right it actually takes expertise 659.65s - 661.65s | It takes investing time 661.65s - 663.65s | And tooling and actually the tooling 663.65s - 665.65s | Isn't as good in the firmware space 665.65s - 667.65s | As it is in some of the general purpose 667.65s - 669.65s | Windows and Linux software 669.65s - 671.65s | Spaces when you're dealing with these 671.65s - 673.65s | Embedded devices the tooling's not as good 673.65s - 675.65s | You have to rely on manual 675.65s - 677.65s | Penetration testings and manual 677.65s - 679.65s | Code review more 679.65s - 681.65s | So these drive up the cost 681.65s - 683.65s | So there's less incentives to 683.65s - 685.65s | Spend the money 685.65s - 687.65s | The other thing i want to mention though is 687.65s - 689.65s | The cost of updating 689.65s - 691.65s | There's a cost to updating software 691.65s - 693.65s | And we know 693.65s - 695.65s | If you find vulnerabilities 695.65s - 697.65s | After you ship the product you're going to have to 697.65s - 699.65s | Update the software and updating 699.65s - 701.65s | Iot devices is actually harder 701.65s - 703.65s | Than updating general purpose software like chrome 703.65s - 705.65s | And windows 705.65s - 707.65s | And mac and things like that 707.65s - 709.65s | Because when you have a failure mode you don't 709.65s - 711.65s | Have a great interface for someone to deal with it 711.65s - 713.65s | Right so you have to invest a lot 713.65s - 715.65s | More for these robust 715.65s - 717.65s | Update process that is less prone 717.65s - 719.65s | To failure 719.65s - 721.65s | And you're doing this on devices that are 721.65s - 723.65s | Inexpensive 723.65s - 725.65s | So we just have a complete mismatch 725.65s - 727.65s | Of incentives when it comes to 727.65s - 729.65s | Especially inexpensive devices 729.65s - 731.65s | And some of these soho routers are like 100 bucks 731.65s - 733.65s | Right so there's not a lot of 733.65s - 735.65s | Incentives to invest in security 735.65s - 737.65s


chunk_id: 164_chunk_14
chunk_text:
After you ship the product you're going to have to 697.65s - 699.65s | Update the software and updating 699.65s - 701.65s | Iot devices is actually harder 701.65s - 703.65s | Than updating general purpose software like chrome 703.65s - 705.65s | And windows 705.65s - 707.65s | And mac and things like that 707.65s - 709.65s | Because when you have a failure mode you don't 709.65s - 711.65s | Have a great interface for someone to deal with it 711.65s - 713.65s | Right so you have to invest a lot 713.65s - 715.65s | More for these robust 715.65s - 717.65s | Update process that is less prone 717.65s - 719.65s | To failure 719.65s - 721.65s | And you're doing this on devices that are 721.65s - 723.65s | Inexpensive 723.65s - 725.65s | So we just have a complete mismatch 725.65s - 727.65s | Of incentives when it comes to 727.65s - 729.65s | Especially inexpensive devices 729.65s - 731.65s | And some of these soho routers are like 100 bucks 731.65s - 733.65s | Right so there's not a lot of 733.65s - 735.65s | Incentives to invest in security 735.65s - 737.65s | So i mean i think one of the 737.65s - 739.65s | Things that is 739.65s - 741.65s | You know kind of picking up on what chris what you 741.65s - 743.65s | Were saying is you know 743.65s - 745.65s | Obviously this hugely 745.65s - 747.65s | Growing internet of things it's 747.65s - 749.65s | Working its way into our homes into our 749.65s - 751.65s | Businesses into sensitive environments 751.65s - 753.65s | Obviously but it's really 753.65s - 755.65s | Sort of from a security 755.65s - 757.65s | And you know 757.65s - 759.65s | Quality standpoint a black box 759.65s - 761.65s | Which is why i wanted dennis keys on 761.65s - 763.65s | This panel because more than 763.65s - 765.65s | Most other people in this planet 765.65s - 767.65s | Dennis has familiarized don't 767.65s - 769.65s | Yes that's true dennis don't don't be 769.65s - 771.65s | Humble has peered deeply 771.65s - 773.65s | Into the workings of smart 773.65s - 775.65s | Connected devices 775.65s - 777.65s | Vacuum robots and smart 777.65s - 779.65s | Doorbells and you name it 779.65s


chunk_id: 164_chunk_15
chunk_text:
| So i mean i think one of the 737.65s - 739.65s | Things that is 739.65s - 741.65s | You know kind of picking up on what chris what you 741.65s - 743.65s | Were saying is you know 743.65s - 745.65s | Obviously this hugely 745.65s - 747.65s | Growing internet of things it's 747.65s - 749.65s | Working its way into our homes into our 749.65s - 751.65s | Businesses into sensitive environments 751.65s - 753.65s | Obviously but it's really 753.65s - 755.65s | Sort of from a security 755.65s - 757.65s | And you know 757.65s - 759.65s | Quality standpoint a black box 759.65s - 761.65s | Which is why i wanted dennis keys on 761.65s - 763.65s | This panel because more than 763.65s - 765.65s | Most other people in this planet 765.65s - 767.65s | Dennis has familiarized don't 767.65s - 769.65s | Yes that's true dennis don't don't be 769.65s - 771.65s | Humble has peered deeply 771.65s - 773.65s | Into the workings of smart 773.65s - 775.65s | Connected devices 775.65s - 777.65s | Vacuum robots and smart 777.65s - 779.65s | Doorbells and you name it 779.65s - 781.65s | So dennis if you could just kind 781.65s - 783.65s | Of tell us a little bit just give us 783.65s - 785.65s | A sense of under the hood 785.65s - 787.65s | Of these connected devices 787.65s - 789.65s | Whether they're end of life or not end of life 789.65s - 791.65s | What are the types of things that you're finding 791.65s - 793.65s | And what are the types of you know problems 793.65s - 795.65s | That exist out there 824.91s - 826.91s | One thing that i noticed 826.91s - 828.91s | Was that all the 828.91s - 830.91s | Recycling 850.91s - 852.91s | One thing 852.91s - 854.91s | In 854.91s - 856.91s | Circles 866.91s - 868.91s | But 868.91s - 870.91s | It's 870.91s - 872.91s | Important 872.91s - 874.91s | So like 874.91s - 876.91s | This 876.91s - 878.91s | Is 878.91s - 880.91s | Not the same 880.91s - 882.91s | As 882.91s - 884.91s | The 884.91s - 886.91s | One 886.91s - 888.91s | That 888.91s - 890.91s | Is 890.91s - 892.91s | The 892.91s - 894.91s | One


chunk_id: 164_chunk_16
chunk_text:
- 781.65s | So dennis if you could just kind 781.65s - 783.65s | Of tell us a little bit just give us 783.65s - 785.65s | A sense of under the hood 785.65s - 787.65s | Of these connected devices 787.65s - 789.65s | Whether they're end of life or not end of life 789.65s - 791.65s | What are the types of things that you're finding 791.65s - 793.65s | And what are the types of you know problems 793.65s - 795.65s | That exist out there 824.91s - 826.91s | One thing that i noticed 826.91s - 828.91s | Was that all the 828.91s - 830.91s | Recycling 850.91s - 852.91s | One thing 852.91s - 854.91s | In 854.91s - 856.91s | Circles 866.91s - 868.91s | But 868.91s - 870.91s | It's 870.91s - 872.91s | Important 872.91s - 874.91s | So like 874.91s - 876.91s | This 876.91s - 878.91s | Is 878.91s - 880.91s | Not the same 880.91s - 882.91s | As 882.91s - 884.91s | The 884.91s - 886.91s | One 886.91s - 888.91s | That 888.91s - 890.91s | Is 890.91s - 892.91s | The 892.91s - 894.91s | One 894.91s - 896.91s | That 896.91s - 898.91s | Is 898.91s - 900.91s | The 900.91s - 902.91s | One 902.91s - 904.91s | That 904.91s - 906.91s | Is 906.91s - 908.91s | The 908.91s - 910.91s | One 910.91s - 912.91s | That 912.91s - 914.91s | Is 914.91s - 916.91s | The 916.91s - 918.91s | One 918.91s - 920.91s | That 920.91s - 922.91s | Is 922.91s - 924.91s | The 924.91s - 926.91s | One 926.91s - 928.91s | That 928.91s - 930.91s | Is 930.91s - 932.91s | The 932.91s - 934.91s | One 934.91s - 936.91s | That 936.91s - 938.91s | Is 938.91s - 940.91s | The 940.91s - 942.91s | One 942.91s - 944.91s | That 944.91s - 946.91s | Is 946.91s - 948.91s | The 948.91s - 950.91s | One 950.91s - 952.91s | That 952.91s - 954.91s | Is 954.91s - 956.91s | The 956.91s - 958.91s | One 958.91s - 960.91s | That 960.91s - 962.91s | Is 962.91s - 964.91s | The 964.91s - 966.91s | One 966.91s - 968.91s | That 968.91s - 970.91s | Is 970.91s - 972.91s | The 972.91s - 974.91s | One


chunk_id: 164_chunk_17
chunk_text:
894.91s - 896.91s | That 896.91s - 898.91s | Is 898.91s - 900.91s | The 900.91s - 902.91s | One 902.91s - 904.91s | That 904.91s - 906.91s | Is 906.91s - 908.91s | The 908.91s - 910.91s | One 910.91s - 912.91s | That 912.91s - 914.91s | Is 914.91s - 916.91s | The 916.91s - 918.91s | One 918.91s - 920.91s | That 920.91s - 922.91s | Is 922.91s - 924.91s | The 924.91s - 926.91s | One 926.91s - 928.91s | That 928.91s - 930.91s | Is 930.91s - 932.91s | The 932.91s - 934.91s | One 934.91s - 936.91s | That 936.91s - 938.91s | Is 938.91s - 940.91s | The 940.91s - 942.91s | One 942.91s - 944.91s | That 944.91s - 946.91s | Is 946.91s - 948.91s | The 948.91s - 950.91s | One 950.91s - 952.91s | That 952.91s - 954.91s | Is 954.91s - 956.91s | The 956.91s - 958.91s | One 958.91s - 960.91s | That 960.91s - 962.91s | Is 962.91s - 964.91s | The 964.91s - 966.91s | One 966.91s - 968.91s | That 968.91s - 970.91s | Is 970.91s - 972.91s | The 972.91s - 974.91s | One 974.91s - 976.91s | That 976.91s - 978.91s | Is 978.91s - 980.91s | The 980.91s - 982.91s | One 982.91s - 984.91s | That 984.91s - 986.91s | Is 986.91s - 988.91s | The 988.91s - 990.91s | One 990.91s - 992.91s | That 992.91s - 994.91s | Is 994.91s - 996.91s | The 996.91s - 998.91s | One 998.91s - 1000.91s | That 1000.91s - 1002.91s | Is 1002.91s - 1004.91s | The 1004.91s - 1006.91s | One 1006.91s - 1008.91s | That 1008.91s - 1010.91s | Is 1010.91s - 1012.91s | The 1012.91s - 1014.91s | One 1014.91s - 1016.91s | That 1016.91s - 1018.91s | Is 1018.91s - 1020.91s | The 1020.91s - 1022.91s | One 1022.91s - 1024.91s | That 1024.91s - 1026.91s | Is 1026.91s - 1028.91s | The 1028.91s - 1030.91s | One 1030.91s - 1032.91s | That 1032.91s - 1034.91s | Is 1034.91s - 1036.91s | The 1036.91s - 1038.91s | One 1038.91s - 1040.91s | That 1040.91s - 1042.91s | Is 1042.91s - 1044.91s | The 1044.91s - 1046.91s | One 1046.91s - 1048.91s | That 1048.91s - 1050.91s | Is 1050.91s - 1052.91s | The 1052.91s - 1054.91s | One


chunk_id: 164_chunk_18
chunk_text:
974.91s - 976.91s | That 976.91s - 978.91s | Is 978.91s - 980.91s | The 980.91s - 982.91s | One 982.91s - 984.91s | That 984.91s - 986.91s | Is 986.91s - 988.91s | The 988.91s - 990.91s | One 990.91s - 992.91s | That 992.91s - 994.91s | Is 994.91s - 996.91s | The 996.91s - 998.91s | One 998.91s - 1000.91s | That 1000.91s - 1002.91s | Is 1002.91s - 1004.91s | The 1004.91s - 1006.91s | One 1006.91s - 1008.91s | That 1008.91s - 1010.91s | Is 1010.91s - 1012.91s | The 1012.91s - 1014.91s | One 1014.91s - 1016.91s | That 1016.91s - 1018.91s | Is 1018.91s - 1020.91s | The 1020.91s - 1022.91s | One 1022.91s - 1024.91s | That 1024.91s - 1026.91s | Is 1026.91s - 1028.91s | The 1028.91s - 1030.91s | One 1030.91s - 1032.91s | That 1032.91s - 1034.91s | Is 1034.91s - 1036.91s | The 1036.91s - 1038.91s | One 1038.91s - 1040.91s | That 1040.91s - 1042.91s | Is 1042.91s - 1044.91s | The 1044.91s - 1046.91s | One 1046.91s - 1048.91s | That 1048.91s - 1050.91s | Is 1050.91s - 1052.91s | The 1052.91s - 1054.91s | One 1054.91s - 1056.91s | That 1056.91s - 1058.91s | Is 1058.91s - 1060.91s | The 1060.91s - 1062.91s | One 1062.91s - 1064.91s | That 1064.91s - 1066.91s | Is 1066.91s - 1068.91s | The 1068.91s - 1070.91s | One 1070.91s - 1072.91s | That 1072.91s - 1074.91s | Is 1074.91s - 1076.91s | The 1076.91s - 1078.91s | One 1078.91s - 1080.91s | That 1080.91s - 1082.91s | Is 1082.91s - 1084.91s | The 1084.91s - 1086.91s | One 1086.91s - 1088.91s | That 1088.91s - 1090.91s | Is 1090.91s - 1092.91s | The 1092.91s - 1094.91s | One 1094.91s - 1096.91s | That 1096.91s - 1098.91s | Is 1098.91s - 1100.91s | The 1100.91s - 1102.91s | One 1102.91s - 1104.91s | That 1104.91s - 1106.91s | Is 1106.91s - 1108.91s | The 1108.91s - 1110.91s | One 1110.91s - 1112.91s | That 1112.91s - 1114.91s | Is 1114.91s - 1116.91s | The 1116.91s - 1118.91s | One 1118.91s - 1120.91s | That 1120.91s - 1122.91s | Is 1122.91s - 1124.91s | The 1124.91s - 1126.91s | One 1126.91s - 1128.91s | That 1128.91s - 1130.91s | Is 1130.91s - 1132.91s | The 1132.91s - 1134.91s | One


chunk_id: 164_chunk_19
chunk_text:
1054.91s - 1056.91s | That 1056.91s - 1058.91s | Is 1058.91s - 1060.91s | The 1060.91s - 1062.91s | One 1062.91s - 1064.91s | That 1064.91s - 1066.91s | Is 1066.91s - 1068.91s | The 1068.91s - 1070.91s | One 1070.91s - 1072.91s | That 1072.91s - 1074.91s | Is 1074.91s - 1076.91s | The 1076.91s - 1078.91s | One 1078.91s - 1080.91s | That 1080.91s - 1082.91s | Is 1082.91s - 1084.91s | The 1084.91s - 1086.91s | One 1086.91s - 1088.91s | That 1088.91s - 1090.91s | Is 1090.91s - 1092.91s | The 1092.91s - 1094.91s | One 1094.91s - 1096.91s | That 1096.91s - 1098.91s | Is 1098.91s - 1100.91s | The 1100.91s - 1102.91s | One 1102.91s - 1104.91s | That 1104.91s - 1106.91s | Is 1106.91s - 1108.91s | The 1108.91s - 1110.91s | One 1110.91s - 1112.91s | That 1112.91s - 1114.91s | Is 1114.91s - 1116.91s | The 1116.91s - 1118.91s | One 1118.91s - 1120.91s | That 1120.91s - 1122.91s | Is 1122.91s - 1124.91s | The 1124.91s - 1126.91s | One 1126.91s - 1128.91s | That 1128.91s - 1130.91s | Is 1130.91s - 1132.91s | The 1132.91s - 1134.91s | One 1134.91s - 1136.91s | That 1136.91s - 1138.91s | Is 1138.91s - 1140.91s | The 1140.91s - 1142.91s | One 1142.91s - 1144.91s | That 1144.91s - 1146.91s | Is 1146.91s - 1148.91s | The 1148.91s - 1150.91s | One 1150.91s - 1152.91s | That 1152.91s - 1154.91s | Is 1154.91s - 1156.91s | The 1156.91s - 1158.91s | One 1158.91s - 1160.91s | That 1160.91s - 1164.35s | Is 1164.35s - 1166.35s | The 1166.35s - 1168.35s | One 1168.35s - 1170.35s | That 1170.35s - 1172.35s | Is 1172.35s - 1174.35s | The 1174.35s - 1176.35s | One 1176.35s - 1178.35s | That 1178.35s - 1180.35s | Is 1180.35s - 1182.35s | The 1182.35s - 1184.35s | One 1184.35s - 1186.35s | That 1186.35s - 1188.35s | Is 1188.35s - 1190.35s | The 1190.35s - 1192.35s | One 1192.35s - 1194.35s | That 1194.35s - 1196.35s | Is 1196.35s - 1198.35s | The 1198.35s - 1200.35s | One 1200.35s - 1202.35s | That 1202.35s - 1204.35s | Is 1204.35s - 1206.35s | The 1206.35s - 1208.35s | One 1208.35s - 1210.35s | That 1210.35s - 1212.35s | Is 1212.35s - 1214.35s | The 1214.35s - 1216.35s | One


chunk_id: 164_chunk_20
chunk_text:
1134.91s - 1136.91s | That 1136.91s - 1138.91s | Is 1138.91s - 1140.91s | The 1140.91s - 1142.91s | One 1142.91s - 1144.91s | That 1144.91s - 1146.91s | Is 1146.91s - 1148.91s | The 1148.91s - 1150.91s | One 1150.91s - 1152.91s | That 1152.91s - 1154.91s | Is 1154.91s - 1156.91s | The 1156.91s - 1158.91s | One 1158.91s - 1160.91s | That 1160.91s - 1164.35s | Is 1164.35s - 1166.35s | The 1166.35s - 1168.35s | One 1168.35s - 1170.35s | That 1170.35s - 1172.35s | Is 1172.35s - 1174.35s | The 1174.35s - 1176.35s | One 1176.35s - 1178.35s | That 1178.35s - 1180.35s | Is 1180.35s - 1182.35s | The 1182.35s - 1184.35s | One 1184.35s - 1186.35s | That 1186.35s - 1188.35s | Is 1188.35s - 1190.35s | The 1190.35s - 1192.35s | One 1192.35s - 1194.35s | That 1194.35s - 1196.35s | Is 1196.35s - 1198.35s | The 1198.35s - 1200.35s | One 1200.35s - 1202.35s | That 1202.35s - 1204.35s | Is 1204.35s - 1206.35s | The 1206.35s - 1208.35s | One 1208.35s - 1210.35s | That 1210.35s - 1212.35s | Is 1212.35s - 1214.35s | The 1214.35s - 1216.35s | One 1216.35s - 1218.35s | That 1218.35s - 1220.35s | Is 1220.35s - 1222.35s | The 1222.35s - 1224.35s | One 1224.35s - 1226.35s | That 1226.35s - 1228.35s | Is 1228.35s - 1230.35s | The 1230.35s - 1232.35s | One 1232.35s - 1234.35s | That 1234.35s - 1236.35s | Is 1236.35s - 1238.35s | The 1238.35s - 1240.35s | One 1240.35s - 1242.35s | That 1242.35s - 1244.35s | Is 1244.35s - 1246.35s | The 1246.35s - 1248.35s | One 1248.35s - 1250.35s | That 1250.35s - 1252.35s | Is 1252.35s - 1254.35s | The 1254.35s - 1256.35s | One 1256.35s - 1258.35s | That 1258.35s - 1260.35s | Is 1260.35s - 1262.35s | The 1262.35s - 1264.35s | One 1264.35s - 1266.35s | That 1266.35s - 1268.35s | Is 1268.35s - 1270.35s | The 1270.35s - 1272.35s | One 1272.35s - 1274.35s | That 1274.35s - 1276.35s | Is 1276.35s - 1278.35s | The 1278.35s - 1280.35s | One 1280.35s - 1282.35s | That 1282.35s - 1284.35s | Is 1284.35s - 1286.35s | The 1286.35s - 1288.35s | One 1288.35s - 1290.35s | That 1290.35s - 1292.35s | Is 1292.35s - 1294.35s | The 1294.35s - 1296.35s | One


chunk_id: 164_chunk_21
chunk_text:
1216.35s - 1218.35s | That 1218.35s - 1220.35s | Is 1220.35s - 1222.35s | The 1222.35s - 1224.35s | One 1224.35s - 1226.35s | That 1226.35s - 1228.35s | Is 1228.35s - 1230.35s | The 1230.35s - 1232.35s | One 1232.35s - 1234.35s | That 1234.35s - 1236.35s | Is 1236.35s - 1238.35s | The 1238.35s - 1240.35s | One 1240.35s - 1242.35s | That 1242.35s - 1244.35s | Is 1244.35s - 1246.35s | The 1246.35s - 1248.35s | One 1248.35s - 1250.35s | That 1250.35s - 1252.35s | Is 1252.35s - 1254.35s | The 1254.35s - 1256.35s | One 1256.35s - 1258.35s | That 1258.35s - 1260.35s | Is 1260.35s - 1262.35s | The 1262.35s - 1264.35s | One 1264.35s - 1266.35s | That 1266.35s - 1268.35s | Is 1268.35s - 1270.35s | The 1270.35s - 1272.35s | One 1272.35s - 1274.35s | That 1274.35s - 1276.35s | Is 1276.35s - 1278.35s | The 1278.35s - 1280.35s | One 1280.35s - 1282.35s | That 1282.35s - 1284.35s | Is 1284.35s - 1286.35s | The 1286.35s - 1288.35s | One 1288.35s - 1290.35s | That 1290.35s - 1292.35s | Is 1292.35s - 1294.35s | The 1294.35s - 1296.35s | One 1296.35s - 1298.35s | That 1298.35s - 1300.35s | Is 1300.35s - 1302.35s | The 1302.35s - 1304.35s | One 1304.35s - 1306.35s | That 1306.35s - 1308.35s | Is 1308.35s - 1310.35s | The 1310.35s - 1312.35s | One 1312.35s - 1314.35s | That 1314.35s - 1316.35s | Is 1316.35s - 1318.35s | The 1318.35s - 1320.35s | One 1320.35s - 1322.35s | That 1322.35s - 1324.35s | Is 1324.35s - 1326.35s | The 1326.35s - 1328.35s | One 1328.35s - 1330.35s | That 1330.35s - 1332.35s | Is 1332.35s - 1334.35s | The 1334.35s - 1336.35s | One 1336.35s - 1338.35s | That 1338.35s - 1340.35s | Is 1340.35s - 1342.35s | The 1342.35s - 1344.35s | One 1344.35s - 1346.35s | That 1346.35s - 1348.35s | Is 1348.35s - 1350.35s | The 1350.35s - 1352.35s | One 1352.35s - 1354.35s | That 1354.35s - 1356.35s | Is 1356.35s - 1358.35s | The 1358.35s - 1360.35s | One 1360.35s - 1362.35s | That 1362.35s - 1364.35s | Is 1364.35s - 1366.35s | The 1366.35s - 1368.35s | One 1368.35s - 1370.35s | That 1370.35s - 1372.35s | Is 1372.35s - 1374.35s | The 1374.35s - 1376.35s | One


chunk_id: 164_chunk_22
chunk_text:
1296.35s - 1298.35s | That 1298.35s - 1300.35s | Is 1300.35s - 1302.35s | The 1302.35s - 1304.35s | One 1304.35s - 1306.35s | That 1306.35s - 1308.35s | Is 1308.35s - 1310.35s | The 1310.35s - 1312.35s | One 1312.35s - 1314.35s | That 1314.35s - 1316.35s | Is 1316.35s - 1318.35s | The 1318.35s - 1320.35s | One 1320.35s - 1322.35s | That 1322.35s - 1324.35s | Is 1324.35s - 1326.35s | The 1326.35s - 1328.35s | One 1328.35s - 1330.35s | That 1330.35s - 1332.35s | Is 1332.35s - 1334.35s | The 1334.35s - 1336.35s | One 1336.35s - 1338.35s | That 1338.35s - 1340.35s | Is 1340.35s - 1342.35s | The 1342.35s - 1344.35s | One 1344.35s - 1346.35s | That 1346.35s - 1348.35s | Is 1348.35s - 1350.35s | The 1350.35s - 1352.35s | One 1352.35s - 1354.35s | That 1354.35s - 1356.35s | Is 1356.35s - 1358.35s | The 1358.35s - 1360.35s | One 1360.35s - 1362.35s | That 1362.35s - 1364.35s | Is 1364.35s - 1366.35s | The 1366.35s - 1368.35s | One 1368.35s - 1370.35s | That 1370.35s - 1372.35s | Is 1372.35s - 1374.35s | The 1374.35s - 1376.35s | One 1376.35s - 1378.35s | That 1378.35s - 1380.35s | Is 1380.35s - 1382.35s | The 1382.35s - 1384.35s | One 1384.35s - 1386.35s | That 1386.35s - 1388.35s | Is 1388.35s - 1390.35s | The 1390.35s - 1392.35s | One 1392.35s - 1394.35s | That 1394.35s - 1396.35s | Is 1396.35s - 1398.35s | The 1398.35s - 1400.35s | One 1400.35s - 1402.35s | That 1402.35s - 1404.35s | Is 1404.35s - 1406.35s | The 1406.35s - 1408.35s | One 1408.35s - 1410.35s | That 1410.35s - 1412.35s | Is 1412.35s - 1414.35s | The 1414.35s - 1416.35s | One 1416.35s - 1418.35s | That 1418.35s - 1420.35s | Is 1420.35s - 1422.35s | The 1422.35s - 1424.35s | One 1424.35s - 1426.35s | That 1426.35s - 1428.35s | Is 1428.35s - 1430.35s | The 1430.35s - 1432.35s | One 1432.35s - 1434.35s | That 1434.35s - 1436.35s | Is 1436.35s - 1438.35s | The 1438.35s - 1440.35s | One 1440.35s - 1442.35s | That 1442.35s - 1444.35s | Is 1444.35s - 1446.35s | The 1446.35s - 1448.35s | One 1448.35s - 1450.35s | That 1450.35s - 1452.35s | Is 1452.35s - 1454.35s | The 1454.35s - 1456.35s | One


chunk_id: 164_chunk_23
chunk_text:
1376.35s - 1378.35s | That 1378.35s - 1380.35s | Is 1380.35s - 1382.35s | The 1382.35s - 1384.35s | One 1384.35s - 1386.35s | That 1386.35s - 1388.35s | Is 1388.35s - 1390.35s | The 1390.35s - 1392.35s | One 1392.35s - 1394.35s | That 1394.35s - 1396.35s | Is 1396.35s - 1398.35s | The 1398.35s - 1400.35s | One 1400.35s - 1402.35s | That 1402.35s - 1404.35s | Is 1404.35s - 1406.35s | The 1406.35s - 1408.35s | One 1408.35s - 1410.35s | That 1410.35s - 1412.35s | Is 1412.35s - 1414.35s | The 1414.35s - 1416.35s | One 1416.35s - 1418.35s | That 1418.35s - 1420.35s | Is 1420.35s - 1422.35s | The 1422.35s - 1424.35s | One 1424.35s - 1426.35s | That 1426.35s - 1428.35s | Is 1428.35s - 1430.35s | The 1430.35s - 1432.35s | One 1432.35s - 1434.35s | That 1434.35s - 1436.35s | Is 1436.35s - 1438.35s | The 1438.35s - 1440.35s | One 1440.35s - 1442.35s | That 1442.35s - 1444.35s | Is 1444.35s - 1446.35s | The 1446.35s - 1448.35s | One 1448.35s - 1450.35s | That 1450.35s - 1452.35s | Is 1452.35s - 1454.35s | The 1454.35s - 1456.35s | One 1456.35s - 1458.35s | That 1458.35s - 1460.35s | Is 1460.35s - 1462.35s | The 1462.35s - 1464.35s | One 1464.35s - 1466.35s | That 1466.35s - 1468.35s | Is 1468.35s - 1470.35s | The 1470.35s - 1472.35s | One 1472.35s - 1474.35s | That 1474.35s - 1476.35s | Is 1476.35s - 1478.35s | The 1478.35s - 1480.35s | One 1480.35s - 1482.35s | That 1482.35s - 1484.35s | Is 1484.35s - 1486.35s | The 1486.35s - 1488.35s | One 1488.35s - 1490.35s | That 1490.35s - 1492.35s | Is 1492.35s - 1494.35s | The 1494.35s - 1496.35s | One 1496.35s - 1498.35s | That 1498.35s - 1500.35s | Is 1500.35s - 1502.35s | The 1502.35s - 1504.35s | One 1504.35s - 1506.35s | That 1506.35s - 1508.35s | Is 1508.35s - 1510.35s | The 1510.35s - 1512.35s | One 1512.35s - 1514.35s | That 1514.35s - 1516.35s | Is 1516.35s - 1518.35s | The 1518.35s - 1520.35s | One 1520.35s - 1522.35s | That 1522.35s - 1524.35s | Is 1524.35s - 1526.35s | The 1526.35s - 1528.35s | One 1528.35s - 1530.35s | That 1530.35s - 1532.35s | Is 1532.35s - 1534.35s | The 1534.35s - 1536.35s | One


chunk_id: 164_chunk_24
chunk_text:
1456.35s - 1458.35s | That 1458.35s - 1460.35s | Is 1460.35s - 1462.35s | The 1462.35s - 1464.35s | One 1464.35s - 1466.35s | That 1466.35s - 1468.35s | Is 1468.35s - 1470.35s | The 1470.35s - 1472.35s | One 1472.35s - 1474.35s | That 1474.35s - 1476.35s | Is 1476.35s - 1478.35s | The 1478.35s - 1480.35s | One 1480.35s - 1482.35s | That 1482.35s - 1484.35s | Is 1484.35s - 1486.35s | The 1486.35s - 1488.35s | One 1488.35s - 1490.35s | That 1490.35s - 1492.35s | Is 1492.35s - 1494.35s | The 1494.35s - 1496.35s | One 1496.35s - 1498.35s | That 1498.35s - 1500.35s | Is 1500.35s - 1502.35s | The 1502.35s - 1504.35s | One 1504.35s - 1506.35s | That 1506.35s - 1508.35s | Is 1508.35s - 1510.35s | The 1510.35s - 1512.35s | One 1512.35s - 1514.35s | That 1514.35s - 1516.35s | Is 1516.35s - 1518.35s | The 1518.35s - 1520.35s | One 1520.35s - 1522.35s | That 1522.35s - 1524.35s | Is 1524.35s - 1526.35s | The 1526.35s - 1528.35s | One 1528.35s - 1530.35s | That 1530.35s - 1532.35s | Is 1532.35s - 1534.35s | The 1534.35s - 1536.35s | One 1536.35s - 1538.35s | That 1538.35s - 1540.35s | Is 1540.35s - 1542.35s | The 1542.35s - 1544.35s | One 1544.35s - 1546.35s | That 1546.35s - 1548.35s | Is 1548.35s - 1550.35s | The 1550.35s - 1552.35s | One 1552.35s - 1554.35s | That 1554.35s - 1556.35s | Is 1556.35s - 1558.35s | The 1558.35s - 1560.35s | One 1560.35s - 1562.35s | That 1562.35s - 1564.35s | Is 1564.35s - 1566.35s | The 1566.35s - 1568.35s | One 1568.35s - 1570.35s | That 1570.35s - 1572.35s | Is 1572.35s - 1574.35s | The 1574.35s - 1576.35s | One 1576.35s - 1578.35s | That 1578.35s - 1580.35s | Is 1580.35s - 1582.35s | The 1582.35s - 1584.35s | One 1584.35s - 1586.35s | That 1586.35s - 1588.35s | Is 1588.35s - 1590.35s | The 1590.35s - 1592.35s | One 1592.35s - 1594.35s | That 1594.35s - 1596.35s | Is 1596.35s - 1598.35s | The 1598.35s - 1600.35s | One 1600.35s - 1602.35s | That 1602.35s - 1604.35s | Is 1604.35s - 1606.35s | The 1606.35s - 1608.35s | One 1608.35s - 1610.35s | That 1610.35s - 1612.35s | Is 1612.35s - 1614.35s | The 1614.35s - 1616.35s | One


chunk_id: 164_chunk_25
chunk_text:
1536.35s - 1538.35s | That 1538.35s - 1540.35s | Is 1540.35s - 1542.35s | The 1542.35s - 1544.35s | One 1544.35s - 1546.35s | That 1546.35s - 1548.35s | Is 1548.35s - 1550.35s | The 1550.35s - 1552.35s | One 1552.35s - 1554.35s | That 1554.35s - 1556.35s | Is 1556.35s - 1558.35s | The 1558.35s - 1560.35s | One 1560.35s - 1562.35s | That 1562.35s - 1564.35s | Is 1564.35s - 1566.35s | The 1566.35s - 1568.35s | One 1568.35s - 1570.35s | That 1570.35s - 1572.35s | Is 1572.35s - 1574.35s | The 1574.35s - 1576.35s | One 1576.35s - 1578.35s | That 1578.35s - 1580.35s | Is 1580.35s - 1582.35s | The 1582.35s - 1584.35s | One 1584.35s - 1586.35s | That 1586.35s - 1588.35s | Is 1588.35s - 1590.35s | The 1590.35s - 1592.35s | One 1592.35s - 1594.35s | That 1594.35s - 1596.35s | Is 1596.35s - 1598.35s | The 1598.35s - 1600.35s | One 1600.35s - 1602.35s | That 1602.35s - 1604.35s | Is 1604.35s - 1606.35s | The 1606.35s - 1608.35s | One 1608.35s - 1610.35s | That 1610.35s - 1612.35s | Is 1612.35s - 1614.35s | The 1614.35s - 1616.35s | One 1616.35s - 1618.35s | That 1618.35s - 1620.35s | Is 1620.35s - 1622.35s | The 1622.35s - 1624.35s | One 1624.35s - 1626.35s | That 1626.35s - 1628.35s | Is 1628.35s - 1630.35s | The 1630.35s - 1632.35s | One 1632.35s - 1634.35s | That 1634.35s - 1636.35s | Is 1636.35s - 1638.35s | The 1638.35s - 1640.35s | One 1640.35s - 1642.35s | That 1642.35s - 1644.35s | Is 1644.35s - 1646.35s | The 1646.35s - 1648.35s | One 1648.35s - 1650.35s | That 1650.35s - 1652.35s | Is 1652.35s - 1654.35s | The 1654.35s - 1656.35s | One 1656.35s - 1658.35s | That 1658.35s - 1660.35s | Is 1660.35s - 1662.35s | The 1662.35s - 1664.35s | One 1664.35s - 1666.35s | That 1666.35s - 1668.35s | Is 1668.35s - 1670.35s | The 1670.35s - 1672.35s | One 1672.35s - 1674.35s | That 1674.35s - 1676.35s | Is 1676.35s - 1678.35s | The 1678.35s - 1680.35s | One 1680.35s - 1682.35s | That 1682.35s - 1684.35s | Is 1684.35s - 1686.35s | The 1686.35s - 1688.35s | One 1688.35s - 1690.35s | That 1690.35s - 1692.35s | Is 1692.35s - 1694.35s | The 1694.35s - 1698.66s | One


chunk_id: 164_chunk_26
chunk_text:
1616.35s - 1618.35s | That 1618.35s - 1620.35s | Is 1620.35s - 1622.35s | The 1622.35s - 1624.35s | One 1624.35s - 1626.35s | That 1626.35s - 1628.35s | Is 1628.35s - 1630.35s | The 1630.35s - 1632.35s | One 1632.35s - 1634.35s | That 1634.35s - 1636.35s | Is 1636.35s - 1638.35s | The 1638.35s - 1640.35s | One 1640.35s - 1642.35s | That 1642.35s - 1644.35s | Is 1644.35s - 1646.35s | The 1646.35s - 1648.35s | One 1648.35s - 1650.35s | That 1650.35s - 1652.35s | Is 1652.35s - 1654.35s | The 1654.35s - 1656.35s | One 1656.35s - 1658.35s | That 1658.35s - 1660.35s | Is 1660.35s - 1662.35s | The 1662.35s - 1664.35s | One 1664.35s - 1666.35s | That 1666.35s - 1668.35s | Is 1668.35s - 1670.35s | The 1670.35s - 1672.35s | One 1672.35s - 1674.35s | That 1674.35s - 1676.35s | Is 1676.35s - 1678.35s | The 1678.35s - 1680.35s | One 1680.35s - 1682.35s | That 1682.35s - 1684.35s | Is 1684.35s - 1686.35s | The 1686.35s - 1688.35s | One 1688.35s - 1690.35s | That 1690.35s - 1692.35s | Is 1692.35s - 1694.35s | The 1694.35s - 1698.66s | One 1698.66s - 1706.77s | That 1706.77s - 1708.77s | Is 1708.77s - 1710.77s | The 1710.77s - 1712.77s | One 1712.77s - 1714.77s | That 1714.77s - 1716.77s | Is 1716.77s - 1718.77s | The 1718.77s - 1720.77s | One 1720.77s - 1722.77s | That 1722.77s - 1724.77s | Is 1724.77s - 1726.77s | The 1726.77s - 1728.77s | One 1728.77s - 1730.77s | That 1730.77s - 1732.77s | Is 1732.77s - 1734.77s | The 1734.77s - 1736.77s | One 1736.77s - 1738.77s | That 1738.77s - 1740.77s | Is 1740.77s - 1742.77s | The 1742.77s - 1744.77s | One 1744.77s - 1746.77s | That 1746.77s - 1748.77s | Is 1748.77s - 1750.77s | The 1750.77s - 1752.77s | One 1752.77s - 1754.77s | That 1754.77s - 1756.77s | Is 1756.77s - 1758.77s | The 1758.77s - 1760.77s | One 1760.77s - 1762.77s | That 1762.77s - 1764.77s | Is 1764.77s - 1766.77s | The 1766.77s - 1768.77s | One 1768.77s - 1770.77s | That 1770.77s - 1772.77s | Is 1772.77s - 1774.77s | The 1774.77s - 1776.77s | One 1776.77s - 1778.77s | That 1778.77s - 1780.77s | Is 1780.77s - 1782.77s | The 1782.77s - 1784.77s | One


chunk_id: 164_chunk_27
chunk_text:
1698.66s - 1706.77s | That 1706.77s - 1708.77s | Is 1708.77s - 1710.77s | The 1710.77s - 1712.77s | One 1712.77s - 1714.77s | That 1714.77s - 1716.77s | Is 1716.77s - 1718.77s | The 1718.77s - 1720.77s | One 1720.77s - 1722.77s | That 1722.77s - 1724.77s | Is 1724.77s - 1726.77s | The 1726.77s - 1728.77s | One 1728.77s - 1730.77s | That 1730.77s - 1732.77s | Is 1732.77s - 1734.77s | The 1734.77s - 1736.77s | One 1736.77s - 1738.77s | That 1738.77s - 1740.77s | Is 1740.77s - 1742.77s | The 1742.77s - 1744.77s | One 1744.77s - 1746.77s | That 1746.77s - 1748.77s | Is 1748.77s - 1750.77s | The 1750.77s - 1752.77s | One 1752.77s - 1754.77s | That 1754.77s - 1756.77s | Is 1756.77s - 1758.77s | The 1758.77s - 1760.77s | One 1760.77s - 1762.77s | That 1762.77s - 1764.77s | Is 1764.77s - 1766.77s | The 1766.77s - 1768.77s | One 1768.77s - 1770.77s | That 1770.77s - 1772.77s | Is 1772.77s - 1774.77s | The 1774.77s - 1776.77s | One 1776.77s - 1778.77s | That 1778.77s - 1780.77s | Is 1780.77s - 1782.77s | The 1782.77s - 1784.77s | One 1784.77s - 1786.77s | That 1786.77s - 1788.77s | Is 1788.77s - 1790.77s | The 1790.77s - 1792.77s | One 1792.77s - 1794.77s | That 1794.77s - 1796.77s | Is 1796.77s - 1798.77s | The 1798.77s - 1800.77s | One 1800.77s - 1802.77s | That 1802.77s - 1804.77s | Is 1804.77s - 1806.77s | The 1806.77s - 1808.77s | One 1808.77s - 1810.77s | That 1810.77s - 1812.77s | Is 1812.77s - 1814.77s | The 1814.77s - 1816.77s | One 1816.77s - 1818.77s | That 1818.77s - 1820.77s | Is 1820.77s - 1822.77s | The 1822.77s - 1824.77s | One 1824.77s - 1826.77s | That 1826.77s - 1828.77s | Is 1828.77s - 1830.77s | The 1830.77s - 1832.77s | One 1832.77s - 1834.77s | That 1834.77s - 1836.77s | Is 1836.77s - 1838.77s | The 1838.77s - 1840.77s | One 1840.77s - 1842.77s | That 1842.77s - 1844.77s | Is 1844.77s - 1846.77s | The 1846.77s - 1848.77s | One 1848.77s - 1850.77s | That 1850.77s - 1852.77s | Is 1852.77s - 1854.77s | The 1854.77s - 1856.77s | One 1856.77s - 1858.77s | That 1858.77s - 1860.77s | Is 1860.77s - 1862.77s | The 1862.77s - 1864.77s | One


chunk_id: 164_chunk_28
chunk_text:
1784.77s - 1786.77s | That 1786.77s - 1788.77s | Is 1788.77s - 1790.77s | The 1790.77s - 1792.77s | One 1792.77s - 1794.77s | That 1794.77s - 1796.77s | Is 1796.77s - 1798.77s | The 1798.77s - 1800.77s | One 1800.77s - 1802.77s | That 1802.77s - 1804.77s | Is 1804.77s - 1806.77s | The 1806.77s - 1808.77s | One 1808.77s - 1810.77s | That 1810.77s - 1812.77s | Is 1812.77s - 1814.77s | The 1814.77s - 1816.77s | One 1816.77s - 1818.77s | That 1818.77s - 1820.77s | Is 1820.77s - 1822.77s | The 1822.77s - 1824.77s | One 1824.77s - 1826.77s | That 1826.77s - 1828.77s | Is 1828.77s - 1830.77s | The 1830.77s - 1832.77s | One 1832.77s - 1834.77s | That 1834.77s - 1836.77s | Is 1836.77s - 1838.77s | The 1838.77s - 1840.77s | One 1840.77s - 1842.77s | That 1842.77s - 1844.77s | Is 1844.77s - 1846.77s | The 1846.77s - 1848.77s | One 1848.77s - 1850.77s | That 1850.77s - 1852.77s | Is 1852.77s - 1854.77s | The 1854.77s - 1856.77s | One 1856.77s - 1858.77s | That 1858.77s - 1860.77s | Is 1860.77s - 1862.77s | The 1862.77s - 1864.77s | One 1864.77s - 1866.77s | That 1866.77s - 1868.77s | Is 1868.77s - 1870.77s | The 1870.77s - 1872.77s | One 1872.77s - 1874.77s | That 1874.77s - 1876.77s | Is 1876.77s - 1878.77s | The 1878.77s - 1880.77s | One 1880.77s - 1882.77s | That 1882.77s - 1884.77s | Is 1884.77s - 1886.77s | The 1886.77s - 1888.77s | One 1888.77s - 1890.77s | That 1890.77s - 1892.77s | Is 1892.77s - 1894.77s | The 1894.77s - 1896.77s | One 1896.77s - 1898.77s | That 1898.77s - 1900.77s | Is 1900.77s - 1902.77s | The 1902.77s - 1904.77s | One 1904.77s - 1906.77s | That 1906.77s - 1908.77s | Is 1908.77s - 1910.77s | The 1910.77s - 1912.77s | One 1912.77s - 1914.77s | That 1914.77s - 1916.77s | Is 1916.77s - 1918.77s | The 1918.77s - 1920.77s | One 1920.77s - 1922.77s | That 1922.77s - 1924.77s | Is 1924.77s - 1928.40s | The 1928.40s - 1930.40s | One 1930.40s - 1932.40s | That 1932.40s - 1934.40s | Is 1934.40s - 1936.40s | The 1936.40s - 1938.40s | One 1938.40s - 1940.40s | That 1940.40s - 1942.40s | Is 1942.40s - 1944.40s | The 1944.40s - 1946.40s | One


chunk_id: 164_chunk_29
chunk_text:
1864.77s - 1866.77s | That 1866.77s - 1868.77s | Is 1868.77s - 1870.77s | The 1870.77s - 1872.77s | One 1872.77s - 1874.77s | That 1874.77s - 1876.77s | Is 1876.77s - 1878.77s | The 1878.77s - 1880.77s | One 1880.77s - 1882.77s | That 1882.77s - 1884.77s | Is 1884.77s - 1886.77s | The 1886.77s - 1888.77s | One 1888.77s - 1890.77s | That 1890.77s - 1892.77s | Is 1892.77s - 1894.77s | The 1894.77s - 1896.77s | One 1896.77s - 1898.77s | That 1898.77s - 1900.77s | Is 1900.77s - 1902.77s | The 1902.77s - 1904.77s | One 1904.77s - 1906.77s | That 1906.77s - 1908.77s | Is 1908.77s - 1910.77s | The 1910.77s - 1912.77s | One 1912.77s - 1914.77s | That 1914.77s - 1916.77s | Is 1916.77s - 1918.77s | The 1918.77s - 1920.77s | One 1920.77s - 1922.77s | That 1922.77s - 1924.77s | Is 1924.77s - 1928.40s | The 1928.40s - 1930.40s | One 1930.40s - 1932.40s | That 1932.40s - 1934.40s | Is 1934.40s - 1936.40s | The 1936.40s - 1938.40s | One 1938.40s - 1940.40s | That 1940.40s - 1942.40s | Is 1942.40s - 1944.40s | The 1944.40s - 1946.40s | One 1946.40s - 1948.40s | That 1948.40s - 1950.40s | Is 1950.40s - 1952.40s | The 1952.40s - 1954.40s | One 1954.40s - 1956.40s | That 1956.40s - 1958.40s | Is 1958.40s - 1960.40s | The 1960.40s - 1962.40s | One 1962.40s - 1964.40s | That 1964.40s - 1966.40s | Is 1966.40s - 1968.40s | The 1968.40s - 1970.40s | One 1970.40s - 1972.40s | That 1972.40s - 1974.40s | Is 1974.40s - 1976.40s | The 1976.40s - 1978.40s | One 1978.40s - 1980.40s | That 1980.40s - 1982.40s | Is 1982.40s - 1984.40s | The 1984.40s - 1986.40s | One 1986.40s - 1988.40s | That 1988.40s - 1990.40s | Is 1990.40s - 1992.40s | The 1992.40s - 1994.40s | One 1994.40s - 1996.40s | That 1996.40s - 1998.40s | Is 1998.40s - 2000.40s | The 2000.40s - 2002.40s | One 2002.40s - 2004.40s | That 2004.40s - 2006.40s | Is 2006.40s - 2008.40s | The 2008.40s - 2010.40s | One 2010.40s - 2012.40s | That 2012.40s - 2014.40s | Is 2014.40s - 2016.40s | The 2016.40s - 2018.40s | One 2018.40s - 2020.40s | That 2020.40s - 2022.40s | Is 2022.40s - 2024.40s | The 2024.40s - 2026.40s | One


chunk_id: 164_chunk_30
chunk_text:
1946.40s - 1948.40s | That 1948.40s - 1950.40s | Is 1950.40s - 1952.40s | The 1952.40s - 1954.40s | One 1954.40s - 1956.40s | That 1956.40s - 1958.40s | Is 1958.40s - 1960.40s | The 1960.40s - 1962.40s | One 1962.40s - 1964.40s | That 1964.40s - 1966.40s | Is 1966.40s - 1968.40s | The 1968.40s - 1970.40s | One 1970.40s - 1972.40s | That 1972.40s - 1974.40s | Is 1974.40s - 1976.40s | The 1976.40s - 1978.40s | One 1978.40s - 1980.40s | That 1980.40s - 1982.40s | Is 1982.40s - 1984.40s | The 1984.40s - 1986.40s | One 1986.40s - 1988.40s | That 1988.40s - 1990.40s | Is 1990.40s - 1992.40s | The 1992.40s - 1994.40s | One 1994.40s - 1996.40s | That 1996.40s - 1998.40s | Is 1998.40s - 2000.40s | The 2000.40s - 2002.40s | One 2002.40s - 2004.40s | That 2004.40s - 2006.40s | Is 2006.40s - 2008.40s | The 2008.40s - 2010.40s | One 2010.40s - 2012.40s | That 2012.40s - 2014.40s | Is 2014.40s - 2016.40s | The 2016.40s - 2018.40s | One 2018.40s - 2020.40s | That 2020.40s - 2022.40s | Is 2022.40s - 2024.40s | The 2024.40s - 2026.40s | One 2026.40s - 2028.40s | That 2028.40s - 2030.40s | Is 2030.40s - 2032.40s | The 2032.40s - 2034.40s | One 2034.40s - 2036.40s | That 2036.40s - 2038.40s | Is 2038.40s - 2040.40s | The 2040.40s - 2042.40s | One 2042.40s - 2044.40s | That 2044.40s - 2046.40s | Is 2046.40s - 2048.40s | The 2048.40s - 2050.40s | One 2050.40s - 2052.40s | That 2052.40s - 2054.40s | Is 2054.40s - 2056.40s | The 2056.40s - 2058.40s | One 2058.40s - 2060.40s | That 2060.40s - 2062.40s | Is 2062.40s - 2064.40s | The 2064.40s - 2066.40s | One 2066.40s - 2068.40s | That 2068.40s - 2070.40s | Is 2070.40s - 2072.40s | The 2072.40s - 2074.40s | One 2074.40s - 2076.40s | That 2076.40s - 2078.40s | Is 2078.40s - 2080.40s | The 2080.40s - 2082.40s | One 2082.40s - 2084.40s | That 2084.40s - 2086.40s | Is 2086.40s - 2088.40s | The 2088.40s - 2090.40s | One 2090.40s - 2092.40s | That 2092.40s - 2094.40s | Is 2094.40s - 2096.40s | The 2096.40s - 2098.40s | One 2098.40s - 2100.40s | That 2100.40s - 2102.40s | Is 2102.40s - 2104.40s | The 2104.40s - 2106.40s | One


chunk_id: 164_chunk_31
chunk_text:
2026.40s - 2028.40s | That 2028.40s - 2030.40s | Is 2030.40s - 2032.40s | The 2032.40s - 2034.40s | One 2034.40s - 2036.40s | That 2036.40s - 2038.40s | Is 2038.40s - 2040.40s | The 2040.40s - 2042.40s | One 2042.40s - 2044.40s | That 2044.40s - 2046.40s | Is 2046.40s - 2048.40s | The 2048.40s - 2050.40s | One 2050.40s - 2052.40s | That 2052.40s - 2054.40s | Is 2054.40s - 2056.40s | The 2056.40s - 2058.40s | One 2058.40s - 2060.40s | That 2060.40s - 2062.40s | Is 2062.40s - 2064.40s | The 2064.40s - 2066.40s | One 2066.40s - 2068.40s | That 2068.40s - 2070.40s | Is 2070.40s - 2072.40s | The 2072.40s - 2074.40s | One 2074.40s - 2076.40s | That 2076.40s - 2078.40s | Is 2078.40s - 2080.40s | The 2080.40s - 2082.40s | One 2082.40s - 2084.40s | That 2084.40s - 2086.40s | Is 2086.40s - 2088.40s | The 2088.40s - 2090.40s | One 2090.40s - 2092.40s | That 2092.40s - 2094.40s | Is 2094.40s - 2096.40s | The 2096.40s - 2098.40s | One 2098.40s - 2100.40s | That 2100.40s - 2102.40s | Is 2102.40s - 2104.40s | The 2104.40s - 2106.40s | One 2106.40s - 2108.40s | That 2108.40s - 2110.40s | Is 2110.40s - 2112.40s | The 2112.40s - 2114.40s | One 2114.40s - 2116.40s | That 2116.40s - 2118.40s | Is 2118.40s - 2120.40s | The 2120.40s - 2122.40s | One 2122.40s - 2124.40s | That 2124.40s - 2126.40s | Is 2126.40s - 2128.40s | The 2128.40s - 2130.40s | One 2130.40s - 2132.40s | That 2132.40s - 2134.40s | Is 2134.40s - 2136.40s | The 2136.40s - 2138.40s | One 2138.40s - 2140.40s | That 2140.40s - 2142.40s | Is 2142.40s - 2144.40s | The 2144.40s - 2146.40s | One 2146.40s - 2148.40s | That 2148.40s - 2150.40s | Is 2150.40s - 2152.40s | The 2152.40s - 2154.40s | One 2154.40s - 2156.40s | That 2156.40s - 2158.40s | Is 2158.40s - 2160.40s | The 2160.40s - 2162.40s | One 2162.40s - 2164.40s | That 2164.40s - 2166.40s | Is 2166.40s - 2168.40s | The 2168.40s - 2170.40s | One 2170.40s - 2172.40s | That 2172.40s - 2174.40s | Is 2174.40s - 2176.40s | The 2176.40s - 2178.40s | One 2178.40s - 2180.40s | That 2180.40s - 2182.40s | Is 2182.40s - 2184.40s | The 2184.40s - 2186.40s | One


chunk_id: 164_chunk_32
chunk_text:
2106.40s - 2108.40s | That 2108.40s - 2110.40s | Is 2110.40s - 2112.40s | The 2112.40s - 2114.40s | One 2114.40s - 2116.40s | That 2116.40s - 2118.40s | Is 2118.40s - 2120.40s | The 2120.40s - 2122.40s | One 2122.40s - 2124.40s | That 2124.40s - 2126.40s | Is 2126.40s - 2128.40s | The 2128.40s - 2130.40s | One 2130.40s - 2132.40s | That 2132.40s - 2134.40s | Is 2134.40s - 2136.40s | The 2136.40s - 2138.40s | One 2138.40s - 2140.40s | That 2140.40s - 2142.40s | Is 2142.40s - 2144.40s | The 2144.40s - 2146.40s | One 2146.40s - 2148.40s | That 2148.40s - 2150.40s | Is 2150.40s - 2152.40s | The 2152.40s - 2154.40s | One 2154.40s - 2156.40s | That 2156.40s - 2158.40s | Is 2158.40s - 2160.40s | The 2160.40s - 2162.40s | One 2162.40s - 2164.40s | That 2164.40s - 2166.40s | Is 2166.40s - 2168.40s | The 2168.40s - 2170.40s | One 2170.40s - 2172.40s | That 2172.40s - 2174.40s | Is 2174.40s - 2176.40s | The 2176.40s - 2178.40s | One 2178.40s - 2180.40s | That 2180.40s - 2182.40s | Is 2182.40s - 2184.40s | The 2184.40s - 2186.40s | One 2186.40s - 2188.40s | That 2188.40s - 2190.40s | Is 2190.40s - 2192.40s | The 2192.40s - 2194.40s | One 2194.40s - 2196.40s | That 2196.40s - 2198.40s | Is 2198.40s - 2200.40s | The 2200.40s - 2202.40s | One 2202.40s - 2204.40s | That 2204.40s - 2206.40s | Is 2206.40s - 2208.40s | The 2208.40s - 2210.40s | One 2210.40s - 2212.40s | That 2212.40s - 2214.40s | Is 2214.40s - 2216.40s | The 2216.40s - 2218.40s | One 2218.40s - 2220.40s | That 2220.40s - 2222.40s | Is 2222.40s - 2224.40s | The 2224.40s - 2226.40s | One 2226.40s - 2228.40s | That 2228.40s - 2230.40s | Is 2230.40s - 2232.40s | The 2232.40s - 2234.40s | One 2234.40s - 2236.40s | That 2236.40s - 2238.40s | Is 2238.40s - 2240.40s | The 2240.40s - 2242.40s | One 2242.40s - 2244.40s | That 2244.40s - 2246.40s | Is 2246.40s - 2248.40s | The 2248.40s - 2250.40s | One 2250.40s - 2252.40s | That 2252.40s - 2254.40s | Is 2254.40s - 2256.40s | The 2256.40s - 2258.40s | One 2258.40s - 2260.40s | That 2260.40s - 2262.40s | Is 2262.40s - 2264.40s | The 2264.40s - 2266.40s | One


chunk_id: 164_chunk_33
chunk_text:
2186.40s - 2188.40s | That 2188.40s - 2190.40s | Is 2190.40s - 2192.40s | The 2192.40s - 2194.40s | One 2194.40s - 2196.40s | That 2196.40s - 2198.40s | Is 2198.40s - 2200.40s | The 2200.40s - 2202.40s | One 2202.40s - 2204.40s | That 2204.40s - 2206.40s | Is 2206.40s - 2208.40s | The 2208.40s - 2210.40s | One 2210.40s - 2212.40s | That 2212.40s - 2214.40s | Is 2214.40s - 2216.40s | The 2216.40s - 2218.40s | One 2218.40s - 2220.40s | That 2220.40s - 2222.40s | Is 2222.40s - 2224.40s | The 2224.40s - 2226.40s | One 2226.40s - 2228.40s | That 2228.40s - 2230.40s | Is 2230.40s - 2232.40s | The 2232.40s - 2234.40s | One 2234.40s - 2236.40s | That 2236.40s - 2238.40s | Is 2238.40s - 2240.40s | The 2240.40s - 2242.40s | One 2242.40s - 2244.40s | That 2244.40s - 2246.40s | Is 2246.40s - 2248.40s | The 2248.40s - 2250.40s | One 2250.40s - 2252.40s | That 2252.40s - 2254.40s | Is 2254.40s - 2256.40s | The 2256.40s - 2258.40s | One 2258.40s - 2260.40s | That 2260.40s - 2262.40s | Is 2262.40s - 2264.40s | The 2264.40s - 2266.40s | One 2266.40s - 2268.40s | That 2268.40s - 2270.40s | Is 2270.40s - 2272.40s | The 2272.40s - 2274.40s | One 2274.40s - 2276.40s | That 2276.40s - 2278.40s | Is 2278.40s - 2280.40s | The 2280.40s - 2282.40s | One 2282.40s - 2284.40s | That 2284.40s - 2286.40s | Is 2286.40s - 2288.40s | The 2288.40s - 2290.40s | One 2290.40s - 2292.40s | That 2292.40s - 2294.40s | Is 2294.40s - 2296.40s | The 2296.40s - 2298.40s | One 2298.40s - 2300.40s | That 2300.40s - 2302.40s | Is 2302.40s - 2304.40s | The 2304.40s - 2306.40s | One 2306.40s - 2308.40s | That 2308.40s - 2310.40s | Is 2310.40s - 2312.40s | The 2312.40s - 2314.40s | One 2314.40s - 2316.40s | That 2316.40s - 2318.40s | Is 2318.40s - 2320.40s | The 2320.40s - 2322.40s | One 2322.40s - 2324.40s | That 2324.40s - 2326.40s | Is 2326.40s - 2328.40s | The 2328.40s - 2330.40s | One 2330.40s - 2332.40s | That 2332.40s - 2334.40s | Is 2334.40s - 2336.40s | The 2336.40s - 2338.40s | One 2338.40s - 2340.40s | That 2340.40s - 2342.40s | Is 2342.40s - 2344.40s | The 2344.40s - 2346.40s | One


chunk_id: 164_chunk_34
chunk_text:
2266.40s - 2268.40s | That 2268.40s - 2270.40s | Is 2270.40s - 2272.40s | The 2272.40s - 2274.40s | One 2274.40s - 2276.40s | That 2276.40s - 2278.40s | Is 2278.40s - 2280.40s | The 2280.40s - 2282.40s | One 2282.40s - 2284.40s | That 2284.40s - 2286.40s | Is 2286.40s - 2288.40s | The 2288.40s - 2290.40s | One 2290.40s - 2292.40s | That 2292.40s - 2294.40s | Is 2294.40s - 2296.40s | The 2296.40s - 2298.40s | One 2298.40s - 2300.40s | That 2300.40s - 2302.40s | Is 2302.40s - 2304.40s | The 2304.40s - 2306.40s | One 2306.40s - 2308.40s | That 2308.40s - 2310.40s | Is 2310.40s - 2312.40s | The 2312.40s - 2314.40s | One 2314.40s - 2316.40s | That 2316.40s - 2318.40s | Is 2318.40s - 2320.40s | The 2320.40s - 2322.40s | One 2322.40s - 2324.40s | That 2324.40s - 2326.40s | Is 2326.40s - 2328.40s | The 2328.40s - 2330.40s | One 2330.40s - 2332.40s | That 2332.40s - 2334.40s | Is 2334.40s - 2336.40s | The 2336.40s - 2338.40s | One 2338.40s - 2340.40s | That 2340.40s - 2342.40s | Is 2342.40s - 2344.40s | The 2344.40s - 2346.40s | One 2346.40s - 2348.40s | That 2348.40s - 2350.40s | Is 2350.40s - 2352.40s | The 2352.40s - 2354.40s | One 2354.40s - 2356.40s | That 2356.40s - 2358.40s | Is 2358.40s - 2360.40s | The 2360.40s - 2362.40s | One 2362.40s - 2364.40s | That 2364.40s - 2366.40s | Is 2366.40s - 2368.40s | The 2368.40s - 2370.40s | One 2370.40s - 2372.40s | That 2372.40s - 2374.40s | Is 2374.40s - 2376.40s | The 2376.40s - 2378.40s | One 2378.40s - 2380.40s | That 2380.40s - 2382.40s | Is 2382.40s - 2384.40s | The 2384.40s - 2386.40s | One 2386.40s - 2388.40s | That 2388.40s - 2390.40s | Is 2390.40s - 2392.40s | The 2392.40s - 2394.40s | One 2394.40s - 2396.40s | That 2396.40s - 2398.40s | Is 2398.40s - 2400.40s | The 2400.40s - 2402.40s | One 2402.40s - 2404.40s | That 2404.40s - 2406.40s | Is 2406.40s - 2408.40s | The 2408.40s - 2410.40s | One 2410.40s - 2413.90s | That 2413.90s - 2415.90s | Is 2415.90s - 2417.90s | The 2417.90s - 2419.90s | One 2419.90s - 2421.90s | That 2421.90s - 2423.90s | Is 2423.90s - 2425.90s | The 2425.90s - 2427.90s | One


chunk_id: 164_chunk_35
chunk_text:
2346.40s - 2348.40s | That 2348.40s - 2350.40s | Is 2350.40s - 2352.40s | The 2352.40s - 2354.40s | One 2354.40s - 2356.40s | That 2356.40s - 2358.40s | Is 2358.40s - 2360.40s | The 2360.40s - 2362.40s | One 2362.40s - 2364.40s | That 2364.40s - 2366.40s | Is 2366.40s - 2368.40s | The 2368.40s - 2370.40s | One 2370.40s - 2372.40s | That 2372.40s - 2374.40s | Is 2374.40s - 2376.40s | The 2376.40s - 2378.40s | One 2378.40s - 2380.40s | That 2380.40s - 2382.40s | Is 2382.40s - 2384.40s | The 2384.40s - 2386.40s | One 2386.40s - 2388.40s | That 2388.40s - 2390.40s | Is 2390.40s - 2392.40s | The 2392.40s - 2394.40s | One 2394.40s - 2396.40s | That 2396.40s - 2398.40s | Is 2398.40s - 2400.40s | The 2400.40s - 2402.40s | One 2402.40s - 2404.40s | That 2404.40s - 2406.40s | Is 2406.40s - 2408.40s | The 2408.40s - 2410.40s | One 2410.40s - 2413.90s | That 2413.90s - 2415.90s | Is 2415.90s - 2417.90s | The 2417.90s - 2419.90s | One 2419.90s - 2421.90s | That 2421.90s - 2423.90s | Is 2423.90s - 2425.90s | The 2425.90s - 2427.90s | One 2427.90s - 2429.90s | That 2429.90s - 2431.90s | Is 2431.90s - 2433.90s | The 2433.90s - 2435.90s | One 2435.90s - 2437.90s | That 2437.90s - 2439.90s | Is 2439.90s - 2441.90s | The 2441.90s - 2443.90s | One 2443.90s - 2445.90s | That 2445.90s - 2447.90s | Is 2447.90s - 2449.90s | The 2449.90s - 2451.90s | One 2451.90s - 2453.90s | That 2453.90s - 2455.90s | Is 2455.90s - 2457.90s | The 2457.90s - 2459.90s | One 2459.90s - 2461.90s | That 2461.90s - 2463.90s | Is 2463.90s - 2465.90s | The 2465.90s - 2467.90s | One 2467.90s - 2469.90s | That 2469.90s - 2473.44s | Is 2473.44s - 2475.44s | The 2475.44s - 2477.44s | One 2477.44s - 2479.44s | That 2479.44s - 2481.44s | Is 2481.44s - 2483.44s | The 2483.44s - 2485.44s | One 2485.44s - 2487.44s | That 2487.44s - 2489.44s | Is 2489.44s - 2491.44s | The 2491.44s - 2493.44s | One 2493.44s - 2495.44s | That 2495.44s - 2499.87s | Is 2499.87s - 2501.87s | The 2501.87s - 2503.87s | One 2503.87s - 2505.87s | That 2505.87s - 2507.87s | Is 2507.87s - 2509.87s | The 2509.87s - 2511.87s | One


chunk_id: 164_chunk_36
chunk_text:
2427.90s - 2429.90s | That 2429.90s - 2431.90s | Is 2431.90s - 2433.90s | The 2433.90s - 2435.90s | One 2435.90s - 2437.90s | That 2437.90s - 2439.90s | Is 2439.90s - 2441.90s | The 2441.90s - 2443.90s | One 2443.90s - 2445.90s | That 2445.90s - 2447.90s | Is 2447.90s - 2449.90s | The 2449.90s - 2451.90s | One 2451.90s - 2453.90s | That 2453.90s - 2455.90s | Is 2455.90s - 2457.90s | The 2457.90s - 2459.90s | One 2459.90s - 2461.90s | That 2461.90s - 2463.90s | Is 2463.90s - 2465.90s | The 2465.90s - 2467.90s | One 2467.90s - 2469.90s | That 2469.90s - 2473.44s | Is 2473.44s - 2475.44s | The 2475.44s - 2477.44s | One 2477.44s - 2479.44s | That 2479.44s - 2481.44s | Is 2481.44s - 2483.44s | The 2483.44s - 2485.44s | One 2485.44s - 2487.44s | That 2487.44s - 2489.44s | Is 2489.44s - 2491.44s | The 2491.44s - 2493.44s | One 2493.44s - 2495.44s | That 2495.44s - 2499.87s | Is 2499.87s - 2501.87s | The 2501.87s - 2503.87s | One 2503.87s - 2505.87s | That 2505.87s - 2507.87s | Is 2507.87s - 2509.87s | The 2509.87s - 2511.87s | One 2511.87s - 2513.87s | That 2513.87s - 2515.87s | Is 2515.87s - 2517.87s | The 2517.87s - 2519.87s | One 2519.87s - 2521.87s | That 2521.87s - 2523.87s | Is 2523.87s - 2525.87s | The 2525.87s - 2527.87s | One 2527.87s - 2529.87s | That 2529.87s - 2531.87s | Is 2531.87s - 2533.87s | The 2533.87s - 2535.87s | One 2535.87s - 2537.87s | That 2537.87s - 2539.87s | Is 2539.87s - 2541.87s | The 2541.87s - 2543.87s | One 2543.87s - 2545.87s | That 2545.87s - 2547.87s | Is 2547.87s - 2549.87s | The 2549.87s - 2551.87s | One 2551.87s - 2553.87s | That 2553.87s - 2555.87s | Is 2555.87s - 2557.87s | The 2557.87s - 2559.87s | One 2559.87s - 2561.87s | That 2561.87s - 2563.87s | Is 2563.87s - 2565.87s | The 2565.87s - 2567.87s | One 2567.87s - 2569.87s | That 2569.87s - 2571.87s | Is 2571.87s - 2573.87s | The 2573.87s - 2575.87s | One 2575.87s - 2577.87s | That 2577.87s - 2579.87s | Is 2579.87s - 2581.87s | The 2581.87s - 2583.87s | One 2583.87s - 2585.87s | That 2585.87s - 2587.87s | Is 2587.87s - 2589.87s | The 2589.87s - 2591.87s | One


chunk_id: 164_chunk_37
chunk_text:
2511.87s - 2513.87s | That 2513.87s - 2515.87s | Is 2515.87s - 2517.87s | The 2517.87s - 2519.87s | One 2519.87s - 2521.87s | That 2521.87s - 2523.87s | Is 2523.87s - 2525.87s | The 2525.87s - 2527.87s | One 2527.87s - 2529.87s | That 2529.87s - 2531.87s | Is 2531.87s - 2533.87s | The 2533.87s - 2535.87s | One 2535.87s - 2537.87s | That 2537.87s - 2539.87s | Is 2539.87s - 2541.87s | The 2541.87s - 2543.87s | One 2543.87s - 2545.87s | That 2545.87s - 2547.87s | Is 2547.87s - 2549.87s | The 2549.87s - 2551.87s | One 2551.87s - 2553.87s | That 2553.87s - 2555.87s | Is 2555.87s - 2557.87s | The 2557.87s - 2559.87s | One 2559.87s - 2561.87s | That 2561.87s - 2563.87s | Is 2563.87s - 2565.87s | The 2565.87s - 2567.87s | One 2567.87s - 2569.87s | That 2569.87s - 2571.87s | Is 2571.87s - 2573.87s | The 2573.87s - 2575.87s | One 2575.87s - 2577.87s | That 2577.87s - 2579.87s | Is 2579.87s - 2581.87s | The 2581.87s - 2583.87s | One 2583.87s - 2585.87s | That 2585.87s - 2587.87s | Is 2587.87s - 2589.87s | The 2589.87s - 2591.87s | One 2591.87s - 2593.87s | That 2593.87s - 2595.87s | Is 2595.87s - 2597.87s | The 2597.87s - 2599.87s | One 2599.87s - 2601.87s | That 2601.87s - 2603.87s | Is 2603.87s - 2605.87s | The 2605.87s - 2607.87s | One 2607.87s - 2609.87s | That 2609.87s - 2611.87s | Is 2611.87s - 2613.87s | The 2613.87s - 2615.87s | One 2615.87s - 2617.87s | That 2617.87s - 2619.87s | Is 2619.87s - 2621.87s | The 2621.87s - 2623.87s | One 2623.87s - 2625.87s | That 2625.87s - 2627.87s | Is 2627.87s - 2629.87s | The 2629.87s - 2631.87s | One 2631.87s - 2633.87s | That 2633.87s - 2635.87s | Is 2635.87s - 2637.87s | The 2637.87s - 2639.87s | One 2639.87s - 2641.87s | That 2641.87s - 2643.87s | Is 2643.87s - 2645.87s | The 2645.87s - 2647.87s | One 2647.87s - 2649.87s | That 2649.87s - 2651.87s | Is 2651.87s - 2653.87s | The 2653.87s - 2655.87s | One 2655.87s - 2657.87s | That 2657.87s - 2659.87s | Is 2659.87s - 2661.87s | The 2661.87s - 2663.87s | One 2663.87s - 2665.87s | That 2665.87s - 2667.87s | Is 2667.87s - 2669.87s | The 2669.87s - 2671.87s | One


chunk_id: 164_chunk_38
chunk_text:
2591.87s - 2593.87s | That 2593.87s - 2595.87s | Is 2595.87s - 2597.87s | The 2597.87s - 2599.87s | One 2599.87s - 2601.87s | That 2601.87s - 2603.87s | Is 2603.87s - 2605.87s | The 2605.87s - 2607.87s | One 2607.87s - 2609.87s | That 2609.87s - 2611.87s | Is 2611.87s - 2613.87s | The 2613.87s - 2615.87s | One 2615.87s - 2617.87s | That 2617.87s - 2619.87s | Is 2619.87s - 2621.87s | The 2621.87s - 2623.87s | One 2623.87s - 2625.87s | That 2625.87s - 2627.87s | Is 2627.87s - 2629.87s | The 2629.87s - 2631.87s | One 2631.87s - 2633.87s | That 2633.87s - 2635.87s | Is 2635.87s - 2637.87s | The 2637.87s - 2639.87s | One 2639.87s - 2641.87s | That 2641.87s - 2643.87s | Is 2643.87s - 2645.87s | The 2645.87s - 2647.87s | One 2647.87s - 2649.87s | That 2649.87s - 2651.87s | Is 2651.87s - 2653.87s | The 2653.87s - 2655.87s | One 2655.87s - 2657.87s | That 2657.87s - 2659.87s | Is 2659.87s - 2661.87s | The 2661.87s - 2663.87s | One 2663.87s - 2665.87s | That 2665.87s - 2667.87s | Is 2667.87s - 2669.87s | The 2669.87s - 2671.87s | One 2671.87s - 2673.87s | That 2673.87s - 2675.87s | Is 2675.87s - 2677.87s | The 2677.87s - 2679.87s | One 2679.87s - 2681.87s | That 2681.87s - 2683.87s | Is 2683.87s - 2685.87s | The 2685.87s - 2687.87s | One 2687.87s - 2689.87s | That 2689.87s - 2691.87s | Is 2691.87s - 2693.87s | The 2693.87s - 2695.87s | One 2695.87s - 2697.87s | That 2697.87s - 2699.87s | Is 2699.87s - 2701.87s | The 2701.87s - 2703.87s | One 2703.87s - 2705.87s | That 2705.87s - 2707.87s | Is 2707.87s - 2709.87s | The 2709.87s - 2711.87s | One 2711.87s - 2713.87s | That 2713.87s - 2715.87s | Is 2715.87s - 2717.87s | The 2717.87s - 2719.87s | One 2719.87s - 2721.87s | That 2721.87s - 2723.87s | Is 2723.87s - 2725.87s | The 2725.87s - 2727.87s | One 2727.87s - 2729.87s | That 2729.87s - 2731.87s | Is 2731.87s - 2733.87s | The 2733.87s - 2735.87s | One 2735.87s - 2737.87s | That 2737.87s - 2739.87s | Is 2739.87s - 2741.87s | The 2741.87s - 2743.87s | One 2743.87s - 2745.87s | That 2745.87s - 2747.87s | Is 2747.87s - 2749.87s | The 2749.87s - 2751.87s | One


chunk_id: 164_chunk_39
chunk_text:
2671.87s - 2673.87s | That 2673.87s - 2675.87s | Is 2675.87s - 2677.87s | The 2677.87s - 2679.87s | One 2679.87s - 2681.87s | That 2681.87s - 2683.87s | Is 2683.87s - 2685.87s | The 2685.87s - 2687.87s | One 2687.87s - 2689.87s | That 2689.87s - 2691.87s | Is 2691.87s - 2693.87s | The 2693.87s - 2695.87s | One 2695.87s - 2697.87s | That 2697.87s - 2699.87s | Is 2699.87s - 2701.87s | The 2701.87s - 2703.87s | One 2703.87s - 2705.87s | That 2705.87s - 2707.87s | Is 2707.87s - 2709.87s | The 2709.87s - 2711.87s | One 2711.87s - 2713.87s | That 2713.87s - 2715.87s | Is 2715.87s - 2717.87s | The 2717.87s - 2719.87s | One 2719.87s - 2721.87s | That 2721.87s - 2723.87s | Is 2723.87s - 2725.87s | The 2725.87s - 2727.87s | One 2727.87s - 2729.87s | That 2729.87s - 2731.87s | Is 2731.87s - 2733.87s | The 2733.87s - 2735.87s | One 2735.87s - 2737.87s | That 2737.87s - 2739.87s | Is 2739.87s - 2741.87s | The 2741.87s - 2743.87s | One 2743.87s - 2745.87s | That 2745.87s - 2747.87s | Is 2747.87s - 2749.87s | The 2749.87s - 2751.87s | One 2751.87s - 2753.87s | That 2753.87s - 2755.87s | Is 2755.87s - 2757.87s | The 2757.87s - 2759.87s | One 2759.87s - 2761.87s | That 2761.87s - 2763.87s | Is 2763.87s - 2765.87s | The 2765.87s - 2767.87s | One 2767.87s - 2769.87s | That 2769.87s - 2771.87s | Is 2771.87s - 2773.87s | The 2773.87s - 2775.87s | One 2775.87s - 2777.87s | That 2777.87s - 2779.87s | Is 2779.87s - 2781.87s | The 2781.87s - 2783.87s | One 2783.87s - 2785.87s | That 2785.87s - 2787.87s | Is 2787.87s - 2789.87s | The 2789.87s - 2791.87s | One 2791.87s - 2793.87s | That 2793.87s - 2795.87s | Is 2795.87s - 2797.87s | The 2797.87s - 2799.87s | One 2799.87s - 2801.87s | That


chunk_id: 164_chunk_40
chunk_text:
2751.87s - 2753.87s | That 2753.87s - 2755.87s | Is 2755.87s - 2757.87s | The 2757.87s - 2759.87s | One 2759.87s - 2761.87s | That 2761.87s - 2763.87s | Is 2763.87s - 2765.87s | The 2765.87s - 2767.87s | One 2767.87s - 2769.87s | That 2769.87s - 2771.87s | Is 2771.87s - 2773.87s | The 2773.87s - 2775.87s | One 2775.87s - 2777.87s | That 2777.87s - 2779.87s | Is 2779.87s - 2781.87s | The 2781.87s - 2783.87s | One 2783.87s - 2785.87s | That 2785.87s - 2787.87s | Is 2787.87s - 2789.87s | The 2789.87s - 2791.87s | One 2791.87s - 2793.87s | That 2793.87s - 2795.87s | Is 2795.87s - 2797.87s | The 2797.87s - 2799.87s | One 2799.87s - 2801.87s | That


chunk_id: 165_chunk_0
chunk_text:
{ "webpage_url": "https://www.youtube.com/watch?v=m9QVfYVJ7R8", "title": "DEF CON 32 - Breaching AWS Through Shadow Resources - Yakir Kadkoda, Michael Katchinskiy, Ofek Itach", "description": "The cloud seems complex, but it's what happens behind the scenes that really complicates things. Some services utilize others as resources as part of their logic/operation. Interestingly enough, it turns out that this could lead to catastrophic results if done unsafely.\n\nThis talk will present six critical vulnerabilities that we found in AWS, along with the stories and methodologies behind them. These vulnerabilities, which were all promptly acknowledged and fixed by AWS, could allow external attackers to breach almost any AWS account. The vulnerabilities range from remote code execution, which could lead to full account takeover, to information disclosure, potentially exposing sensitive data, or causing denial of service. The session will share our story of discovery, how we were able to identify commonalities among them, and how we developed a method to uncover more vulnerabilities and enhance the impact by using common techniques leading to privilege escalation. We will then detail our approach for mapping service external resources and release our Open-Source tool to research service internal API calls. We will also present a method to check if accounts have been vulnerable to this vector in the past.\n\nWe will conclude our talk with the lessons learned during this research and our future line of research. We will highlight new areas that cloud researchers need to explore when hunting for cloud vulnerabilities and highlight best practices for developers to use in complex environments.", "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw", "duration": 2231, "channel": "DEFCONConference", "uploader": "DEFCONConference", "upload_date": "20241016" } 3.95s - 8.95s | This text was transcribed using whisper model: large-v2 So, hello everybody. We are very excited to be here. 8.95s - 13.95s | And welcome to the session, Breaching AWS Accounts Through Shadow Resources. 13.95s - 18.95s | And in this session, we will demonstrate several vulnerabilities that we found on AWS. 18.95s - 23.95s | The most severe of these vulnerabilities could allow an attacker to add an admin role to another account. 23.95s - 27.23s | So, let's start. 27.23s - 34.23s | Let's start by discussing the most debatable topic on AWS, which is AWS Account ID. 34.23s - 40.23s | So, each AWS account has a unique identifier associated with it. 40.23s - 44.23s | This identifier consists of 12 digits. 44.23s - 51.23s | And the most important thing


chunk_id: 165_chunk_1
chunk_text:
been vulnerable to this vector in the past.\n\nWe will conclude our talk with the lessons learned during this research and our future line of research. We will highlight new areas that cloud researchers need to explore when hunting for cloud vulnerabilities and highlight best practices for developers to use in complex environments.", "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw", "duration": 2231, "channel": "DEFCONConference", "uploader": "DEFCONConference", "upload_date": "20241016" } 3.95s - 8.95s | This text was transcribed using whisper model: large-v2 So, hello everybody. We are very excited to be here. 8.95s - 13.95s | And welcome to the session, Breaching AWS Accounts Through Shadow Resources. 13.95s - 18.95s | And in this session, we will demonstrate several vulnerabilities that we found on AWS. 18.95s - 23.95s | The most severe of these vulnerabilities could allow an attacker to add an admin role to another account. 23.95s - 27.23s | So, let's start. 27.23s - 34.23s | Let's start by discussing the most debatable topic on AWS, which is AWS Account ID. 34.23s - 40.23s | So, each AWS account has a unique identifier associated with it. 40.23s - 44.23s | This identifier consists of 12 digits. 44.23s - 51.23s | And the most important thing about this is that some treat it as a secret and some don't. 51.23s - 58.23s | And along the history of AWS, we have many different opinions whether it is a secret or not. 58.23s - 65.23s | Although AWS in their documentation states that this account ID should be shared carefully, 65.23s - 67.23s | they do not consider this a secret. 67.23s - 71.23s | But we as security practitioners, security researchers, 71.23s - 76.23s | know that attackers could achieve problematic things only by knowing this account ID. 76.23s - 79.23s | So, what is the right answer? 79.23s - 82.23s | Are AWS account IDs secret or not? 82.23s - 88.23s | We hope that by the end of this session, we will have a more solid opinion about this. 88.23s - 91.23s | So, let us introduce ourselves. 91.23s - 98.23s | My name is Yakir Kotkoda and here with me are Michael Kaczynski and Ofik Itach. 98.23s - 101.23s | We are all security researchers from Aqua Security 101.23s - 107.23s | and we are focusing in our daily on cloud vulnerabilities, open source vulnerabilities, and more. 107.23s - 109.23s | Let me


chunk_id: 165_chunk_2
chunk_text:
about this is that some treat it as a secret and some don't. 51.23s - 58.23s | And along the history of AWS, we have many different opinions whether it is a secret or not. 58.23s - 65.23s | Although AWS in their documentation states that this account ID should be shared carefully, 65.23s - 67.23s | they do not consider this a secret. 67.23s - 71.23s | But we as security practitioners, security researchers, 71.23s - 76.23s | know that attackers could achieve problematic things only by knowing this account ID. 76.23s - 79.23s | So, what is the right answer? 79.23s - 82.23s | Are AWS account IDs secret or not? 82.23s - 88.23s | We hope that by the end of this session, we will have a more solid opinion about this. 88.23s - 91.23s | So, let us introduce ourselves. 91.23s - 98.23s | My name is Yakir Kotkoda and here with me are Michael Kaczynski and Ofik Itach. 98.23s - 101.23s | We are all security researchers from Aqua Security 101.23s - 107.23s | and we are focusing in our daily on cloud vulnerabilities, open source vulnerabilities, and more. 107.23s - 109.23s | Let me go over the agenda. 109.23s - 113.23s | We will introduce something that's called shadow resources and what they are. 113.23s - 117.23s | Then, several vulnerabilities that we found on AWS. 117.23s - 124.23s | And an open source tool that we developed during our research that helped us to find more vulnerabilities. 124.23s - 128.23s | After this, we will introduce a new technique called Bucket Monopoly 128.23s - 131.23s | that helps us emphasize the risk of our findings. 131.23s - 137.23s | And we will end our session by suggesting some mitigations and recommendations. 137.23s - 141.23s | So, let's first talk how our journey began. 141.23s - 147.23s | While we worked with the AWS Management Console, which is the GUI of AWS, 147.23s - 153.23s | we noticed that when a user used the CloudFormation service and uploaded a template file, 153.23s - 158.23s | AWS, behind the scenes, creates an S3 bucket for the user. 158.23s - 165.23s | Although the user did not explicitly ask AWS to do so, this is how the service operates. 165.23s - 169.23s | We have decided to name this kind of resources that spawned automatically 169.23s


chunk_id: 165_chunk_3
chunk_text:
go over the agenda. 109.23s - 113.23s | We will introduce something that's called shadow resources and what they are. 113.23s - 117.23s | Then, several vulnerabilities that we found on AWS. 117.23s - 124.23s | And an open source tool that we developed during our research that helped us to find more vulnerabilities. 124.23s - 128.23s | After this, we will introduce a new technique called Bucket Monopoly 128.23s - 131.23s | that helps us emphasize the risk of our findings. 131.23s - 137.23s | And we will end our session by suggesting some mitigations and recommendations. 137.23s - 141.23s | So, let's first talk how our journey began. 141.23s - 147.23s | While we worked with the AWS Management Console, which is the GUI of AWS, 147.23s - 153.23s | we noticed that when a user used the CloudFormation service and uploaded a template file, 153.23s - 158.23s | AWS, behind the scenes, creates an S3 bucket for the user. 158.23s - 165.23s | Although the user did not explicitly ask AWS to do so, this is how the service operates. 165.23s - 169.23s | We have decided to name this kind of resources that spawned automatically 169.23s - 172.23s | without the user intervention a shadow resource. 172.23s - 175.23s | So, let's explain this term. 175.23s - 179.23s | When we refer to shadow resources, we are mainly referring to resources 179.23s - 185.23s | that are generated automatically or semi-automatically by AWS. 185.23s - 189.23s | Most of the time, they spawn without user intervention 189.23s - 193.23s | and they might go unnoticed by the account owner. 193.23s - 197.23s | And the great example for this is just the S3 bucket that we saw 197.23s - 201.23s | that the CloudFormation service creates for the user. 201.23s - 206.23s | Now, let's align some common knowledge about S3 bucket, 206.23s - 210.23s | which is one of the first services by AWS. 210.23s - 213.23s | This service has some special uniqueness. 213.23s - 219.23s | First of all, S3 bucket name must be globally unique across all AWS. 219.23s - 223.23s | For example, if you create an S3 bucket called CoolBucket1, 223.23s - 227.23s | no one else on AWS could claim this name. 227.23s - 230.23s | It will be available only under your account. 230.23s - 235.23s | So,


chunk_id: 165_chunk_4
chunk_text:
- 172.23s | without the user intervention a shadow resource. 172.23s - 175.23s | So, let's explain this term. 175.23s - 179.23s | When we refer to shadow resources, we are mainly referring to resources 179.23s - 185.23s | that are generated automatically or semi-automatically by AWS. 185.23s - 189.23s | Most of the time, they spawn without user intervention 189.23s - 193.23s | and they might go unnoticed by the account owner. 193.23s - 197.23s | And the great example for this is just the S3 bucket that we saw 197.23s - 201.23s | that the CloudFormation service creates for the user. 201.23s - 206.23s | Now, let's align some common knowledge about S3 bucket, 206.23s - 210.23s | which is one of the first services by AWS. 210.23s - 213.23s | This service has some special uniqueness. 213.23s - 219.23s | First of all, S3 bucket name must be globally unique across all AWS. 219.23s - 223.23s | For example, if you create an S3 bucket called CoolBucket1, 223.23s - 227.23s | no one else on AWS could claim this name. 227.23s - 230.23s | It will be available only under your account. 230.23s - 235.23s | So, let's set up a view and talk about our first vulnerability on CloudFormation. 235.23s - 238.23s | So, first of all, what is CloudFormation? 238.23s - 242.23s | CloudFormation is an infrastructure as code service by AWS 242.23s - 244.23s | similar to the Terraform project. 244.23s - 249.23s | A user will define a template file that contains AWS resources. 249.23s - 254.23s | Then the user stores this template file locally or in S3 bucket. 254.23s - 259.23s | And then the user will create a stack based on this template file. 259.23s - 262.23s | And when the user will deploy this stack, 262.23s - 265.23s | the CloudFormation service deploys the resources 265.23s - 268.23s | that exist under this template file. 268.23s - 271.23s | Now, I want us to understand what happens behind the scenes 271.23s - 274.23s | when the user uploads a template file to this service. 274.23s - 281.23s | So, first, the user clicks on the upload template file on the GUI. 281.23s - 287.23s | And we need to remember that every operation on AWS is eventually an API request. 287.23s - 292.23s | So, the create upload bucket


chunk_id: 165_chunk_5
chunk_text:
let's set up a view and talk about our first vulnerability on CloudFormation. 235.23s - 238.23s | So, first of all, what is CloudFormation? 238.23s - 242.23s | CloudFormation is an infrastructure as code service by AWS 242.23s - 244.23s | similar to the Terraform project. 244.23s - 249.23s | A user will define a template file that contains AWS resources. 249.23s - 254.23s | Then the user stores this template file locally or in S3 bucket. 254.23s - 259.23s | And then the user will create a stack based on this template file. 259.23s - 262.23s | And when the user will deploy this stack, 262.23s - 265.23s | the CloudFormation service deploys the resources 265.23s - 268.23s | that exist under this template file. 268.23s - 271.23s | Now, I want us to understand what happens behind the scenes 271.23s - 274.23s | when the user uploads a template file to this service. 274.23s - 281.23s | So, first, the user clicks on the upload template file on the GUI. 281.23s - 287.23s | And we need to remember that every operation on AWS is eventually an API request. 287.23s - 292.23s | So, the create upload bucket API request will be invoked. 292.23s - 296.23s | The CloudFormation service will try to create an S3 bucket. 296.23s - 299.23s | Then it will return the bucket name. 299.23s - 307.23s | And then the put object API request will upload the template file to the CloudFormation service. 307.23s - 310.23s | Then we will have a lot of API requests. 310.23s - 312.23s | But in the end, the user will submit the stack, 312.23s - 317.23s | which will cause the CloudFormation service to deploy all the AWS resources 317.23s - 320.23s | that exist under this template file. 320.23s - 326.23s | Now, I want us to focus on the bucket naming pattern of this S3 bucket. 326.23s - 329.23s | So, it will consist of three different parts. 329.23s - 333.23s | The first one is a prefix, which is a constant string. 333.23s - 335.23s | And it will remain the same. 335.23s - 338.23s | In this case, it is CF template. 338.23s - 343.23s | Then we have the hash, which is a unique identifier per account. 343.23s - 350.23s | And then a region, which will be related to where


chunk_id: 165_chunk_6
chunk_text:
API request will be invoked. 292.23s - 296.23s | The CloudFormation service will try to create an S3 bucket. 296.23s - 299.23s | Then it will return the bucket name. 299.23s - 307.23s | And then the put object API request will upload the template file to the CloudFormation service. 307.23s - 310.23s | Then we will have a lot of API requests. 310.23s - 312.23s | But in the end, the user will submit the stack, 312.23s - 317.23s | which will cause the CloudFormation service to deploy all the AWS resources 317.23s - 320.23s | that exist under this template file. 320.23s - 326.23s | Now, I want us to focus on the bucket naming pattern of this S3 bucket. 326.23s - 329.23s | So, it will consist of three different parts. 329.23s - 333.23s | The first one is a prefix, which is a constant string. 333.23s - 335.23s | And it will remain the same. 335.23s - 338.23s | In this case, it is CF template. 338.23s - 343.23s | Then we have the hash, which is a unique identifier per account. 343.23s - 350.23s | And then a region, which will be related to where the user initiates the CloudFormation service. 350.23s - 352.23s | So, now let's visualize this. 352.23s - 357.23s | So, basically, when a user uses the CloudFormation service via the AWS GUI, 357.23s - 362.23s | AWS behind the scenes creates an S3 bucket with this pattern. 362.23s - 368.23s | And when the user will try to create another CloudFormation service in a new region for the first time, 368.23s - 372.23s | the CloudFormation service creates an S3 bucket with the same prefix, 372.23s - 376.23s | with the same hash, but with a different region. 376.23s - 381.23s | So, we have here a semi-predictable bucket name. 381.23s - 388.23s | So, what if an attacker opens or claims this bucket before the user? 388.23s - 395.23s | So, if an attacker does so, this technique is called bucket namesquatting or bucket sniping. 395.23s - 399.23s | You can read a great blog by Oren McKay about this technique. 399.23s - 401.23s | Now, let's explain this. 401.23s - 405.23s | So, we have here the user with the CloudFormation service on a specific region. 405.23s - 409.23s | And then an attacker on a new region.


chunk_id: 165_chunk_7
chunk_text:
the user initiates the CloudFormation service. 350.23s - 352.23s | So, now let's visualize this. 352.23s - 357.23s | So, basically, when a user uses the CloudFormation service via the AWS GUI, 357.23s - 362.23s | AWS behind the scenes creates an S3 bucket with this pattern. 362.23s - 368.23s | And when the user will try to create another CloudFormation service in a new region for the first time, 368.23s - 372.23s | the CloudFormation service creates an S3 bucket with the same prefix, 372.23s - 376.23s | with the same hash, but with a different region. 376.23s - 381.23s | So, we have here a semi-predictable bucket name. 381.23s - 388.23s | So, what if an attacker opens or claims this bucket before the user? 388.23s - 395.23s | So, if an attacker does so, this technique is called bucket namesquatting or bucket sniping. 395.23s - 399.23s | You can read a great blog by Oren McKay about this technique. 399.23s - 401.23s | Now, let's explain this. 401.23s - 405.23s | So, we have here the user with the CloudFormation service on a specific region. 405.23s - 409.23s | And then an attacker on a new region. 409.23s - 415.23s | And what attacker did here is that he creates a bucket under his account with the hash of the user. 415.23s - 418.23s | We will talk about this later, the prefix and the region. 418.23s - 425.23s | So, whenever the user will try to use the CloudFormation service in this region for the first time, 425.23s - 430.23s | the CloudFormation service will try to interact with the attacker-claimed bucket. 430.23s - 433.23s | But it will receive an error. 433.23s - 439.23s | So, basically, we have here a way to prevent the other user from using the CloudFormation service 439.23s - 446.23s | on a specific region, which can be considered as a DOS scenario. 446.23s - 451.23s | And a DOS scenario is fine, but it isn't enough for a DEF concession. 451.23s - 454.23s | So, let's escalate it. 454.23s - 458.23s | What if an attacker opened a bucket for public access? 458.23s - 463.58s | So, the reason why the CloudFormation service got an error before 463.58s - 468.58s | is because the attacker needs still to define some settings on their S3 bucket. 468.58s - 474.58s |


chunk_id: 165_chunk_8
chunk_text:
409.23s - 415.23s | And what attacker did here is that he creates a bucket under his account with the hash of the user. 415.23s - 418.23s | We will talk about this later, the prefix and the region. 418.23s - 425.23s | So, whenever the user will try to use the CloudFormation service in this region for the first time, 425.23s - 430.23s | the CloudFormation service will try to interact with the attacker-claimed bucket. 430.23s - 433.23s | But it will receive an error. 433.23s - 439.23s | So, basically, we have here a way to prevent the other user from using the CloudFormation service 439.23s - 446.23s | on a specific region, which can be considered as a DOS scenario. 446.23s - 451.23s | And a DOS scenario is fine, but it isn't enough for a DEF concession. 451.23s - 454.23s | So, let's escalate it. 454.23s - 458.23s | What if an attacker opened a bucket for public access? 458.23s - 463.58s | So, the reason why the CloudFormation service got an error before 463.58s - 468.58s | is because the attacker needs still to define some settings on their S3 bucket. 468.58s - 474.58s | First of all, the attacker needs to allow public access because it's blocked by default. 474.58s - 483.58s | And then, in order to allow cross-account access, the attacker needs to define a resource-based policy. 483.58s - 489.58s | In this case, we have a very permissive bucket policy that allows any principal on AWS 489.58s - 493.58s | to perform any action on the S3 bucket of the attacker. 493.58s - 497.58s | Of course, this is just a POC, and this is very dangerous. 497.58s - 502.58s | So, after the attacker does so, now an interesting thing will happen. 502.58s - 508.58s | The CloudFormation service of the victim will succeed to interact with the attacker-claimed bucket. 508.58s - 514.58s | So, whenever the user uploads a template file, it will be dropped to the attacker S3 bucket. 514.58s - 521.58s | So, we have here a way to enumerate different secrets and resources that the user wrote in their template file. 521.58s - 527.40s | So, this is an information disclosure scenario. 527.40s - 535.40s | But, if an attacker already has access to this template file, what if an attacker modifies it? 535.40s - 541.40s


chunk_id: 165_chunk_9
chunk_text:
First of all, the attacker needs to allow public access because it's blocked by default. 474.58s - 483.58s | And then, in order to allow cross-account access, the attacker needs to define a resource-based policy. 483.58s - 489.58s | In this case, we have a very permissive bucket policy that allows any principal on AWS 489.58s - 493.58s | to perform any action on the S3 bucket of the attacker. 493.58s - 497.58s | Of course, this is just a POC, and this is very dangerous. 497.58s - 502.58s | So, after the attacker does so, now an interesting thing will happen. 502.58s - 508.58s | The CloudFormation service of the victim will succeed to interact with the attacker-claimed bucket. 508.58s - 514.58s | So, whenever the user uploads a template file, it will be dropped to the attacker S3 bucket. 514.58s - 521.58s | So, we have here a way to enumerate different secrets and resources that the user wrote in their template file. 521.58s - 527.40s | So, this is an information disclosure scenario. 527.40s - 535.40s | But, if an attacker already has access to this template file, what if an attacker modifies it? 535.40s - 541.40s | So, if an attacker does so, this is called resource injection in CloudFormation templates, 541.40s - 549.40s | and it's a great technique that's published already by RhinoLab and also credited to Matthew Filler about this. 549.40s - 557.40s | And all the idea behind this technique is some type of check, type of issue behavior that the CloudFormation service has by default 557.40s - 565.40s | that allow an attacker a window of opportunity to modify a template's file before the CloudFormation service tries to deploy them. 565.40s - 571.40s | So, it's possible for an attacker to modify this template file and actually do it manually 571.40s - 575.40s | or with Lambda that will backdoor this template automatically. 575.40s - 577.40s | So, now let's visualize this. 577.40s - 581.71s | Here we have the user and the attacker account. 581.71s - 585.71s | The attacker is in external account, and the attacker creates an S3 bucket 585.71s - 588.71s | that the CloudFormation service of the victim will try to use. 588.71s - 593.71s | And a Lambda that will backdoor any file that dropped to this S3 bucket. 593.71s - 602.71s | So, whenever


chunk_id: 165_chunk_10
chunk_text:
| So, if an attacker does so, this is called resource injection in CloudFormation templates, 541.40s - 549.40s | and it's a great technique that's published already by RhinoLab and also credited to Matthew Filler about this. 549.40s - 557.40s | And all the idea behind this technique is some type of check, type of issue behavior that the CloudFormation service has by default 557.40s - 565.40s | that allow an attacker a window of opportunity to modify a template's file before the CloudFormation service tries to deploy them. 565.40s - 571.40s | So, it's possible for an attacker to modify this template file and actually do it manually 571.40s - 575.40s | or with Lambda that will backdoor this template automatically. 575.40s - 577.40s | So, now let's visualize this. 577.40s - 581.71s | Here we have the user and the attacker account. 581.71s - 585.71s | The attacker is in external account, and the attacker creates an S3 bucket 585.71s - 588.71s | that the CloudFormation service of the victim will try to use. 588.71s - 593.71s | And a Lambda that will backdoor any file that dropped to this S3 bucket. 593.71s - 602.71s | So, whenever the user creates a stack, the CloudFormation service uploads the victim template to the attacker S3 bucket. 602.71s - 611.71s | Then the Lambda will be triggered and gets the template file from the attacker claim bucket. 611.71s - 614.71s | Then the Lambda will perform a resource injection. 614.71s - 617.71s | And here we have a new resource. 617.71s - 621.71s | It's an admin role that can be assumed by the attacker. 621.71s - 628.71s | Then the Lambda will inject this backdoor template file to the S3 bucket. 628.71s - 632.71s | And as I said before, we have here some type of check, type of use issue. 632.71s - 636.71s | So, the user needs to deploy the template file. 636.71s - 638.71s | So, the user clicks on the submit stack. 638.71s - 646.71s | And then the previously vulnerable CloudFormation service will attempt to get the backdoor template file from the attacker S3 bucket. 646.71s - 650.71s | And deploy this malicious role under the victim account. 650.71s - 655.71s | So, we have here an admin role from external accounts that the attacker can claim. 655.71s - 659.71s | So, actually, which


chunk_id: 165_chunk_11
chunk_text:
the user creates a stack, the CloudFormation service uploads the victim template to the attacker S3 bucket. 602.71s - 611.71s | Then the Lambda will be triggered and gets the template file from the attacker claim bucket. 611.71s - 614.71s | Then the Lambda will perform a resource injection. 614.71s - 617.71s | And here we have a new resource. 617.71s - 621.71s | It's an admin role that can be assumed by the attacker. 621.71s - 628.71s | Then the Lambda will inject this backdoor template file to the S3 bucket. 628.71s - 632.71s | And as I said before, we have here some type of check, type of use issue. 632.71s - 636.71s | So, the user needs to deploy the template file. 636.71s - 638.71s | So, the user clicks on the submit stack. 638.71s - 646.71s | And then the previously vulnerable CloudFormation service will attempt to get the backdoor template file from the attacker S3 bucket. 646.71s - 650.71s | And deploy this malicious role under the victim account. 650.71s - 655.71s | So, we have here an admin role from external accounts that the attacker can claim. 655.71s - 659.71s | So, actually, which means an account takeover. 659.71s - 666.48s | Thank you. 666.48s - 670.48s | But there are some important points to mention. 670.48s - 676.48s | In order to add or inject an admin role to another account, the initiator of the CloudFormation service, 676.48s - 683.48s | which is an AWS user or a service role, needs to have some high privilege. 683.48s - 689.48s | And we can assume that users that use the CloudFormation service via the GUI have such privilege. 689.48s - 696.48s | And even if they do not have high privilege, it's still possible to modify what exists in the template file. 696.48s - 704.48s | And, of course, the attacker needs to wait for the victim to use the CloudFormation service in a new region for the first time. 704.48s - 708.48s | So, now, let's see a really quick POC of this. 708.48s - 714.48s | Here we have the victim account that tried to use the CloudFormation service via the GUI and upload the template file. 714.48s - 719.48s | Behind the scenes, the template file already dropped to the attacker claim bucket. 719.48s - 723.48s | And the user still


chunk_id: 165_chunk_12
chunk_text:
means an account takeover. 659.71s - 666.48s | Thank you. 666.48s - 670.48s | But there are some important points to mention. 670.48s - 676.48s | In order to add or inject an admin role to another account, the initiator of the CloudFormation service, 676.48s - 683.48s | which is an AWS user or a service role, needs to have some high privilege. 683.48s - 689.48s | And we can assume that users that use the CloudFormation service via the GUI have such privilege. 689.48s - 696.48s | And even if they do not have high privilege, it's still possible to modify what exists in the template file. 696.48s - 704.48s | And, of course, the attacker needs to wait for the victim to use the CloudFormation service in a new region for the first time. 704.48s - 708.48s | So, now, let's see a really quick POC of this. 708.48s - 714.48s | Here we have the victim account that tried to use the CloudFormation service via the GUI and upload the template file. 714.48s - 719.48s | Behind the scenes, the template file already dropped to the attacker claim bucket. 719.48s - 723.48s | And the user still needs to define stack name, privilege, and more. 723.48s - 726.48s | And this is what caused the time-of-check, time-of-use issue. 726.48s - 731.48s | As we can see here, we have the attacker as the bucket with the template file of the user. 731.48s - 733.48s | And the attacker can modify it. 733.48s - 735.48s | Meanwhile, the attacker deploys the stack. 735.48s - 743.48s | And we can see that we have under this deployment an attacker user, which is a really privileged role, an admin role. 743.48s - 750.48s | And we can see also that this role can be assumed from an external account, in this case the attacker account. 750.48s - 757.48s | So, all attacker needs to do is to assume this role, find the related account ID of the user on the CloudWatch logs, 757.48s - 765.48s | and then the attacker has an admin role on the victim account, which is one of the most severe things that we can receive in the cloud, right? 765.48s - 776.26s | Thank you, Yakir, for showing us such a cool technique. 776.26s - 781.26s | But before we continue, let's not ignore the


chunk_id: 165_chunk_13
chunk_text:
needs to define stack name, privilege, and more. 723.48s - 726.48s | And this is what caused the time-of-check, time-of-use issue. 726.48s - 731.48s | As we can see here, we have the attacker as the bucket with the template file of the user. 731.48s - 733.48s | And the attacker can modify it. 733.48s - 735.48s | Meanwhile, the attacker deploys the stack. 735.48s - 743.48s | And we can see that we have under this deployment an attacker user, which is a really privileged role, an admin role. 743.48s - 750.48s | And we can see also that this role can be assumed from an external account, in this case the attacker account. 750.48s - 757.48s | So, all attacker needs to do is to assume this role, find the related account ID of the user on the CloudWatch logs, 757.48s - 765.48s | and then the attacker has an admin role on the victim account, which is one of the most severe things that we can receive in the cloud, right? 765.48s - 776.26s | Thank you, Yakir, for showing us such a cool technique. 776.26s - 781.26s | But before we continue, let's not ignore the elephant in the room. 782.26s - 791.26s | Yakir showed us previously a way to, sorry. 791.26s - 798.26s | Previously, Yakir showed us a way to, he showed us that the bucket name needs to be predictable. 798.26s - 803.26s | But when we look at the bucket name, it's definitely not predictable, right? 803.26s - 805.26s | It's due to the hash in the middle. 805.26s - 808.26s | So, we knew we had to address this problem. 808.26s - 817.26s | The first attempt that we did was actually trying to enumerate and calculate every possible hash. 817.26s - 823.26s | But we quickly realized it's just not doable to the amount of option that we had. 823.26s - 828.26s | Then we thought maybe we can reverse the hash or something like that. 828.26s - 831.26s | Yakir said that the hash is unique per account. 831.26s - 837.26s | So, maybe it's based on the account ID or other unique identifier in the account. 837.26s - 844.26s | But after many unsuccessful attempts, we left that technique. 844.26s - 848.26s | Then we decided to turn to open source. 848.26s - 852.26s | In open


chunk_id: 165_chunk_14
chunk_text:
elephant in the room. 782.26s - 791.26s | Yakir showed us previously a way to, sorry. 791.26s - 798.26s | Previously, Yakir showed us a way to, he showed us that the bucket name needs to be predictable. 798.26s - 803.26s | But when we look at the bucket name, it's definitely not predictable, right? 803.26s - 805.26s | It's due to the hash in the middle. 805.26s - 808.26s | So, we knew we had to address this problem. 808.26s - 817.26s | The first attempt that we did was actually trying to enumerate and calculate every possible hash. 817.26s - 823.26s | But we quickly realized it's just not doable to the amount of option that we had. 823.26s - 828.26s | Then we thought maybe we can reverse the hash or something like that. 828.26s - 831.26s | Yakir said that the hash is unique per account. 831.26s - 837.26s | So, maybe it's based on the account ID or other unique identifier in the account. 837.26s - 844.26s | But after many unsuccessful attempts, we left that technique. 844.26s - 848.26s | Then we decided to turn to open source. 848.26s - 852.26s | In open source, we saw this code. 852.26s - 856.26s | And in this code, we saw that there is some cases. 856.26s - 860.26s | There is a code that shows that the bucket is actually randomized. 860.26s - 862.26s | The hash is actually randomized. 862.26s - 871.41s | And what that actually means is we can't predict the hash. 871.41s - 877.41s | So, our technique is not going to work in the real world. 877.41s - 885.41s | But as good researchers, we were sad about this. 885.41s - 888.41s | Because we know that our technique is not going to work. 888.41s - 893.41s | And we had to rethink about everything that we came so far. 893.41s - 895.41s | We have a really nice technique. 895.41s - 899.41s | We managed to remote account takeover. 899.41s - 903.41s | But we don't have how to use it in the real world. 903.41s - 908.41s | But as good researchers, we thought about a solution. 908.41s - 914.41s | We used the greatest tool known to us, which is the search tool. 914.41s - 916.41s | We used GitHub search. 916.41s - 919.41s | And we


chunk_id: 165_chunk_15
chunk_text:
source, we saw this code. 852.26s - 856.26s | And in this code, we saw that there is some cases. 856.26s - 860.26s | There is a code that shows that the bucket is actually randomized. 860.26s - 862.26s | The hash is actually randomized. 862.26s - 871.41s | And what that actually means is we can't predict the hash. 871.41s - 877.41s | So, our technique is not going to work in the real world. 877.41s - 885.41s | But as good researchers, we were sad about this. 885.41s - 888.41s | Because we know that our technique is not going to work. 888.41s - 893.41s | And we had to rethink about everything that we came so far. 893.41s - 895.41s | We have a really nice technique. 895.41s - 899.41s | We managed to remote account takeover. 899.41s - 903.41s | But we don't have how to use it in the real world. 903.41s - 908.41s | But as good researchers, we thought about a solution. 908.41s - 914.41s | We used the greatest tool known to us, which is the search tool. 914.41s - 916.41s | We used GitHub search. 916.41s - 919.41s | And we used source graph search. 919.41s - 923.41s | We managed to find over a thousand buckets. 923.41s - 926.41s | Some of them with the hash that we mentioned. 926.41s - 928.41s | All of them with the hash that we mentioned. 928.41s - 935.41s | And it gave us the ability to hack a couple of big organizations. 935.41s - 937.41s | But we didn't stop there. 937.41s - 946.41s | During our searches, we actually find that there is cases where the bucket name of some services 946.41s - 950.41s | is actually created by just using account ID. 950.41s - 959.41s | So, we thought to ourselves, maybe instead of trying to find a mysterious hash 959.41s - 962.41s | or trying to understand this randomized string, 962.41s - 969.41s | maybe we can just use the account ID instead and find new vulnerability 969.41s - 973.41s | that the bucket name actually contains the account ID. 973.41s - 982.82s | So, we decided to shift our whole research and turn to find more bucket patterns. 982.82s - 987.82s | We used the open source and looked for more bucket patterns. 987.82s - 990.82s | We used


chunk_id: 165_chunk_16
chunk_text:
used source graph search. 919.41s - 923.41s | We managed to find over a thousand buckets. 923.41s - 926.41s | Some of them with the hash that we mentioned. 926.41s - 928.41s | All of them with the hash that we mentioned. 928.41s - 935.41s | And it gave us the ability to hack a couple of big organizations. 935.41s - 937.41s | But we didn't stop there. 937.41s - 946.41s | During our searches, we actually find that there is cases where the bucket name of some services 946.41s - 950.41s | is actually created by just using account ID. 950.41s - 959.41s | So, we thought to ourselves, maybe instead of trying to find a mysterious hash 959.41s - 962.41s | or trying to understand this randomized string, 962.41s - 969.41s | maybe we can just use the account ID instead and find new vulnerability 969.41s - 973.41s | that the bucket name actually contains the account ID. 973.41s - 982.82s | So, we decided to shift our whole research and turn to find more bucket patterns. 982.82s - 987.82s | We used the open source and looked for more bucket patterns. 987.82s - 990.82s | We used AWS documentation and SDK. 990.82s - 996.82s | We even started calling and trying to press nearly every possible button in AWS GUI. 996.82s - 1004.82s | And we even created a tool, an open source tool that you can all play with it after this talk. 1004.82s - 1011.82s | It lets you debug AWS like you're debugging network buckets. 1011.82s - 1018.82s | And it shows the inner API calls made by AWS, which is kind of nice. 1018.82s - 1020.82s | So, let's see how it works. 1020.82s - 1024.82s | In one screen, we initiate an API call. 1024.82s - 1032.82s | This API call in this scenario is the upload template that Kir talked about before. 1032.82s - 1037.82s | In the other screen, we use Wireshark with our plugin. 1037.82s - 1039.82s | We wrote a plugin for Wireshark. 1039.82s - 1045.82s | And we're just starting to capture API calls that we made. 1045.82s - 1050.82s | And what is interesting about what we've seen using this tool 1050.82s - 1055.82s | is actually when we initiate the API call in the GUI, it's actually one API call. 1055.82s - 1059.82s | But


chunk_id: 165_chunk_17
chunk_text:
AWS documentation and SDK. 990.82s - 996.82s | We even started calling and trying to press nearly every possible button in AWS GUI. 996.82s - 1004.82s | And we even created a tool, an open source tool that you can all play with it after this talk. 1004.82s - 1011.82s | It lets you debug AWS like you're debugging network buckets. 1011.82s - 1018.82s | And it shows the inner API calls made by AWS, which is kind of nice. 1018.82s - 1020.82s | So, let's see how it works. 1020.82s - 1024.82s | In one screen, we initiate an API call. 1024.82s - 1032.82s | This API call in this scenario is the upload template that Kir talked about before. 1032.82s - 1037.82s | In the other screen, we use Wireshark with our plugin. 1037.82s - 1039.82s | We wrote a plugin for Wireshark. 1039.82s - 1045.82s | And we're just starting to capture API calls that we made. 1045.82s - 1050.82s | And what is interesting about what we've seen using this tool 1050.82s - 1055.82s | is actually when we initiate the API call in the GUI, it's actually one API call. 1055.82s - 1059.82s | But this API call is undocumented. 1059.82s - 1068.82s | And the equivalent to that API call is actually five different API calls made by the inner services of AWS. 1068.82s - 1071.82s | One of them is the create bucket that Kir told you before. 1071.82s - 1073.82s | And it also calculates the hash. 1073.82s - 1077.82s | So, we have here an undocumented API call used by AWS to create buckets. 1078.82s - 1085.82s | So, all of the techniques that I mentioned before gave us around hundreds of buckets. 1085.82s - 1089.82s | And we understand that we have tons of work to do. 1089.82s - 1095.82s | Because, as a reminder, some of the buckets came from open source projects. 1095.82s - 1099.82s | So, we need to understand which bucket is related to what service. 1099.82s - 1104.82s | And we also need to understand if any of these services is exploitable. 1105.82s - 1110.82s | So, you're probably wondering what is the answer for those questions. 1110.82s - 1117.82s | And the answer was, we managed to find five different vulnerabilities within AWS. 1117.82s - 1120.82s | Some of them by just using the


chunk_id: 165_chunk_18
chunk_text:
this API call is undocumented. 1059.82s - 1068.82s | And the equivalent to that API call is actually five different API calls made by the inner services of AWS. 1068.82s - 1071.82s | One of them is the create bucket that Kir told you before. 1071.82s - 1073.82s | And it also calculates the hash. 1073.82s - 1077.82s | So, we have here an undocumented API call used by AWS to create buckets. 1078.82s - 1085.82s | So, all of the techniques that I mentioned before gave us around hundreds of buckets. 1085.82s - 1089.82s | And we understand that we have tons of work to do. 1089.82s - 1095.82s | Because, as a reminder, some of the buckets came from open source projects. 1095.82s - 1099.82s | So, we need to understand which bucket is related to what service. 1099.82s - 1104.82s | And we also need to understand if any of these services is exploitable. 1105.82s - 1110.82s | So, you're probably wondering what is the answer for those questions. 1110.82s - 1117.82s | And the answer was, we managed to find five different vulnerabilities within AWS. 1117.82s - 1120.82s | Some of them by just using the account ID. 1120.82s - 1131.51s | So, let's talk about the common steps that we need to take that is common to all the vulnerabilities that we found. 1131.51s - 1135.51s | As Kir said before, we need to create a bucket name before the user. 1135.51s - 1137.51s | We also need to open the bucket to the world. 1137.51s - 1142.51s | And we need to put lambda or something to monitor the bucket. 1142.51s - 1145.51s | And when a file is dropped to the bucket, we can change it. 1145.51s - 1147.51s | It's the same technique. 1147.51s - 1152.95s | So, let's explore our second vulnerability for today in AWS Glue. 1152.95s - 1161.95s | This one is really strong because you only need the account ID to exploit a remote account. 1162.95s - 1167.95s | And just a reminder, account ID is not a secret by AWS, right? 1167.95s - 1171.95s | So, what is AWS Glue? 1171.95s - 1175.95s | AWS Glue is a service for data engineers. 1175.95s - 1178.95s | It is basically used for data manipulation. 1178.95s - 1183.95s | To trigger the vulnerability, the user needs to create a


chunk_id: 165_chunk_19
chunk_text:
account ID. 1120.82s - 1131.51s | So, let's talk about the common steps that we need to take that is common to all the vulnerabilities that we found. 1131.51s - 1135.51s | As Kir said before, we need to create a bucket name before the user. 1135.51s - 1137.51s | We also need to open the bucket to the world. 1137.51s - 1142.51s | And we need to put lambda or something to monitor the bucket. 1142.51s - 1145.51s | And when a file is dropped to the bucket, we can change it. 1145.51s - 1147.51s | It's the same technique. 1147.51s - 1152.95s | So, let's explore our second vulnerability for today in AWS Glue. 1152.95s - 1161.95s | This one is really strong because you only need the account ID to exploit a remote account. 1162.95s - 1167.95s | And just a reminder, account ID is not a secret by AWS, right? 1167.95s - 1171.95s | So, what is AWS Glue? 1171.95s - 1175.95s | AWS Glue is a service for data engineers. 1175.95s - 1178.95s | It is basically used for data manipulation. 1178.95s - 1183.95s | To trigger the vulnerability, the user needs to create a job in Glue. 1183.95s - 1188.95s | When you do so, a bucket is automatically configured with a predictable name. 1188.95s - 1191.95s | There, files of Glue will be stored. 1191.95s - 1197.95s | So, if a bucket is predictable, we can take it before the user. 1197.95s - 1200.95s | And that's exactly what we did. 1200.95s - 1202.95s | Our user creates a job. 1202.95s - 1206.95s | When he creates a job, a script is dropped to our bucket. 1206.95s - 1209.95s | We have our lambda that changes the file. 1209.95s - 1214.95s | And when the user runs the job, he gets the modified script. 1215.95s - 1220.95s | And voila, we have a remote code execution on the remote account. 1220.95s - 1231.66s | So, you are probably wondering, what are the privileges of the AWS Glue service? 1231.66s - 1238.66s | So, it's actually configured by the user that triggers the job. 1238.66s - 1247.66s | Most of the time, it will be a default service role that you get when you use AWS Glue for the first time. 1247.66s - 1250.66s | And that role is pretty interesting. 1250.66s - 1255.66s


chunk_id: 165_chunk_20
chunk_text:
job in Glue. 1183.95s - 1188.95s | When you do so, a bucket is automatically configured with a predictable name. 1188.95s - 1191.95s | There, files of Glue will be stored. 1191.95s - 1197.95s | So, if a bucket is predictable, we can take it before the user. 1197.95s - 1200.95s | And that's exactly what we did. 1200.95s - 1202.95s | Our user creates a job. 1202.95s - 1206.95s | When he creates a job, a script is dropped to our bucket. 1206.95s - 1209.95s | We have our lambda that changes the file. 1209.95s - 1214.95s | And when the user runs the job, he gets the modified script. 1215.95s - 1220.95s | And voila, we have a remote code execution on the remote account. 1220.95s - 1231.66s | So, you are probably wondering, what are the privileges of the AWS Glue service? 1231.66s - 1238.66s | So, it's actually configured by the user that triggers the job. 1238.66s - 1247.66s | Most of the time, it will be a default service role that you get when you use AWS Glue for the first time. 1247.66s - 1250.66s | And that role is pretty interesting. 1250.66s - 1255.66s | Because it has a lot of enumeration potential on the account. 1255.66s - 1258.66s | And also, it has some write potential in the account. 1258.66s - 1263.66s | So, as a red teamer, you could probably escalate from here. 1263.66s - 1266.66s | But it's not the topic for our talk. 1266.66s - 1271.66s | Another cool anecdote about this vulnerability is actually invisible. 1271.66s - 1273.66s | And I will explain. 1274.66s - 1281.66s | When the user tries to get the script and look at the script, he actually gets the original script. 1281.66s - 1284.66s | Even though it's already modified. 1284.66s - 1288.66s | And when he runs it, he actually runs the modified script. 1288.66s - 1291.66s | This is just due to a bug in the AWS Glue. 1291.66s - 1293.66s | But it's still cool. 1293.66s - 1296.66s | So, let's see the full POC. 1296.66s - 1298.66s | We recorded that in February. 1298.66s - 1303.66s | Here you can see a user creating a Glue job. 1303.66s - 1310.66s | When you press the save button, the files are dropped to the attacker bucket. 1310.66s - 1315.66s | And


chunk_id: 165_chunk_21
chunk_text:
| Because it has a lot of enumeration potential on the account. 1255.66s - 1258.66s | And also, it has some write potential in the account. 1258.66s - 1263.66s | So, as a red teamer, you could probably escalate from here. 1263.66s - 1266.66s | But it's not the topic for our talk. 1266.66s - 1271.66s | Another cool anecdote about this vulnerability is actually invisible. 1271.66s - 1273.66s | And I will explain. 1274.66s - 1281.66s | When the user tries to get the script and look at the script, he actually gets the original script. 1281.66s - 1284.66s | Even though it's already modified. 1284.66s - 1288.66s | And when he runs it, he actually runs the modified script. 1288.66s - 1291.66s | This is just due to a bug in the AWS Glue. 1291.66s - 1293.66s | But it's still cool. 1293.66s - 1296.66s | So, let's see the full POC. 1296.66s - 1298.66s | We recorded that in February. 1298.66s - 1303.66s | Here you can see a user creating a Glue job. 1303.66s - 1310.66s | When you press the save button, the files are dropped to the attacker bucket. 1310.66s - 1315.66s | And that's what also gives us the time to modify the script. 1315.66s - 1323.66s | Because if we are automating this, the Lambda takes just a couple of milliseconds to inject the code there. 1323.66s - 1330.66s | In this POC, we just put a print for POC purposes. 1330.66s - 1336.66s | And as you can see, when the user tries to get the script, he gets the original script. 1336.66s - 1348.48s | And when he runs the script, if we look at the logs, you can see that the script is actually modified. 1348.48s - 1356.60s | And we got remote code execution. 1356.60s - 1361.60s | So, now let's explore the third vulnerability for today. 1361.60s - 1366.60s | In EMR, which is another service of AWS. 1366.60s - 1372.60s | This one is also kind of cool because, again, it's only the account ID. 1372.60s - 1374.60s | That's what we were looking for. 1374.60s - 1380.60s | And it has a cool post-exploitation technique. 1380.60s - 1386.60s | So, EMR, it's a service for data consumption used by data scientists. 1386.60s - 1388.60s | Another data service. 1388.60s - 1393.60s | To trigger the


chunk_id: 165_chunk_22
chunk_text:
that's what also gives us the time to modify the script. 1315.66s - 1323.66s | Because if we are automating this, the Lambda takes just a couple of milliseconds to inject the code there. 1323.66s - 1330.66s | In this POC, we just put a print for POC purposes. 1330.66s - 1336.66s | And as you can see, when the user tries to get the script, he gets the original script. 1336.66s - 1348.48s | And when he runs the script, if we look at the logs, you can see that the script is actually modified. 1348.48s - 1356.60s | And we got remote code execution. 1356.60s - 1361.60s | So, now let's explore the third vulnerability for today. 1361.60s - 1366.60s | In EMR, which is another service of AWS. 1366.60s - 1372.60s | This one is also kind of cool because, again, it's only the account ID. 1372.60s - 1374.60s | That's what we were looking for. 1374.60s - 1380.60s | And it has a cool post-exploitation technique. 1380.60s - 1386.60s | So, EMR, it's a service for data consumption used by data scientists. 1386.60s - 1388.60s | Another data service. 1388.60s - 1393.60s | To trigger the vulnerability, the user needs to create a studio. 1393.60s - 1397.60s | And when you do so, a bucket is automatically configured. 1397.60s - 1399.60s | And that's where we come to the picture. 1399.60s - 1402.60s | Again, we open the bucket before the user. 1402.60s - 1408.60s | When the user creates a studio, he actually stores Jupyter notebooks to our bucket. 1408.60s - 1412.60s | In our bucket, we have our Lambda that changes the code. 1412.60s - 1417.60s | And in Jupyter notebook, you can inject JavaScript. 1417.60s - 1420.60s | So, we decided to inject JavaScript here. 1420.60s - 1423.60s | And it acts like stored XSS. 1423.60s - 1432.60s | When the user tries to open his EMR, his service, he gets the modified Jupyter notebook. 1432.60s - 1439.60s | And every time he will go to the notebook, he will be redirected to a fake login page created by us. 1439.60s - 1444.87s | A quick disclaimer about this vulnerability. 1444.87s - 1446.87s | It's not a zero shot. 1446.87s - 1454.87s | It means that the vulnerability, when the user configures the page, he actually needs to do some changes. 1454.87s -


chunk_id: 165_chunk_23
chunk_text:
vulnerability, the user needs to create a studio. 1393.60s - 1397.60s | And when you do so, a bucket is automatically configured. 1397.60s - 1399.60s | And that's where we come to the picture. 1399.60s - 1402.60s | Again, we open the bucket before the user. 1402.60s - 1408.60s | When the user creates a studio, he actually stores Jupyter notebooks to our bucket. 1408.60s - 1412.60s | In our bucket, we have our Lambda that changes the code. 1412.60s - 1417.60s | And in Jupyter notebook, you can inject JavaScript. 1417.60s - 1420.60s | So, we decided to inject JavaScript here. 1420.60s - 1423.60s | And it acts like stored XSS. 1423.60s - 1432.60s | When the user tries to open his EMR, his service, he gets the modified Jupyter notebook. 1432.60s - 1439.60s | And every time he will go to the notebook, he will be redirected to a fake login page created by us. 1439.60s - 1444.87s | A quick disclaimer about this vulnerability. 1444.87s - 1446.87s | It's not a zero shot. 1446.87s - 1454.87s | It means that the vulnerability, when the user configures the page, he actually needs to do some changes. 1454.87s - 1456.87s | Because he gets an error. 1456.87s - 1458.87s | But the error is really vague. 1458.87s - 1463.87s | And when I see an error like this as a user, I do one of two things. 1463.87s - 1466.87s | Either I change the role. 1466.87s - 1470.87s | Or I use the policy that is recommended by AWS. 1470.87s - 1474.87s | In both cases, the vulnerability is going to work. 1474.87s - 1478.87s | This is due to inconsistent in AWS. 1478.87s - 1487.87s | The policy that they recommend is actually lacking a string condition that is supposed to protect you from such an attack. 1487.87s - 1489.87s | But they forgot it. 1489.87s - 1493.87s | Now Michael will show you a couple of more vulnerabilities. 1493.87s - 1498.87s | And we'll show you how our technique applies on open source projects. 1498.87s - 1505.95s | Thank you. 1505.95s - 1506.95s | All right. 1506.95s - 1508.95s | So, thank you, Ofek. 1508.95s - 1511.95s | So nowadays, everyone loves AI and machine learning. 1511.95s - 1514.95s | And we could not miss a chance to talk about this on our lecture. 1514.95s -


chunk_id: 165_chunk_24
chunk_text:
1456.87s | Because he gets an error. 1456.87s - 1458.87s | But the error is really vague. 1458.87s - 1463.87s | And when I see an error like this as a user, I do one of two things. 1463.87s - 1466.87s | Either I change the role. 1466.87s - 1470.87s | Or I use the policy that is recommended by AWS. 1470.87s - 1474.87s | In both cases, the vulnerability is going to work. 1474.87s - 1478.87s | This is due to inconsistent in AWS. 1478.87s - 1487.87s | The policy that they recommend is actually lacking a string condition that is supposed to protect you from such an attack. 1487.87s - 1489.87s | But they forgot it. 1489.87s - 1493.87s | Now Michael will show you a couple of more vulnerabilities. 1493.87s - 1498.87s | And we'll show you how our technique applies on open source projects. 1498.87s - 1505.95s | Thank you. 1505.95s - 1506.95s | All right. 1506.95s - 1508.95s | So, thank you, Ofek. 1508.95s - 1511.95s | So nowadays, everyone loves AI and machine learning. 1511.95s - 1514.95s | And we could not miss a chance to talk about this on our lecture. 1514.95s - 1519.95s | Let's discuss the rest of the vulnerabilities and start from AWS SageMaker. 1519.95s - 1526.95s | So SageMaker is a tool in AWS that is designed to build, train, and deploy machine learning models. 1526.95s - 1530.95s | Canvas is part of the AWS SageMaker ecosystem. 1530.95s - 1534.95s | And it's a very cool no code drag and drop interface. 1534.95s - 1541.95s | We discovered that when a user creates a Canvas instance for the first time on a specific region, 1541.95s - 1546.95s | then a bucket with the name SageMaker dash region dash account ID is created. 1547.95s - 1552.95s | And the S3 bucket will store files that are utilized by the service. 1552.95s - 1555.95s | So let's go over the full attack scenario. 1555.95s - 1558.95s | So the attacker has claimed the bucket before the user. 1558.95s - 1561.95s | And then the user opens Canvas. 1561.95s - 1564.95s | And it will create a data set and uploads the files. 1564.95s - 1569.95s | On the background, the files will be uploaded to the attacker control S3 bucket. 1569.95s - 1571.95s | And then the attacker could get the


chunk_id: 165_chunk_25
chunk_text:
1519.95s | Let's discuss the rest of the vulnerabilities and start from AWS SageMaker. 1519.95s - 1526.95s | So SageMaker is a tool in AWS that is designed to build, train, and deploy machine learning models. 1526.95s - 1530.95s | Canvas is part of the AWS SageMaker ecosystem. 1530.95s - 1534.95s | And it's a very cool no code drag and drop interface. 1534.95s - 1541.95s | We discovered that when a user creates a Canvas instance for the first time on a specific region, 1541.95s - 1546.95s | then a bucket with the name SageMaker dash region dash account ID is created. 1547.95s - 1552.95s | And the S3 bucket will store files that are utilized by the service. 1552.95s - 1555.95s | So let's go over the full attack scenario. 1555.95s - 1558.95s | So the attacker has claimed the bucket before the user. 1558.95s - 1561.95s | And then the user opens Canvas. 1561.95s - 1564.95s | And it will create a data set and uploads the files. 1564.95s - 1569.95s | On the background, the files will be uploaded to the attacker control S3 bucket. 1569.95s - 1571.95s | And then the attacker could get the data set. 1571.95s - 1573.95s | And we will have data leakage. 1573.95s - 1578.95s | But if that's not enough, the attacker could also manipulate the data set. 1578.95s - 1581.95s | And then SageMaker will use the manipulated data set. 1581.95s - 1583.95s | And we have data manipulation. 1583.95s - 1586.95s | So it may lead to inaccurate models. 1586.95s - 1591.95s | And all of this can happen without the user even knowing that something has changed. 1591.95s - 1595.95s | And to our next vulnerability on AWS is on CodeStar. 1595.95s - 1599.95s | So CodeStar is a tool that provides a unified user interface 1599.95s - 1602.95s | to easily manage software development activities. 1602.95s - 1606.95s | So the service was deprecated just, I think, two weeks ago. 1606.95s - 1610.95s | And in this scenario, the attacker has claimed the bucket again before the user. 1610.95s - 1615.95s | And when a user tries to create a CodeStar project on a region, 1615.95s - 1619.95s | then CodeStar on the background will try to create a bucket. 1619.95s - 1623.95s | And it will fail. And it will return the user an


chunk_id: 165_chunk_26
chunk_text:
data set. 1571.95s - 1573.95s | And we will have data leakage. 1573.95s - 1578.95s | But if that's not enough, the attacker could also manipulate the data set. 1578.95s - 1581.95s | And then SageMaker will use the manipulated data set. 1581.95s - 1583.95s | And we have data manipulation. 1583.95s - 1586.95s | So it may lead to inaccurate models. 1586.95s - 1591.95s | And all of this can happen without the user even knowing that something has changed. 1591.95s - 1595.95s | And to our next vulnerability on AWS is on CodeStar. 1595.95s - 1599.95s | So CodeStar is a tool that provides a unified user interface 1599.95s - 1602.95s | to easily manage software development activities. 1602.95s - 1606.95s | So the service was deprecated just, I think, two weeks ago. 1606.95s - 1610.95s | And in this scenario, the attacker has claimed the bucket again before the user. 1610.95s - 1615.95s | And when a user tries to create a CodeStar project on a region, 1615.95s - 1619.95s | then CodeStar on the background will try to create a bucket. 1619.95s - 1623.95s | And it will fail. And it will return the user an error. 1623.95s - 1626.95s | So this is essentially a denial of service attack 1626.95s - 1632.95s | since the attacker prevents the user from using CodeStar on a specific region. 1632.95s - 1635.95s | And there's one more vulnerability on service catalog. 1635.95s - 1637.95s | We won't elaborate about it right now. 1637.95s - 1642.95s | But we're going to publish a blog in the next few hours so you could see it there. 1642.95s - 1649.95s | Okay. So after we talked about the vulnerabilities in AWS, 1649.95s - 1652.95s | on our research we also identified that this attack vector affects 1652.95s - 1655.95s | many open source projects as well apparently. 1655.95s - 1660.95s | And many open source projects create S3 buckets as part of functionality. 1660.95s - 1664.95s | And the consequences change depending on the project. 1664.95s - 1668.95s | But some projects are vulnerable and could allow an attacker 1668.95s - 1671.95s | to gain full access to all of the files in the bucket. 1671.95s - 1677.95s | So here you can see an example of a project that checks if the bucket exists. 1678.95s - 1682.95s | And this


chunk_id: 165_chunk_27
chunk_text:
error. 1623.95s - 1626.95s | So this is essentially a denial of service attack 1626.95s - 1632.95s | since the attacker prevents the user from using CodeStar on a specific region. 1632.95s - 1635.95s | And there's one more vulnerability on service catalog. 1635.95s - 1637.95s | We won't elaborate about it right now. 1637.95s - 1642.95s | But we're going to publish a blog in the next few hours so you could see it there. 1642.95s - 1649.95s | Okay. So after we talked about the vulnerabilities in AWS, 1649.95s - 1652.95s | on our research we also identified that this attack vector affects 1652.95s - 1655.95s | many open source projects as well apparently. 1655.95s - 1660.95s | And many open source projects create S3 buckets as part of functionality. 1660.95s - 1664.95s | And the consequences change depending on the project. 1664.95s - 1668.95s | But some projects are vulnerable and could allow an attacker 1668.95s - 1671.95s | to gain full access to all of the files in the bucket. 1671.95s - 1677.95s | So here you can see an example of a project that checks if the bucket exists. 1678.95s - 1682.95s | And this check is wrong since an attacker could claim the bucket 1682.95s - 1686.95s | and the project will print to the screen that the bucket already exists 1686.95s - 1690.95s | but it will continue running without any problems. 1690.95s - 1695.95s | And there's another example of a project that tries to verify that the bucket exists 1695.95s - 1699.95s | and it tries to list the bucket. But this check is also wrong 1699.95s - 1704.95s | since an attacker could claim the bucket, open it for public access, 1704.95s - 1708.95s | set permissive policy and by doing so it will allow the victim 1708.95s - 1713.95s | to list using the AWS S3 LS command to list the bucket 1713.95s - 1720.39s | and again the script will continue running without any failure. 1720.39s - 1723.39s | And also as part of our investigation we found services 1723.39s - 1726.39s | that could be vulnerable in the past. 1726.39s - 1728.39s | These services created predictable bucket names. 1728.39s - 1733.39s | For instance Athena once created a bucket with the name AWS Athena 1733.39s - 1737.39s | query results dash uh account ID dash region.


chunk_id: 165_chunk_28
chunk_text:
check is wrong since an attacker could claim the bucket 1682.95s - 1686.95s | and the project will print to the screen that the bucket already exists 1686.95s - 1690.95s | but it will continue running without any problems. 1690.95s - 1695.95s | And there's another example of a project that tries to verify that the bucket exists 1695.95s - 1699.95s | and it tries to list the bucket. But this check is also wrong 1699.95s - 1704.95s | since an attacker could claim the bucket, open it for public access, 1704.95s - 1708.95s | set permissive policy and by doing so it will allow the victim 1708.95s - 1713.95s | to list using the AWS S3 LS command to list the bucket 1713.95s - 1720.39s | and again the script will continue running without any failure. 1720.39s - 1723.39s | And also as part of our investigation we found services 1723.39s - 1726.39s | that could be vulnerable in the past. 1726.39s - 1728.39s | These services created predictable bucket names. 1728.39s - 1733.39s | For instance Athena once created a bucket with the name AWS Athena 1733.39s - 1737.39s | query results dash uh account ID dash region. 1737.39s - 1742.39s | This bucket is not created anymore and when we when we encountered it 1742.39s - 1746.39s | Athena did not seem to be vulnerable and now there's this bucket is created 1746.39s - 1751.39s | by the user specification. Alright so we discussed vulnerabilities 1751.39s - 1754.39s | in AWS services and open source projects as well. 1754.39s - 1759.39s | Now let's explore how we can elevate what we've learned so far to the next level. 1760.39s - 1764.39s | So we wanted to increase the chances of a victim to be compromised. 1764.39s - 1768.39s | It would be important to us to show that this attack vector is not just theoretical 1768.39s - 1772.39s | but it's also practical and effective on real world scenarios. 1772.39s - 1775.39s | And we are proud to produce uh to introduce a new technique 1775.39s - 1779.39s | we named bucket monopoly. So in previous vulnerabilities 1779.39s - 1782.39s | we targeted specific regions of other accounts. 1782.39s - 1785.39s | We could check if a bucket already already exists and if not 1785.39s - 1788.39s | we could claim it before the victim. However as


chunk_id: 165_chunk_29
chunk_text:
1737.39s - 1742.39s | This bucket is not created anymore and when we when we encountered it 1742.39s - 1746.39s | Athena did not seem to be vulnerable and now there's this bucket is created 1746.39s - 1751.39s | by the user specification. Alright so we discussed vulnerabilities 1751.39s - 1754.39s | in AWS services and open source projects as well. 1754.39s - 1759.39s | Now let's explore how we can elevate what we've learned so far to the next level. 1760.39s - 1764.39s | So we wanted to increase the chances of a victim to be compromised. 1764.39s - 1768.39s | It would be important to us to show that this attack vector is not just theoretical 1768.39s - 1772.39s | but it's also practical and effective on real world scenarios. 1772.39s - 1775.39s | And we are proud to produce uh to introduce a new technique 1775.39s - 1779.39s | we named bucket monopoly. So in previous vulnerabilities 1779.39s - 1782.39s | we targeted specific regions of other accounts. 1782.39s - 1785.39s | We could check if a bucket already already exists and if not 1785.39s - 1788.39s | we could claim it before the victim. However as you all know 1788.39s - 1792.39s | AWS has multiple regions so instead of focusing on a single region 1792.39s - 1797.39s | we could claim all possible regions that the user has not claimed yet. 1797.39s - 1800.39s | This strategy increases the likelihood of an unsuspecting victim 1800.39s - 1804.39s | interacting with an attacker on S3 bucket. 1804.39s - 1807.39s | But since we have several vulnerable services 1807.39s - 1811.39s | let's create all of the buckets in all of the possible services. 1811.39s - 1815.39s | This is practically a landmine. The victim is surrounded by malicious 1815.39s - 1820.39s | buckets belonging to different services. Whenever the victim will use 1820.39s - 1825.39s | a new service from uh the six services we presented on any new region 1825.39s - 1831.47s | it will be immediately compromised. Let's explain step by step 1831.47s - 1836.47s | how to perform this kind of attack. First of all we must identify 1836.47s - 1840.47s | predictable bucket name. After finding these buckets we need to verify 1840.47s - 1843.47s | that the associated services that create these kinds of buckets 1843.47s - 1848.47s | are indeed


chunk_id: 165_chunk_30
chunk_text:
you all know 1788.39s - 1792.39s | AWS has multiple regions so instead of focusing on a single region 1792.39s - 1797.39s | we could claim all possible regions that the user has not claimed yet. 1797.39s - 1800.39s | This strategy increases the likelihood of an unsuspecting victim 1800.39s - 1804.39s | interacting with an attacker on S3 bucket. 1804.39s - 1807.39s | But since we have several vulnerable services 1807.39s - 1811.39s | let's create all of the buckets in all of the possible services. 1811.39s - 1815.39s | This is practically a landmine. The victim is surrounded by malicious 1815.39s - 1820.39s | buckets belonging to different services. Whenever the victim will use 1820.39s - 1825.39s | a new service from uh the six services we presented on any new region 1825.39s - 1831.47s | it will be immediately compromised. Let's explain step by step 1831.47s - 1836.47s | how to perform this kind of attack. First of all we must identify 1836.47s - 1840.47s | predictable bucket name. After finding these buckets we need to verify 1840.47s - 1843.47s | that the associated services that create these kinds of buckets 1843.47s - 1848.47s | are indeed vulnerable. Secondly we must recognize what is the unique identifier. 1848.47s - 1851.47s | And the last step which is the easy one we need to claim 1851.47s - 1856.47s | all the bucket names across all regions. So we showed you several ways 1856.47s - 1860.47s | how to find these kinds of buckets. We start reconnaissance by looking for 1860.47s - 1864.47s | bucket names that contains a prefix or a postfix alongside 1864.47s - 1869.47s | with an identifier like account ID or a hash. And it could be achieved 1869.47s - 1873.47s | by using the GitHub regex search. We could read AWS documentation as well. 1873.47s - 1877.47s | And we could use, we could crawl AWS services with tools like 1877.47s - 1882.47s | TrailShark that Ofek just showed you before. Next the second step is to understand 1882.47s - 1887.47s | what is the unique identifier inside the bucket name. It might be a random hash 1887.47s - 1892.47s | and it will require further instigation. It could also be account ID or some kind of 1892.47s - 1898.47s | other public metadata information. If it's a hash we could search on GitHub


chunk_id: 165_chunk_31
chunk_text:
vulnerable. Secondly we must recognize what is the unique identifier. 1848.47s - 1851.47s | And the last step which is the easy one we need to claim 1851.47s - 1856.47s | all the bucket names across all regions. So we showed you several ways 1856.47s - 1860.47s | how to find these kinds of buckets. We start reconnaissance by looking for 1860.47s - 1864.47s | bucket names that contains a prefix or a postfix alongside 1864.47s - 1869.47s | with an identifier like account ID or a hash. And it could be achieved 1869.47s - 1873.47s | by using the GitHub regex search. We could read AWS documentation as well. 1873.47s - 1877.47s | And we could use, we could crawl AWS services with tools like 1877.47s - 1882.47s | TrailShark that Ofek just showed you before. Next the second step is to understand 1882.47s - 1887.47s | what is the unique identifier inside the bucket name. It might be a random hash 1887.47s - 1892.47s | and it will require further instigation. It could also be account ID or some kind of 1892.47s - 1898.47s | other public metadata information. If it's a hash we could search on GitHub 1898.47s - 1902.47s | and on SourceGraph to find leaked hashes and then target them. And if it's 1902.47s - 1906.47s | an account ID there are multiple ways to find them. So the first method is 1906.47s - 1911.47s | to use GitHub. Uh we could search uh the GitHub regex search for specific patterns. 1911.47s - 1915.47s | We could also leverage the GrayHat Warfare platform which is a platform 1915.47s - 1919.47s | that collects publicly accessible S3 buckets. And then we could extract the account ID 1919.47s - 1925.47s | out of the bucket. So Jerome Brown did it and he extracted nearly 197,000 1925.97s - 1931.47s | unique account IDs. We could also extract the account ID out of the AWS access key ID. 1931.47s - 1936.47s | Nice article by Tal Berry who showed how to do it. And lastly there are valuable 1936.47s - 1941.47s | lists out there of known AWS accounts which includes account IDs of numerous large 1941.47s - 1946.47s | organizations and vendors. And the last step is to monopolize. So Attacker 1946.47s - 1951.47s | utilized the understanding of naming conventions and account IDs to strategically create 1951.47s


chunk_id: 165_chunk_32
chunk_text:
1898.47s - 1902.47s | and on SourceGraph to find leaked hashes and then target them. And if it's 1902.47s - 1906.47s | an account ID there are multiple ways to find them. So the first method is 1906.47s - 1911.47s | to use GitHub. Uh we could search uh the GitHub regex search for specific patterns. 1911.47s - 1915.47s | We could also leverage the GrayHat Warfare platform which is a platform 1915.47s - 1919.47s | that collects publicly accessible S3 buckets. And then we could extract the account ID 1919.47s - 1925.47s | out of the bucket. So Jerome Brown did it and he extracted nearly 197,000 1925.97s - 1931.47s | unique account IDs. We could also extract the account ID out of the AWS access key ID. 1931.47s - 1936.47s | Nice article by Tal Berry who showed how to do it. And lastly there are valuable 1936.47s - 1941.47s | lists out there of known AWS accounts which includes account IDs of numerous large 1941.47s - 1946.47s | organizations and vendors. And the last step is to monopolize. So Attacker 1946.47s - 1951.47s | utilized the understanding of naming conventions and account IDs to strategically create 1951.47s - 1957.47s | S3 buckets with predictable names across all AWS regions where these buckets do not exist yet. 1957.47s - 1963.47s | Then the attacker will open the bucket for public access, set permissive policy and by doing 1963.47s - 1970.47s | so they position themselves to intercept the victim future interactions with these buckets. 1970.47s - 1974.97s | Now let's talk a little bit about disclosure and timeline. So we reported these vulnerabilities 1974.97s - 1979.97s | at the middle of February and AWS immediately started fixing them. We got our final 1979.97s - 1985.47s | confirmation that the vulnerabilities were fixed at uh the end of June. And the general 1985.47s - 1991.47s | approach here was consistent. So AWS will either uh add some kind of a random sequence or a 1991.47s - 1997.47s | number to the bucket and then create it. Or they will prompt the user to choose a new bucket 1997.47s - 2002.97s | name thereby they will ignore the already claimed bucket. AWS also indicated that they are 2002.97s - 2006.97s | confirming the results of each team investigation and they will ca- contact customers 2006.97s - 2013.47s | directly in


chunk_id: 165_chunk_33
chunk_text:
- 1957.47s | S3 buckets with predictable names across all AWS regions where these buckets do not exist yet. 1957.47s - 1963.47s | Then the attacker will open the bucket for public access, set permissive policy and by doing 1963.47s - 1970.47s | so they position themselves to intercept the victim future interactions with these buckets. 1970.47s - 1974.97s | Now let's talk a little bit about disclosure and timeline. So we reported these vulnerabilities 1974.97s - 1979.97s | at the middle of February and AWS immediately started fixing them. We got our final 1979.97s - 1985.47s | confirmation that the vulnerabilities were fixed at uh the end of June. And the general 1985.47s - 1991.47s | approach here was consistent. So AWS will either uh add some kind of a random sequence or a 1991.47s - 1997.47s | number to the bucket and then create it. Or they will prompt the user to choose a new bucket 1997.47s - 2002.97s | name thereby they will ignore the already claimed bucket. AWS also indicated that they are 2002.97s - 2006.97s | confirming the results of each team investigation and they will ca- contact customers 2006.97s - 2013.47s | directly in the event that they were affected. So to conclude what we've seen up until now. We 2013.47s - 2018.27s | have identified six vulnerabilities in AWS uh that might enable an attacker to exploit 2018.27s - 2023.57s | organization. We explained how these vulnerabilities occur and we presented a new attack vector 2023.57s - 2028.17s | called Shadow Resources as well as the technique we named Bucket Monopoly. While the 2028.17s - 2033.47s | vulnerabilities we mentioned were already mitigated by AWS, this attack vector can still be 2033.47s - 2039.81s | applicable to other AWS services and many, many open source projects as you just saw. So to 2039.81s - 2045.37s | prevent an entity that assumes a role accessing a bucket you do not trust, you can define a 2045.37s - 2050.67s | scoped policy that contains the AWS resource account condition. So this approach will prevent 2050.67s - 2057.07s | the user in your account to access and write data to buckets that are located on accounts you 2057.07s - 2064.27s | do not trust. We also recommend verifying that the owner of the S3 bucket using the expected 2064.27s - 2070.11s | bucket owner header to


chunk_id: 165_chunk_34
chunk_text:
the event that they were affected. So to conclude what we've seen up until now. We 2013.47s - 2018.27s | have identified six vulnerabilities in AWS uh that might enable an attacker to exploit 2018.27s - 2023.57s | organization. We explained how these vulnerabilities occur and we presented a new attack vector 2023.57s - 2028.17s | called Shadow Resources as well as the technique we named Bucket Monopoly. While the 2028.17s - 2033.47s | vulnerabilities we mentioned were already mitigated by AWS, this attack vector can still be 2033.47s - 2039.81s | applicable to other AWS services and many, many open source projects as you just saw. So to 2039.81s - 2045.37s | prevent an entity that assumes a role accessing a bucket you do not trust, you can define a 2045.37s - 2050.67s | scoped policy that contains the AWS resource account condition. So this approach will prevent 2050.67s - 2057.07s | the user in your account to access and write data to buckets that are located on accounts you 2057.07s - 2064.27s | do not trust. We also recommend verifying that the owner of the S3 bucket using the expected 2064.27s - 2070.11s | bucket owner header to ensure that the buckets that are used by your services are indeed 2070.11s - 2075.57s | under your account. It's very simple. You can just take each one of your buckets, the cloud 2075.57s - 2080.81s | formation, the glue, the EMR and the rest of them and for each region check that no one has 2080.81s - 2085.77s | claimed your bucket. It's a simple solution and it's great to check if you uh haven't been 2085.77s - 2093.74s | exploited. Sorry, this command. And um the expected bucket owner header is also valuable for 2093.74s - 2102.25s | open source projects as well to verify that no one has claimed the bucket. And lastly, name 2102.25s - 2109.03s | your S3 bucket with some kind of um a random number or a string. Make it the bucket name less 2109.03s - 2118.41s | predictable. So after everything we've demonstrated, do you still believe account ID is not a 2118.41s - 2126.82s | secret? Thank you. We have short time for questions and you're welcome to follow us on Twitter. 2126.82s - 2138.86s | Alright. Questions anyone? Alright. We can. So, so do I, do I policy to uh


chunk_id: 165_chunk_35
chunk_text:
ensure that the buckets that are used by your services are indeed 2070.11s - 2075.57s | under your account. It's very simple. You can just take each one of your buckets, the cloud 2075.57s - 2080.81s | formation, the glue, the EMR and the rest of them and for each region check that no one has 2080.81s - 2085.77s | claimed your bucket. It's a simple solution and it's great to check if you uh haven't been 2085.77s - 2093.74s | exploited. Sorry, this command. And um the expected bucket owner header is also valuable for 2093.74s - 2102.25s | open source projects as well to verify that no one has claimed the bucket. And lastly, name 2102.25s - 2109.03s | your S3 bucket with some kind of um a random number or a string. Make it the bucket name less 2109.03s - 2118.41s | predictable. So after everything we've demonstrated, do you still believe account ID is not a 2118.41s - 2126.82s | secret? Thank you. We have short time for questions and you're welcome to follow us on Twitter. 2126.82s - 2138.86s | Alright. Questions anyone? Alright. We can. So, so do I, do I policy to uh prevent a lot of these 2161.17s - 2166.17s | attacks? So you can use them. Uh as as I showed you before um the, sorry, the the uh the 2171.48s - 2177.38s | um. Thank you. So you should, we we showed you several ways. I think the the resource account 2177.38s - 2183.66s | condition should be fine to prevent all your roles and users that assuming this role from 2183.66s - 2188.76s | accessing buckets you do not trust. I mean for specific roles that need to access some kinds of 2188.76s - 2193.76s | buckets, you just, I mean by default I recommend adding these like section to making sure that 2194.76s - 2199.76s | the buckets you try to access or your services et cetera will not um access buckets that you do 2204.00s - 2209.00s | not own or maybe someone else owns. Right. Cause you might also delete the bucket and then 2210.96s - 2216.94s | someone can create it. So it's like a dangling resource as well. Alright. Yeah I think I'm gonna 2216.94s - 2221.94s | have to go back through and double check my. Thank you. My uh deny policies. Thanks.


chunk_id: 165_chunk_36
chunk_text:
prevent a lot of these 2161.17s - 2166.17s | attacks? So you can use them. Uh as as I showed you before um the, sorry, the the uh the 2171.48s - 2177.38s | um. Thank you. So you should, we we showed you several ways. I think the the resource account 2177.38s - 2183.66s | condition should be fine to prevent all your roles and users that assuming this role from 2183.66s - 2188.76s | accessing buckets you do not trust. I mean for specific roles that need to access some kinds of 2188.76s - 2193.76s | buckets, you just, I mean by default I recommend adding these like section to making sure that 2194.76s - 2199.76s | the buckets you try to access or your services et cetera will not um access buckets that you do 2204.00s - 2209.00s | not own or maybe someone else owns. Right. Cause you might also delete the bucket and then 2210.96s - 2216.94s | someone can create it. So it's like a dangling resource as well. Alright. Yeah I think I'm gonna 2216.94s - 2221.94s | have to go back through and double check my. Thank you. My uh deny policies. Thanks. 2221.94s - 2225.60s | Alright. Thank you very much for attending.


chunk_id: 166_chunk_0
chunk_text:
{ "webpage_url": "https://www.youtube.com/watch?v=kEIJFsOgEBY", "title": "DEF CON 32 - AMD Sinkclose-Universal Ring2 Privilege Escalation - Enrique Nissim, Krzysztof Okupski", "description": "System Management Mode (SMM) is one of the most powerful execution modes in the x86 architecture and code at this level is invisible to the Hypervisor and OS-level protections, including anti-cheat engines and anti-virus systems. While the BIOS ecosystem's complexity has led to a multitude of vulnerabilities in firmware over time, vendors are now making strides in delivering patches with greater speed and efficiency. Unfortunately, these efforts are not enough in the presence of a CPU vulnerability.\n\nWhen researching the AMD processor, our team noticed a flaw in one of the critical components required for securing SMM. This silicon-level issue appears to have remained undetected for nearly two decades.\n\nThis presentation starts by providing an introduction to SMM and the security mechanisms that the AMD processor provides to support it. Subsequently, it delves into the CPU design flaw and the complete methodology and engineering used to create a universal ring -2 privilege escalation exploit.", "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw", "duration": 2614, "channel": "DEFCONConference", "uploader": "DEFCONConference", "upload_date": "20241016" } 0.00s - 5.76s | This text was transcribed using whisper model: large-v2 as a bootkit or in some cases as a firmware implant as we'll see later. What's good also is 5.76s - 13.08s | that code here is hidden from the OS and the hypervisor so antivirus EDRs or anti-cheat 13.08s - 18.48s | engines won't won't won't see these things right? Now in terms of privilege level this is 18.48s - 22.86s | just uh simplification but we can think it about like this we have our applications like for 22.86s - 28.46s | instance our browser running at the very top of ring three then we have our OS ring zero and 28.46s - 35.12s | if we have a hypervisor it's down the OS of course and only then we have SMM. Now how does 35.12s - 41.04s | this work? We can divide the uh the thing in into two phases. We have boot time where the 41.04s - 46.04s | firmware BIOS UFI code will after initializing the the hardware will load the SMM code into an 48.48s - 54.68s | special area of memory called SM RAM. And then it will hand off the execution to the OS 54.68s - 60.64s | loader then the OS loads and as you can


chunk_id: 166_chunk_1
chunk_text:
cases as a firmware implant as we'll see later. What's good also is 5.76s - 13.08s | that code here is hidden from the OS and the hypervisor so antivirus EDRs or anti-cheat 13.08s - 18.48s | engines won't won't won't see these things right? Now in terms of privilege level this is 18.48s - 22.86s | just uh simplification but we can think it about like this we have our applications like for 22.86s - 28.46s | instance our browser running at the very top of ring three then we have our OS ring zero and 28.46s - 35.12s | if we have a hypervisor it's down the OS of course and only then we have SMM. Now how does 35.12s - 41.04s | this work? We can divide the uh the thing in into two phases. We have boot time where the 41.04s - 46.04s | firmware BIOS UFI code will after initializing the the hardware will load the SMM code into an 48.48s - 54.68s | special area of memory called SM RAM. And then it will hand off the execution to the OS 54.68s - 60.64s | loader then the OS loads and as you can see SMM is just a run time concept. It will provide 60.64s - 65.88s | services for the for the platform. For instance power management, security and the OS can 65.88s - 71.32s | invoke some services from it as well. So how does that happen? Well there's this con- concept 71.32s - 78.20s | of system management interrupt. When an SMI occurs the processor gets interrupted and then 78.56s - 85.66s | the the current register set of the processor is saved into the SM RAM into a safety area. And 85.66s - 90.66s | then whatever needs to happen happens some um good feature for the system and it then comes 93.44s - 99.98s | back to the OS. In this case we are doing a synchronous SMI like a software SMI the OS is um 99.98s - 104.98s | invoking a service from SMM. Now we've been working on this area for a bit. Um we we 108.68s - 112.26s | published some some blogs. We've done some some presentations before. How are you on 112.26s - 117.26s | Hexagon? We have a couple of CVEs in 2023 and we also released some tools for um checking


chunk_id: 166_chunk_2
chunk_text:
see SMM is just a run time concept. It will provide 60.64s - 65.88s | services for the for the platform. For instance power management, security and the OS can 65.88s - 71.32s | invoke some services from it as well. So how does that happen? Well there's this con- concept 71.32s - 78.20s | of system management interrupt. When an SMI occurs the processor gets interrupted and then 78.56s - 85.66s | the the current register set of the processor is saved into the SM RAM into a safety area. And 85.66s - 90.66s | then whatever needs to happen happens some um good feature for the system and it then comes 93.44s - 99.98s | back to the OS. In this case we are doing a synchronous SMI like a software SMI the OS is um 99.98s - 104.98s | invoking a service from SMM. Now we've been working on this area for a bit. Um we we 108.68s - 112.26s | published some some blogs. We've done some some presentations before. How are you on 112.26s - 117.26s | Hexagon? We have a couple of CVEs in 2023 and we also released some tools for um checking for 119.70s - 126.10s | misconfigurations and known issues. Um all of these things that we've done before are mostly 126.10s - 131.44s | related to either misconfigurations from vendors or software vulnerabilities in components. 131.44s - 137.48s | Now we're gonna present today is an architectural flaw in the AMD processor itself. So that's 137.50s - 142.50s | very different. And so for that we're gonna just see again what is what makes the security of 142.50s - 148.08s | SMM. So we can think on the CPU when it's an SMM mode we have the memory controller in the 148.08s - 153.12s | middle and we can just access this area with where the SMM code and data lives. We can 153.12s - 158.68s | execute instructions from this area. We can write to this area and read. However when the CPU 158.68s - 165.02s | is in normal mode meaning non-SMM the memory controller just rejects um if if if you read 165.04s - 170.44s | from this um from this memory you're just gonna return receive F's. Writes are discarded and 170.44s - 176.84s | of course execution is disallowed. How does this hap- how is


chunk_id: 166_chunk_3
chunk_text:
for 119.70s - 126.10s | misconfigurations and known issues. Um all of these things that we've done before are mostly 126.10s - 131.44s | related to either misconfigurations from vendors or software vulnerabilities in components. 131.44s - 137.48s | Now we're gonna present today is an architectural flaw in the AMD processor itself. So that's 137.50s - 142.50s | very different. And so for that we're gonna just see again what is what makes the security of 142.50s - 148.08s | SMM. So we can think on the CPU when it's an SMM mode we have the memory controller in the 148.08s - 153.12s | middle and we can just access this area with where the SMM code and data lives. We can 153.12s - 158.68s | execute instructions from this area. We can write to this area and read. However when the CPU 158.68s - 165.02s | is in normal mode meaning non-SMM the memory controller just rejects um if if if you read 165.04s - 170.44s | from this um from this memory you're just gonna return receive F's. Writes are discarded and 170.44s - 176.84s | of course execution is disallowed. How does this hap- how is this happening? Well we have 176.84s - 182.48s | um what's called a TSEC region or top of memory segment region. Essentially the firmware 182.48s - 187.48s | after loads uh after it loads SMM at boot time it will hopefully configure these 2 registers 188.02s - 193.02s | and the idea is to overlap um have this region to overlap with all the contents of SMM to 197.16s - 202.30s | protect it. We have uh 2 registers we have the TSEC base and the TSEC mask which is the 202.30s - 208.80s | length. The TSEC ma- the TSEC mask as you can see have also uh additional fields and yeah 208.80s - 214.34s | essentially this is the way. The memory controller will see that uh the CPU is executing in 214.38s - 221.08s | normal mode and will just reject to read the content or write the content of the SMRAM. Has 221.08s - 226.08s | to be enabled. That's why the T-valid bit is there. Now the layout of SMRAM uh basically is 229.72s - 234.72s | up to the vendor to define but most systems out there are gonna follow what the EDK2 has


chunk_id: 166_chunk_4
chunk_text:
this happening? Well we have 176.84s - 182.48s | um what's called a TSEC region or top of memory segment region. Essentially the firmware 182.48s - 187.48s | after loads uh after it loads SMM at boot time it will hopefully configure these 2 registers 188.02s - 193.02s | and the idea is to overlap um have this region to overlap with all the contents of SMM to 197.16s - 202.30s | protect it. We have uh 2 registers we have the TSEC base and the TSEC mask which is the 202.30s - 208.80s | length. The TSEC ma- the TSEC mask as you can see have also uh additional fields and yeah 208.80s - 214.34s | essentially this is the way. The memory controller will see that uh the CPU is executing in 214.38s - 221.08s | normal mode and will just reject to read the content or write the content of the SMRAM. Has 221.08s - 226.08s | to be enabled. That's why the T-valid bit is there. Now the layout of SMRAM uh basically is 229.72s - 234.72s | up to the vendor to define but most systems out there are gonna follow what the EDK2 has 237.16s - 242.56s | which is TianoCore. This is reference code. And uh essentially it's gonna consist at the 242.56s - 248.36s | very bottom you can see here um SMM core area. This is just supporting code for the rest of 248.36s - 253.36s | um of what's gonna be in there. And then for each core we're gonna have an SMM base and at a 255.64s - 260.74s | specific offset 8000 from the SMM base we're gonna have the entry point which is where the 260.74s - 266.18s | processor, the core is gonna start executing from when the SMI happens. And then we have a 266.18s - 272.42s | safe state at offset FE00. This is TianoCore right? It can be laid out differently by the 272.42s - 277.52s | vendor. And then we have the SMI handlers at the very top which is are gonna be the 277.52s - 282.12s | functions that are are gonna be useful for for us for the system. Handling power, security or 282.12s - 288.12s | whatever. Um so yeah just a summary of the SMRAM registers. We have the 3 just we just 288.12s - 293.80s | mentioned.


chunk_id: 166_chunk_5
chunk_text:
237.16s - 242.56s | which is TianoCore. This is reference code. And uh essentially it's gonna consist at the 242.56s - 248.36s | very bottom you can see here um SMM core area. This is just supporting code for the rest of 248.36s - 253.36s | um of what's gonna be in there. And then for each core we're gonna have an SMM base and at a 255.64s - 260.74s | specific offset 8000 from the SMM base we're gonna have the entry point which is where the 260.74s - 266.18s | processor, the core is gonna start executing from when the SMI happens. And then we have a 266.18s - 272.42s | safe state at offset FE00. This is TianoCore right? It can be laid out differently by the 272.42s - 277.52s | vendor. And then we have the SMI handlers at the very top which is are gonna be the 277.52s - 282.12s | functions that are are gonna be useful for for us for the system. Handling power, security or 282.12s - 288.12s | whatever. Um so yeah just a summary of the SMRAM registers. We have the 3 just we just 288.12s - 293.80s | mentioned. And we also have an SMM block. That's very important. Hopefully the firmware code 293.80s - 299.90s | is gonna set this bit so that the whatever runs at run time the OS cannot tamper with these 299.92s - 305.82s | registers. We don't want for example at run time having the OS disabling the TSEC location 305.82s - 312.24s | because this will just um update or change the code at the SMRAM location and execute with 312.24s - 318.64s | these additional privileges right? Now this need to be configured for each core. With that we 318.64s - 323.64s | can see a first difference between how Intel and AMD manage the access to MSRs. On Intel 324.30s - 329.30s | systems these MSRs that are related to SMM are only accessible while the CPU is in SMM. In 334.24s - 341.00s | fact obtaining the SMM base for example on Intel could be considered a leak. On AMD all 341.00s - 348.12s | these MSRs are accessible from ring zero no problem. Again if we have the SMM lock bit set 348.12s - 352.92s | then the configuration cannot be changed. Not even SMM can change the


chunk_id: 166_chunk_6
chunk_text:
And we also have an SMM block. That's very important. Hopefully the firmware code 293.80s - 299.90s | is gonna set this bit so that the whatever runs at run time the OS cannot tamper with these 299.92s - 305.82s | registers. We don't want for example at run time having the OS disabling the TSEC location 305.82s - 312.24s | because this will just um update or change the code at the SMRAM location and execute with 312.24s - 318.64s | these additional privileges right? Now this need to be configured for each core. With that we 318.64s - 323.64s | can see a first difference between how Intel and AMD manage the access to MSRs. On Intel 324.30s - 329.30s | systems these MSRs that are related to SMM are only accessible while the CPU is in SMM. In 334.24s - 341.00s | fact obtaining the SMM base for example on Intel could be considered a leak. On AMD all 341.00s - 348.12s | these MSRs are accessible from ring zero no problem. Again if we have the SMM lock bit set 348.12s - 352.92s | then the configuration cannot be changed. Not even SMM can change the configuration until 352.94s - 357.14s | the next power cycle in which I mean the firmware will take over again and configure this in 357.14s - 362.14s | the same way. But we can now spot the bug in the documentation. This is the same TSEC mask 365.52s - 372.08s | register and the fields just a picture from the documentation. We can see how the SMM lock 372.08s - 378.12s | is covering all of the fields except for two over there. These two fields are gonna be what 378.16s - 384.36s | we're gonna be talking about um in this session. And we have T-Close and A-Close. Um we're 384.36s - 390.40s | just gonna focus on T-Close. A-Close it stands for um the same feature but for uh a previous 390.40s - 394.08s | region called ASEC which is overlaps on the video memory. It's not used anymore so it doesn't 394.08s - 399.08s | matter. But what happens is when this bit is set the data accesses that the core that the 401.52s - 407.72s | core performs when it's running in SMM are gonna be directed to MMIO instead of to SMRAM. And 407.72s -


chunk_id: 166_chunk_7
chunk_text:
configuration until 352.94s - 357.14s | the next power cycle in which I mean the firmware will take over again and configure this in 357.14s - 362.14s | the same way. But we can now spot the bug in the documentation. This is the same TSEC mask 365.52s - 372.08s | register and the fields just a picture from the documentation. We can see how the SMM lock 372.08s - 378.12s | is covering all of the fields except for two over there. These two fields are gonna be what 378.16s - 384.36s | we're gonna be talking about um in this session. And we have T-Close and A-Close. Um we're 384.36s - 390.40s | just gonna focus on T-Close. A-Close it stands for um the same feature but for uh a previous 390.40s - 394.08s | region called ASEC which is overlaps on the video memory. It's not used anymore so it doesn't 394.08s - 399.08s | matter. But what happens is when this bit is set the data accesses that the core that the 401.52s - 407.72s | core performs when it's running in SMM are gonna be directed to MMIO instead of to SMRAM. And 407.72s - 413.70s | that's that's that's cool because as we said before we could set this bit from ring 0 413.70s - 420.30s | because it's not locked by the SMM lock right? It actually in the in the A-Close description 420.30s - 425.70s | it also says hey I mean don't forget to unset this when you're returning from SMM cause 425.70s - 430.72s | otherwise your safety are gonna be erroneously read from MMIO. That's bad. Um the 431.32s - 438.32s | documentation says as well hey if you have a valid T-Close region and you're in SMM and the 438.32s - 443.16s | T-Close is set then instruction fetches are still gonna be directed to DRAM but data 443.16s - 449.40s | accesses are gonna go to MMIO instead. If you're not in SMM then both accesses, both type 449.40s - 454.40s | of accesses are gonna go to MMIO. So we can say um x86 behaves in a hardware like a 454.80s - 461.70s | hardware architecture goes to hardware right? If we have um our core core 0 for example 461.70s - 467.14s | running in normal mode both data and instruction fetches just go to


chunk_id: 166_chunk_8
chunk_text:
413.70s | that's that's that's cool because as we said before we could set this bit from ring 0 413.70s - 420.30s | because it's not locked by the SMM lock right? It actually in the in the A-Close description 420.30s - 425.70s | it also says hey I mean don't forget to unset this when you're returning from SMM cause 425.70s - 430.72s | otherwise your safety are gonna be erroneously read from MMIO. That's bad. Um the 431.32s - 438.32s | documentation says as well hey if you have a valid T-Close region and you're in SMM and the 438.32s - 443.16s | T-Close is set then instruction fetches are still gonna be directed to DRAM but data 443.16s - 449.40s | accesses are gonna go to MMIO instead. If you're not in SMM then both accesses, both type 449.40s - 454.40s | of accesses are gonna go to MMIO. So we can say um x86 behaves in a hardware like a 454.80s - 461.70s | hardware architecture goes to hardware right? If we have um our core core 0 for example 461.70s - 467.14s | running in normal mode both data and instruction fetches just go to MMIO. If we have our 467.14s - 472.62s | core 0 now in SMM with the T-Close off this is what happens. No problem we read and 472.62s - 478.42s | execute from SMRAM. However when set T-Close on now data fetches go like this. This is a 478.42s - 483.42s | problem because this portion can be controlled by an attacker. So triggering the 486.18s - 492.32s | condition is super easy we just need to um set this this bit, this T-Close bit and call 492.32s - 497.30s | into an SMI and the system will immediately freeze, hang or you're gonna spot the problem 497.30s - 502.30s | right there. This feature exists because um while AMD wanted to have the ability to re-use 503.02s - 508.02s | the physical address space and have SMM code um access an IO device that were using the 511.16s - 517.40s | same SMRAM uh physical memory essentially. Um we haven't seen any vendor using this 517.40s - 522.40s | feature um but yeah that's why. And it was on on what we could track is in 2006 there was 525.00s - 529.28s | this document that first mentioned the


chunk_id: 166_chunk_9
chunk_text:
MMIO. If we have our 467.14s - 472.62s | core 0 now in SMM with the T-Close off this is what happens. No problem we read and 472.62s - 478.42s | execute from SMRAM. However when set T-Close on now data fetches go like this. This is a 478.42s - 483.42s | problem because this portion can be controlled by an attacker. So triggering the 486.18s - 492.32s | condition is super easy we just need to um set this this bit, this T-Close bit and call 492.32s - 497.30s | into an SMI and the system will immediately freeze, hang or you're gonna spot the problem 497.30s - 502.30s | right there. This feature exists because um while AMD wanted to have the ability to re-use 503.02s - 508.02s | the physical address space and have SMM code um access an IO device that were using the 511.16s - 517.40s | same SMRAM uh physical memory essentially. Um we haven't seen any vendor using this 517.40s - 522.40s | feature um but yeah that's why. And it was on on what we could track is in 2006 there was 525.00s - 529.28s | this document that first mentioned the feature so it means it's been around at least for 529.32s - 535.57s | 18 years. Now for people familiarized with um biosecurity they're probably gonna remember 538.65s - 543.69s | this vulnerability presented by Christopher Thomas in 2015 called the memory sinkhole 543.69s - 549.49s | attack. And what happened was that he was able to remap the APIC which is a specific 549.49s - 555.23s | device um in the um available and overlap it with the T-Seq area and it caused the same 555.23s - 559.97s | effect. Uh data fetches will go to MMIO instead of SMRAM. Now the difference here of 559.97s - 566.45s | course is that uh that was only limited to the APIC and it only affected the 4K region where 566.45s - 572.25s | the APIC was overlapped with. The sinkhole's behavior changed uh how the entire T-Seq 572.25s - 578.13s | works. Um any device in theory could be overlapped right? Because we just direct any 578.13s - 584.38s | access to the MMIO space. So we can bring some some attack ideas in. Our easy thing will 585.38s - 590.38s | be, the easiest thing will be to just


chunk_id: 166_chunk_10
chunk_text:
feature so it means it's been around at least for 529.32s - 535.57s | 18 years. Now for people familiarized with um biosecurity they're probably gonna remember 538.65s - 543.69s | this vulnerability presented by Christopher Thomas in 2015 called the memory sinkhole 543.69s - 549.49s | attack. And what happened was that he was able to remap the APIC which is a specific 549.49s - 555.23s | device um in the um available and overlap it with the T-Seq area and it caused the same 555.23s - 559.97s | effect. Uh data fetches will go to MMIO instead of SMRAM. Now the difference here of 559.97s - 566.45s | course is that uh that was only limited to the APIC and it only affected the 4K region where 566.45s - 572.25s | the APIC was overlapped with. The sinkhole's behavior changed uh how the entire T-Seq 572.25s - 578.13s | works. Um any device in theory could be overlapped right? Because we just direct any 578.13s - 584.38s | access to the MMIO space. So we can bring some some attack ideas in. Our easy thing will 585.38s - 590.38s | be, the easiest thing will be to just grab any PCI device and hopefully we'll have a good 593.42s - 597.66s | register layout on its bar so that we can take control of the execution at the very 597.66s - 602.10s | beginning of the entry point. As there are multiple integrated devices that we could use we 602.10s - 607.20s | could just try remapping one of those and based on what we read the register should become 607.20s - 612.20s | visible at the T-Seq location from the OS. However this failed. We can see here how the 614.84s - 619.84s | uh we have an Ethernet controller uh with its original uh bar 2 uh D0714000. We have some 624.12s - 628.22s | registers right here. They're visible registers. And we're gonna try to overlap when we try 628.22s - 633.22s | to overlap it with the SMM entry uh BFEB0000 we can see that we're still reading F's. So the 634.92s - 639.94s | remapping failed. Registers are not available. Um we can see that the registers were moved from 640.60s - 645.60s | their original location. They're they're something happened. When we restore we can see 650.18s - 655.88s | the registers


chunk_id: 166_chunk_11
chunk_text:
grab any PCI device and hopefully we'll have a good 593.42s - 597.66s | register layout on its bar so that we can take control of the execution at the very 597.66s - 602.10s | beginning of the entry point. As there are multiple integrated devices that we could use we 602.10s - 607.20s | could just try remapping one of those and based on what we read the register should become 607.20s - 612.20s | visible at the T-Seq location from the OS. However this failed. We can see here how the 614.84s - 619.84s | uh we have an Ethernet controller uh with its original uh bar 2 uh D0714000. We have some 624.12s - 628.22s | registers right here. They're visible registers. And we're gonna try to overlap when we try 628.22s - 633.22s | to overlap it with the SMM entry uh BFEB0000 we can see that we're still reading F's. So the 634.92s - 639.94s | remapping failed. Registers are not available. Um we can see that the registers were moved from 640.60s - 645.60s | their original location. They're they're something happened. When we restore we can see 650.18s - 655.88s | the registers again. So it's not that we broke anything. So it's just the the the priority 655.88s - 660.88s | of the memory probably failed right? So what that that led us to try to understand ok how 660.88s - 667.90s | that does how how is that working? Have this register called top of memory or TOM. Um this 667.92s - 672.92s | thing defines a limit between the usable DRAM before 4 gigabytes on the physical address space 675.30s - 680.30s | and MMIO space on top. Now on Intel this register has a lock bit. Once it's configured you 682.64s - 687.28s | cannot tamper with it anymore at run time. But on AMD it doesn't have such a lock so we 687.28s - 692.78s | can just you know modify this and maybe that's good for us. The idea is simple. We have 692.80s - 698.24s | this is uh imagine this is the layout right? And we'll move the MMIO space or the TOM that 698.24s - 703.72s | defines the MMIO space to match with the TSEC base. So we have something like that. Maybe 703.72s - 708.72s | then trying the same trick that


chunk_id: 166_chunk_12
chunk_text:
again. So it's not that we broke anything. So it's just the the the priority 655.88s - 660.88s | of the memory probably failed right? So what that that led us to try to understand ok how 660.88s - 667.90s | that does how how is that working? Have this register called top of memory or TOM. Um this 667.92s - 672.92s | thing defines a limit between the usable DRAM before 4 gigabytes on the physical address space 675.30s - 680.30s | and MMIO space on top. Now on Intel this register has a lock bit. Once it's configured you 682.64s - 687.28s | cannot tamper with it anymore at run time. But on AMD it doesn't have such a lock so we 687.28s - 692.78s | can just you know modify this and maybe that's good for us. The idea is simple. We have 692.80s - 698.24s | this is uh imagine this is the layout right? And we'll move the MMIO space or the TOM that 698.24s - 703.72s | defines the MMIO space to match with the TSEC base. So we have something like that. Maybe 703.72s - 708.72s | then trying the same trick that we uh did before could work. Unfortunately we could move the 711.02s - 715.76s | TSEC no problem but it didn't change the behavior that we saw before. In practice it didn't 715.76s - 720.76s | work. So that led us to dig dig uh dig uh deeper into into the computation of the 723.14s - 727.14s | foundation and we found there are some actual priorities when the core access um some 727.14s - 731.10s | portion of the physical address space. Essentially determines what what is going. And we 731.10s - 736.32s | can see that the TSEC and ASIC mechanisms are listed 4. Which means 1, 2 and 3 with whatever 736.32s - 742.22s | is listed there has less less priority than this. And at the at number 1 we can see the TOM 742.22s - 745.86s | is is is listed there. So we have that's why it never worked. Right? It would have never 745.86s - 750.86s | worked. What's at 5? Where we have the MMIO configuration space and the APIC. So 753.76s - 758.76s | uh that makes sense. We the APIC was used before in the Intel attack. The MMIO config


chunk_id: 166_chunk_13
chunk_text:
we uh did before could work. Unfortunately we could move the 711.02s - 715.76s | TSEC no problem but it didn't change the behavior that we saw before. In practice it didn't 715.76s - 720.76s | work. So that led us to dig dig uh dig uh deeper into into the computation of the 723.14s - 727.14s | foundation and we found there are some actual priorities when the core access um some 727.14s - 731.10s | portion of the physical address space. Essentially determines what what is going. And we 731.10s - 736.32s | can see that the TSEC and ASIC mechanisms are listed 4. Which means 1, 2 and 3 with whatever 736.32s - 742.22s | is listed there has less less priority than this. And at the at number 1 we can see the TOM 742.22s - 745.86s | is is is listed there. So we have that's why it never worked. Right? It would have never 745.86s - 750.86s | worked. What's at 5? Where we have the MMIO configuration space and the APIC. So 753.76s - 758.76s | uh that makes sense. We the APIC was used before in the Intel attack. The MMIO config space 761.40s - 766.40s | we cannot use really. Um and then at 6 we have this NORBRIDGE address space uh routing but uh 768.92s - 773.92s | that probably stands for older architectures. This is not seen in modern modern stuff. So we 773.92s - 780.42s | cannot use it. For the APIC we cannot really use it and we're gonna explain why. But for 780.44s - 785.44s | that we need to give an analysis of of um how the SMM entry point code works. When the SMM 787.90s - 794.64s | when the SMI occurs the SMM core uh that the core um executing at SMM starts executing in 794.64s - 800.52s | real mode. In 16 bit mode flat. No protection whatsoever. What it has to do is quickly go 800.52s - 804.82s | to protected mode 32 bit and then goes to long mode and then passes the execution to the 804.82s - 809.62s | handlers. This is a very simplified view. Now that first step going to from real mode to 809.62s - 815.90s | protected mode is is key right? That's the first thing that needs to happen. For this um on 815.90s


chunk_id: 166_chunk_14
chunk_text:
space 761.40s - 766.40s | we cannot use really. Um and then at 6 we have this NORBRIDGE address space uh routing but uh 768.92s - 773.92s | that probably stands for older architectures. This is not seen in modern modern stuff. So we 773.92s - 780.42s | cannot use it. For the APIC we cannot really use it and we're gonna explain why. But for 780.44s - 785.44s | that we need to give an analysis of of um how the SMM entry point code works. When the SMM 787.90s - 794.64s | when the SMI occurs the SMM core uh that the core um executing at SMM starts executing in 794.64s - 800.52s | real mode. In 16 bit mode flat. No protection whatsoever. What it has to do is quickly go 800.52s - 804.82s | to protected mode 32 bit and then goes to long mode and then passes the execution to the 804.82s - 809.62s | handlers. This is a very simplified view. Now that first step going to from real mode to 809.62s - 815.90s | protected mode is is key right? That's the first thing that needs to happen. For this um on 815.90s - 820.90s | x86 we need essentially an are enabled segmentation. Uh segmentation provides um the 824.10s - 828.30s | ability for the for the core to see the memory in a segmented way. That's that's how it's 828.30s - 833.38s | called. Essentially we can have different segments for memory and assigns uh different 833.38s - 838.38s | permissions or like um the ability to execute code or or just read data and stuff like that. 838.42s - 844.28s | We have this key data structure called global descriptor table of G or GDT. And we have a 844.28s - 849.72s | register on the processor that is called GDTR that's gonna point to the base of our GDT 849.72s - 855.16s | structure and it's gonna have a limit in bytes. And so the GDT is just really an array of 855.16s - 858.20s | descriptors. And we can have different type of descriptors. We can have we can have code 858.20s - 862.74s | descriptors, data descriptors. Each one is gonna have a base. The first one is never used. 862.74s - 866.80s | That's why it's called it's called null descriptor. But then when we have


chunk_id: 166_chunk_15
chunk_text:
- 820.90s | x86 we need essentially an are enabled segmentation. Uh segmentation provides um the 824.10s - 828.30s | ability for the for the core to see the memory in a segmented way. That's that's how it's 828.30s - 833.38s | called. Essentially we can have different segments for memory and assigns uh different 833.38s - 838.38s | permissions or like um the ability to execute code or or just read data and stuff like that. 838.42s - 844.28s | We have this key data structure called global descriptor table of G or GDT. And we have a 844.28s - 849.72s | register on the processor that is called GDTR that's gonna point to the base of our GDT 849.72s - 855.16s | structure and it's gonna have a limit in bytes. And so the GDT is just really an array of 855.16s - 858.20s | descriptors. And we can have different type of descriptors. We can have we can have code 858.20s - 862.74s | descriptors, data descriptors. Each one is gonna have a base. The first one is never used. 862.74s - 866.80s | That's why it's called it's called null descriptor. But then when we have a jump you can see 866.80s - 871.66s | we'll have um a jump. It's not only having an offset like a target location but it's also 871.66s - 876.10s | gonna have like a segment selector right here. That segment selector picks the descriptor 876.10s - 881.10s | we're gonna use for the for for our our code segment. And then the top the the offset is 881.10s - 887.42s | added to the base that it's indicated by the GDT. Forming the final linear address. With 887.42s - 892.42s | that we can do uh an analysis of um the EDK2 SMM entry point. Essentially um we can see 896.98s - 903.70s | that at the very beginning we are moving into the register BX. The entry point plus 4D. This 903.70s - 910.14s | is in this is a decom like um extracted from a from from a compiled um SMM code. So you can 910.14s - 915.38s | see at 4D right there we have a GDT description ready to to to be loaded into the GDTR. The 915.38s - 919.34s | next instruction that matters for us is the load GDT. This is instruction that


chunk_id: 166_chunk_16
chunk_text:
a jump you can see 866.80s - 871.66s | we'll have um a jump. It's not only having an offset like a target location but it's also 871.66s - 876.10s | gonna have like a segment selector right here. That segment selector picks the descriptor 876.10s - 881.10s | we're gonna use for the for for our our code segment. And then the top the the offset is 881.10s - 887.42s | added to the base that it's indicated by the GDT. Forming the final linear address. With 887.42s - 892.42s | that we can do uh an analysis of um the EDK2 SMM entry point. Essentially um we can see 896.98s - 903.70s | that at the very beginning we are moving into the register BX. The entry point plus 4D. This 903.70s - 910.14s | is in this is a decom like um extracted from a from from a compiled um SMM code. So you can 910.14s - 915.38s | see at 4D right there we have a GDT description ready to to to be loaded into the GDTR. The 915.38s - 919.34s | next instruction that matters for us is the load GDT. This is instruction that is gonna load 919.34s - 925.92s | the GDTR with the content that BX points to. And finally we have a jump over here that's 925.94s - 932.44s | gonna perform the actual um going into protected mode. And it has the selector of co of code 932.44s - 939.36s | as as well and the offset. Now with this what what will happen if we over overlap a device 939.36s - 945.72s | that we control on the entry point? And we control offset 4D. What will happen is that the 945.72s - 951.10s | load GDT will be loading something that we control. So we can load our fake GDT right? So 951.12s - 956.58s | that's what we're trying to do here. We're trying to get control over the offset 4D with any 956.58s - 962.02s | device that we can find so that the the fake GDT then provides the descriptors we need and we 962.02s - 968.90s | can take control and jump down there. That's the whole idea of the attack. And that's why 968.90s - 973.80s | the APIC is a problem. Two things. First the system becomes unstable when the APIC is


chunk_id: 166_chunk_17
chunk_text:
is gonna load 919.34s - 925.92s | the GDTR with the content that BX points to. And finally we have a jump over here that's 925.94s - 932.44s | gonna perform the actual um going into protected mode. And it has the selector of co of code 932.44s - 939.36s | as as well and the offset. Now with this what what will happen if we over overlap a device 939.36s - 945.72s | that we control on the entry point? And we control offset 4D. What will happen is that the 945.72s - 951.10s | load GDT will be loading something that we control. So we can load our fake GDT right? So 951.12s - 956.58s | that's what we're trying to do here. We're trying to get control over the offset 4D with any 956.58s - 962.02s | device that we can find so that the the fake GDT then provides the descriptors we need and we 962.02s - 968.90s | can take control and jump down there. That's the whole idea of the attack. And that's why 968.90s - 973.80s | the APIC is a problem. Two things. First the system becomes unstable when the APIC is 973.80s - 979.28s | moved. Super unstable. Second the APIC registers are not useful for taking control in the way 979.28s - 985.06s | we need. We can see that at 4D we have these reserved regions with all 0s. Writes are 985.06s - 990.24s | discarded here. We're not able to control here and if we load a GDTR with all 0s we're 990.24s - 996.84s | essentially saying to the processor hey here's an empty GDT. So this won't work. And at this 996.84s - 1001.52s | point we found another device not documented by the the the specification that also has 1001.52s - 1006.62s | priority over uh the TSEC region. That's the spy controller and Christoph's gonna describe 1006.62s - 1011.64s | it for us. Alright. So the spy controller is a very nice device for us because it's present 1014.34s - 1019.70s | in all the systems we've tested and it's basically used to access the spy flash on um AMD uh 1019.70s - 1024.54s | systems. So for example for reading, writing, erasing the spy flash it always goes for the 1024.54s - 1029.48s | spy controller. And it has a couple of key


chunk_id: 166_chunk_18
chunk_text:
973.80s - 979.28s | moved. Super unstable. Second the APIC registers are not useful for taking control in the way 979.28s - 985.06s | we need. We can see that at 4D we have these reserved regions with all 0s. Writes are 985.06s - 990.24s | discarded here. We're not able to control here and if we load a GDTR with all 0s we're 990.24s - 996.84s | essentially saying to the processor hey here's an empty GDT. So this won't work. And at this 996.84s - 1001.52s | point we found another device not documented by the the the specification that also has 1001.52s - 1006.62s | priority over uh the TSEC region. That's the spy controller and Christoph's gonna describe 1006.62s - 1011.64s | it for us. Alright. So the spy controller is a very nice device for us because it's present 1014.34s - 1019.70s | in all the systems we've tested and it's basically used to access the spy flash on um AMD uh 1019.70s - 1024.54s | systems. So for example for reading, writing, erasing the spy flash it always goes for the 1024.54s - 1029.48s | spy controller. And it has a couple of key features that are really uh interesting to us. 1029.48s - 1034.48s | First of all we can relocate the bar over the SMM entry point. Secondly the portions which 1034.48s - 1038.86s | are interesting to us at offset 4D we can control them. And three it actually takes 1038.86s - 1044.60s | precedence over uh SMRAM when TCLOS is enabled. So with that in mind what we will do for our 1044.60s - 1051.30s | attack is simply take the spy bar, relocate it over the SMM entry point of core zero and 1051.30s - 1056.30s | then afterwards manipulate the values at offset 4D within that bar. Um the um registers 1058.30s - 1062.48s | that actually correspond to that portion of memory in the bar uh are the memory range and 1062.48s - 1067.58s | run protection zero register. Those were used in the past to uh lock down access to the spy 1067.58s - 1073.22s | flash but mostly these are not configured and not fixed so we can fully control them. On 1073.22s - 1078.06s | some systems they are fixed but actually they are fixed to values which are still useful for 1078.06s -


chunk_id: 166_chunk_19
chunk_text:
features that are really uh interesting to us. 1029.48s - 1034.48s | First of all we can relocate the bar over the SMM entry point. Secondly the portions which 1034.48s - 1038.86s | are interesting to us at offset 4D we can control them. And three it actually takes 1038.86s - 1044.60s | precedence over uh SMRAM when TCLOS is enabled. So with that in mind what we will do for our 1044.60s - 1051.30s | attack is simply take the spy bar, relocate it over the SMM entry point of core zero and 1051.30s - 1056.30s | then afterwards manipulate the values at offset 4D within that bar. Um the um registers 1058.30s - 1062.48s | that actually correspond to that portion of memory in the bar uh are the memory range and 1062.48s - 1067.58s | run protection zero register. Those were used in the past to uh lock down access to the spy 1067.58s - 1073.22s | flash but mostly these are not configured and not fixed so we can fully control them. On 1073.22s - 1078.06s | some systems they are fixed but actually they are fixed to values which are still useful for 1078.06s - 1083.06s | us. So before I dive into the exploits uh I also want to uh show you a little bit our debugging 1085.58s - 1090.58s | stuff because it's a little bit special. Um so we are facing actually two challenges uh 1092.54s - 1098.44s | when we try to develop the exploit. First of all we didn't really have a way to know whether our 1098.44s - 1103.62s | payload ran because the system just crashes, reboots and memory is just all wiped. Uh and 1103.62s - 1109.76s | secondly we didn't really have any debugging framework for SMM. Um and like for example 1109.76s - 1114.36s | when crashes happen we want to be able to modify the code however we see fit. So to resolve the 1114.36s - 1120.40s | first issue we actually took a PCI squirrel which is typically used with PCI leach for a DMA 1120.42s - 1127.06s | attacks but the nice thing about it is actually is that it has a bar buffer as we call it 1127.06s - 1133.30s | where when we write to it it actually survives across reboots. So for instance a payload can 1133.30s - 1138.68s


chunk_id: 166_chunk_20
chunk_text:
1083.06s | us. So before I dive into the exploits uh I also want to uh show you a little bit our debugging 1085.58s - 1090.58s | stuff because it's a little bit special. Um so we are facing actually two challenges uh 1092.54s - 1098.44s | when we try to develop the exploit. First of all we didn't really have a way to know whether our 1098.44s - 1103.62s | payload ran because the system just crashes, reboots and memory is just all wiped. Uh and 1103.62s - 1109.76s | secondly we didn't really have any debugging framework for SMM. Um and like for example 1109.76s - 1114.36s | when crashes happen we want to be able to modify the code however we see fit. So to resolve the 1114.36s - 1120.40s | first issue we actually took a PCI squirrel which is typically used with PCI leach for a DMA 1120.42s - 1127.06s | attacks but the nice thing about it is actually is that it has a bar buffer as we call it 1127.06s - 1133.30s | where when we write to it it actually survives across reboots. So for instance a payload can 1133.30s - 1138.68s | write a value to uh the bar buffer kind of like a checkpoint so we know it ran and then when the 1138.68s - 1143.04s | system reboots it's still going to be there. Right. And if we want to modify for example for 1143.04s - 1148.52s | the second issue if we want to modify uh code in SMM for some extra debugging capabilities for 1148.54s - 1154.04s | that we just um injected a firmware implant uh that loads a nice SMM module that allows us to 1154.04s - 1159.02s | do all of that. So the setup looks like this we just have the PCI squirrel connected to our 1159.02s - 1164.02s | target device via an M2 uh adapter and all of this is powered externally by a power supply. So 1166.62s - 1171.36s | it's time to get our hands dirty so let's take a look at how uh the exploit looks like. In the 1171.36s - 1175.86s | first attempt uh we remap the spy bar just like mentioned before over the SMM entry point of 1175.94s - 1182.94s | core zero. Then we tweak uh these values at offset 4D. We create


chunk_id: 166_chunk_21
chunk_text:
| write a value to uh the bar buffer kind of like a checkpoint so we know it ran and then when the 1138.68s - 1143.04s | system reboots it's still going to be there. Right. And if we want to modify for example for 1143.04s - 1148.52s | the second issue if we want to modify uh code in SMM for some extra debugging capabilities for 1148.54s - 1154.04s | that we just um injected a firmware implant uh that loads a nice SMM module that allows us to 1154.04s - 1159.02s | do all of that. So the setup looks like this we just have the PCI squirrel connected to our 1159.02s - 1164.02s | target device via an M2 uh adapter and all of this is powered externally by a power supply. So 1166.62s - 1171.36s | it's time to get our hands dirty so let's take a look at how uh the exploit looks like. In the 1171.36s - 1175.86s | first attempt uh we remap the spy bar just like mentioned before over the SMM entry point of 1175.94s - 1182.94s | core zero. Then we tweak uh these values at offset 4D. We create a fake GDT in the beginning 1182.94s - 1187.38s | of the address space uh with the with a nice base address that will allow us when the jump 1187.38s - 1193.72s | happens to redirect execution to our own payload. And then when we uh execute the SMM entry 1193.72s - 1199.10s | point code with TCLs enabled what's going to happen is uh the old GDT is actually going to 1199.10s - 1204.84s | load the GDT register uh with a value that points to our own fake GDT so that's great. And 1204.84s - 1209.12s | afterwards when the jump happens a descriptor from the fake GDT is going to be taken that we 1209.12s - 1214.12s | control um and it's going to be used as a base uh for the jump. So and um this is going to 1218.26s - 1223.94s | redirect execution like this at least in theory. So um an interesting detail is actually how 1223.94s - 1228.94s | we pick the base address in the GDT descriptor um and for that we have to understand how it 1229.68s - 1234.68s | normally executes and how it executes with TCLs in this


chunk_id: 166_chunk_22
chunk_text:
a fake GDT in the beginning 1182.94s - 1187.38s | of the address space uh with the with a nice base address that will allow us when the jump 1187.38s - 1193.72s | happens to redirect execution to our own payload. And then when we uh execute the SMM entry 1193.72s - 1199.10s | point code with TCLs enabled what's going to happen is uh the old GDT is actually going to 1199.10s - 1204.84s | load the GDT register uh with a value that points to our own fake GDT so that's great. And 1204.84s - 1209.12s | afterwards when the jump happens a descriptor from the fake GDT is going to be taken that we 1209.12s - 1214.12s | control um and it's going to be used as a base uh for the jump. So and um this is going to 1218.26s - 1223.94s | redirect execution like this at least in theory. So um an interesting detail is actually how 1223.94s - 1228.94s | we pick the base address in the GDT descriptor um and for that we have to understand how it 1229.68s - 1234.68s | normally executes and how it executes with TCLs in this case. So um when the 4 jump happens um 1238.76s - 1244.12s | and the normal execution what happens is the GDT register is going to point to GDT within 1244.12s - 1248.66s | SMRAM where it's nicely protected. Um and the segment selector is going to index into that 1248.66s - 1254.16s | table um and the base is going to be actually fixed to zero. Which means with a base of zero 1254.16s - 1259.90s | and we add it uh to the 4 jump offset what's going to happen is the linear address is going to 1259.90s - 1265.40s | be the same. Now in our case actually we have a bit of an issue. We want to read the the 1265.40s - 1270.42s | execution um outside of TSEG. The only problem is that within the first 4 gigs of memory 1273.02s - 1277.98s | after TSEG there's not really any spot where we can put a payload right? So if we increase the 1277.98s - 1282.06s | base a little bit sure the instruction pointer is going to go a bit more up up up up and the 1282.06s - 1287.80s | address space we


chunk_id: 166_chunk_23
chunk_text:
case. So um when the 4 jump happens um 1238.76s - 1244.12s | and the normal execution what happens is the GDT register is going to point to GDT within 1244.12s - 1248.66s | SMRAM where it's nicely protected. Um and the segment selector is going to index into that 1248.66s - 1254.16s | table um and the base is going to be actually fixed to zero. Which means with a base of zero 1254.16s - 1259.90s | and we add it uh to the 4 jump offset what's going to happen is the linear address is going to 1259.90s - 1265.40s | be the same. Now in our case actually we have a bit of an issue. We want to read the the 1265.40s - 1270.42s | execution um outside of TSEG. The only problem is that within the first 4 gigs of memory 1273.02s - 1277.98s | after TSEG there's not really any spot where we can put a payload right? So if we increase the 1277.98s - 1282.06s | base a little bit sure the instruction pointer is going to go a bit more up up up up and the 1282.06s - 1287.80s | address space we don't really have DRAM over there that we control. So we wondered okay what 1287.80s - 1292.80s | happens if we actually increase the base such that when we uh the base of the GDT descriptor 1296.08s - 1301.08s | such that when we add it to the 4 jump offset it actually overflows. Um yeah it just 1303.54s - 1308.28s | overflows. So we thought okay this isn't going to be possible but actually it was. And this is 1308.28s - 1313.38s | nice because uh if we choose the base sufficiently big and we add the offset we can actually 1313.38s - 1316.42s | make it wrap around and make it jump to our own payload in the beginning of the physical 1316.42s - 1320.58s | address space. The beginning of the physical address space we have DRAM there. Great we 1320.58s - 1326.66s | control all of that. So uh that was one of the key takeaways actually that we had from the 1326.66s - 1333.00s | research as well. So this worked our payload actually ran and we saw this because it would 1333.00s - 1337.24s | write a value this nice checkpoint to our bar


chunk_id: 166_chunk_24
chunk_text:
don't really have DRAM over there that we control. So we wondered okay what 1287.80s - 1292.80s | happens if we actually increase the base such that when we uh the base of the GDT descriptor 1296.08s - 1301.08s | such that when we add it to the 4 jump offset it actually overflows. Um yeah it just 1303.54s - 1308.28s | overflows. So we thought okay this isn't going to be possible but actually it was. And this is 1308.28s - 1313.38s | nice because uh if we choose the base sufficiently big and we add the offset we can actually 1313.38s - 1316.42s | make it wrap around and make it jump to our own payload in the beginning of the physical 1316.42s - 1320.58s | address space. The beginning of the physical address space we have DRAM there. Great we 1320.58s - 1326.66s | control all of that. So uh that was one of the key takeaways actually that we had from the 1326.66s - 1333.00s | research as well. So this worked our payload actually ran and we saw this because it would 1333.00s - 1337.24s | write a value this nice checkpoint to our bar buffer but the system would crash and we 1337.26s - 1342.00s | wondered okay why is this happening? Um the reason was the SMM safe state. So like Enrique 1342.00s - 1347.20s | mentioned when a CPU goes to SMM mode it actually saves the current register state into the uh 1347.20s - 1354.02s | SMM safe state. When it returns it just restores it. What happens is when TCLs is enabled 1354.02s - 1359.08s | actually the writes when the core enters SMM are going to be discarded. Which means when we 1359.08s - 1364.36s | return with TCLs disabled actually it's just going to use stale values that were still there 1364.38s - 1369.16s | that were stored before. And to resolve this the trick is actually pretty straight forward. 1369.16s - 1375.66s | We trigger the SMM twice. One time um without TCLs and the second time with TCLs. So we first 1375.66s - 1382.60s | put the core zero into a known controlled state and then trigger an SMI without TCLs. This 1382.60s - 1387.70s | is going to prime the SMM safe state and afterwards when we trigger the bug with TCLs 1387.70s - 1392.74s


chunk_id: 166_chunk_25
chunk_text:
buffer but the system would crash and we 1337.26s - 1342.00s | wondered okay why is this happening? Um the reason was the SMM safe state. So like Enrique 1342.00s - 1347.20s | mentioned when a CPU goes to SMM mode it actually saves the current register state into the uh 1347.20s - 1354.02s | SMM safe state. When it returns it just restores it. What happens is when TCLs is enabled 1354.02s - 1359.08s | actually the writes when the core enters SMM are going to be discarded. Which means when we 1359.08s - 1364.36s | return with TCLs disabled actually it's just going to use stale values that were still there 1364.38s - 1369.16s | that were stored before. And to resolve this the trick is actually pretty straight forward. 1369.16s - 1375.66s | We trigger the SMM twice. One time um without TCLs and the second time with TCLs. So we first 1375.66s - 1382.60s | put the core zero into a known controlled state and then trigger an SMI without TCLs. This 1382.60s - 1387.70s | is going to prime the SMM safe state and afterwards when we trigger the bug with TCLs 1387.70s - 1392.74s | enabled the code is going to go for the same execution path and is just going to reuse the 1392.76s - 1399.60s | values that we stored before. So that worked but unfortunately it crashed again. But this 1399.60s - 1404.70s | time around we did see actually that the uh the core zero was returning from SMM so that was 1404.70s - 1409.78s | great. We had full control of core zero. OS code was running. We saw our checkpoints. Great. 1409.78s - 1415.68s | But no matter what we tried this damn thing was still crashing. Um so we spent an eternity 1415.68s - 1421.56s | debugging this thing until we stumbled into this. When we enable TCLs what happens is we 1421.58s - 1427.32s | enable it on core zero only but actually it gets enabled on both cores. Core zero and core 1427.32s - 1432.78s | one. Um and we found that the culprit for this is symmetric multithreading. So this is AMD's 1432.78s - 1437.56s | implementation of Intel hyperthreading. Um and what it does is it divides a physical core 1437.56s - 1442.26s | into two logical cores. And some of the resources


chunk_id: 166_chunk_26
chunk_text:
| enabled the code is going to go for the same execution path and is just going to reuse the 1392.76s - 1399.60s | values that we stored before. So that worked but unfortunately it crashed again. But this 1399.60s - 1404.70s | time around we did see actually that the uh the core zero was returning from SMM so that was 1404.70s - 1409.78s | great. We had full control of core zero. OS code was running. We saw our checkpoints. Great. 1409.78s - 1415.68s | But no matter what we tried this damn thing was still crashing. Um so we spent an eternity 1415.68s - 1421.56s | debugging this thing until we stumbled into this. When we enable TCLs what happens is we 1421.58s - 1427.32s | enable it on core zero only but actually it gets enabled on both cores. Core zero and core 1427.32s - 1432.78s | one. Um and we found that the culprit for this is symmetric multithreading. So this is AMD's 1432.78s - 1437.56s | implementation of Intel hyperthreading. Um and what it does is it divides a physical core 1437.56s - 1442.26s | into two logical cores. And some of the resources on these logical cores are shared and some 1442.26s - 1447.30s | of them are not. So for instance the SMM base MSR is separate so every logical core has a 1447.34s - 1452.34s | different base MSR. But the TSEC mask is actually shared which is what we just saw. Right? And 1455.68s - 1460.68s | we wondered is this the actual issue because we assume when an SMI gets triggered that only 1460.68s - 1466.50s | one core goes into SMM at a time. And we put this to the test and what we saw is the 1466.50s - 1472.40s | following. When we have multiple cores running in normal mode so outside of SMM um when we 1472.58s - 1478.04s | when one of them triggers an SMI an interrupt gets asserted on all of the cores. And all of 1478.04s - 1481.82s | the cores are going to go into SMM mode and going to start executing the SMM entry point 1481.82s - 1486.82s | codes um for uh for each and one of them. So our assumptions were actually wrong. Right? We 1489.32s - 1493.76s | assume the SMIs are local but they're actually not.


chunk_id: 166_chunk_27
chunk_text:
on these logical cores are shared and some 1442.26s - 1447.30s | of them are not. So for instance the SMM base MSR is separate so every logical core has a 1447.34s - 1452.34s | different base MSR. But the TSEC mask is actually shared which is what we just saw. Right? And 1455.68s - 1460.68s | we wondered is this the actual issue because we assume when an SMI gets triggered that only 1460.68s - 1466.50s | one core goes into SMM at a time. And we put this to the test and what we saw is the 1466.50s - 1472.40s | following. When we have multiple cores running in normal mode so outside of SMM um when we 1472.58s - 1478.04s | when one of them triggers an SMI an interrupt gets asserted on all of the cores. And all of 1478.04s - 1481.82s | the cores are going to go into SMM mode and going to start executing the SMM entry point 1481.82s - 1486.82s | codes um for uh for each and one of them. So our assumptions were actually wrong. Right? We 1489.32s - 1493.76s | assume the SMIs are local but they're actually not. And we thought that this was actually the 1493.76s - 1499.36s | case because the indicate two code has a so called rendezvous routine which will every time 1499.36s - 1503.96s | you enter into SMM this routine is going to be triggered. And that core which entered into 1503.96s - 1510.54s | SMM will send an explicit interprocessor interrupt to all of the logical cores to explicitly 1510.54s - 1515.58s | pull them from whatever state they were in into SMM. And well what's the point of that if 1515.58s - 1519.88s | actually all the cores always go into SMM anyway right? Um and we dug a little bit deeper 1519.88s - 1524.76s | into the documentation and we found that the IO hub seems to be responsible for this to uh 1524.76s - 1529.76s | basically assert this interrupt on all of the cores so we're out of luck. So to summarize we had 1532.70s - 1538.14s | all cores always going into SMM and T-Cores being enabled on two cores at the same time and 1538.14s - 1543.84s | not just one as we initially thought. And this will actually make just core one go haywire.


chunk_id: 166_chunk_28
chunk_text:
And we thought that this was actually the 1493.76s - 1499.36s | case because the indicate two code has a so called rendezvous routine which will every time 1499.36s - 1503.96s | you enter into SMM this routine is going to be triggered. And that core which entered into 1503.96s - 1510.54s | SMM will send an explicit interprocessor interrupt to all of the logical cores to explicitly 1510.54s - 1515.58s | pull them from whatever state they were in into SMM. And well what's the point of that if 1515.58s - 1519.88s | actually all the cores always go into SMM anyway right? Um and we dug a little bit deeper 1519.88s - 1524.76s | into the documentation and we found that the IO hub seems to be responsible for this to uh 1524.76s - 1529.76s | basically assert this interrupt on all of the cores so we're out of luck. So to summarize we had 1532.70s - 1538.14s | all cores always going into SMM and T-Cores being enabled on two cores at the same time and 1538.14s - 1543.84s | not just one as we initially thought. And this will actually make just core one go haywire. 1543.84s - 1548.02s | Right? We have control of core zero but core one is uh just going to go nuts and crash the 1548.02s - 1553.02s | whole system. So to tackle the problem we had to get control of core one some way. Uh and we 1555.76s - 1560.86s | dug deep into our bag of tricks to really uh see if maybe there's a nice elegant solution to 1560.86s - 1565.86s | this to just take core one out of the running. Um so we tried to um we tried to find another 1569.10s - 1574.18s | device to overlap with the entry point of core one. There was none. Uh we tried to disable 1574.18s - 1580.72s | SMT and the BIOS that also didn't work. We tried to uh use the so called init IPI and also 1580.74s - 1586.68s | the SKN instruction to put core one into a state that would actually make it ignore SMIs. That 1586.68s - 1592.08s | also didn't work. And finally we also tried to send a so called SMI IPI which at least 1592.08s - 1597.20s | according to the documentation would allow us to trigger an


chunk_id: 166_chunk_29
chunk_text:
1543.84s - 1548.02s | Right? We have control of core zero but core one is uh just going to go nuts and crash the 1548.02s - 1553.02s | whole system. So to tackle the problem we had to get control of core one some way. Uh and we 1555.76s - 1560.86s | dug deep into our bag of tricks to really uh see if maybe there's a nice elegant solution to 1560.86s - 1565.86s | this to just take core one out of the running. Um so we tried to um we tried to find another 1569.10s - 1574.18s | device to overlap with the entry point of core one. There was none. Uh we tried to disable 1574.18s - 1580.72s | SMT and the BIOS that also didn't work. We tried to uh use the so called init IPI and also 1580.74s - 1586.68s | the SKN instruction to put core one into a state that would actually make it ignore SMIs. That 1586.68s - 1592.08s | also didn't work. And finally we also tried to send a so called SMI IPI which at least 1592.08s - 1597.20s | according to the documentation would allow us to trigger an SMI on individual cores. And it 1597.20s - 1601.96s | also didn't work. So despite the documentation indicating one thing in practice we didn't 1601.96s - 1607.00s | manage to uh get it to work. So we're running out of options and we had to take a step back 1607.02s - 1611.56s | and analyze the problem. And we realized okay the LGDT is the actual problem because it's 1611.56s - 1616.56s | going to be load loading the GDT register with all Fs. Right? So is this is there maybe some way 1619.06s - 1625.24s | we can actually still take advantage of this? Um so when the SMM entry point normally 1625.24s - 1629.24s | executes what happens with the GDT register is it's going to be ordered with a nice value for 1629.24s - 1635.64s | the base. It's going to be pointing to the GDT within uh SMRAM. Right? And afterwards the 1635.66s - 1641.30s | segment selector is going to be taken, added to it uh and the base within that uh 1641.30s - 1648.24s | descriptor is going to be used to calculate the final linear address. Now in our case what's 1648.24s -


chunk_id: 166_chunk_30
chunk_text:
SMI on individual cores. And it 1597.20s - 1601.96s | also didn't work. So despite the documentation indicating one thing in practice we didn't 1601.96s - 1607.00s | manage to uh get it to work. So we're running out of options and we had to take a step back 1607.02s - 1611.56s | and analyze the problem. And we realized okay the LGDT is the actual problem because it's 1611.56s - 1616.56s | going to be load loading the GDT register with all Fs. Right? So is this is there maybe some way 1619.06s - 1625.24s | we can actually still take advantage of this? Um so when the SMM entry point normally 1625.24s - 1629.24s | executes what happens with the GDT register is it's going to be ordered with a nice value for 1629.24s - 1635.64s | the base. It's going to be pointing to the GDT within uh SMRAM. Right? And afterwards the 1635.66s - 1641.30s | segment selector is going to be taken, added to it uh and the base within that uh 1641.30s - 1648.24s | descriptor is going to be used to calculate the final linear address. Now in our case what's 1648.24s - 1652.10s | going to happen with tick codes is enabled uh the GDT register is going to be ordered with 1652.10s - 1658.48s | all Fs. Both the limits and the base. And what's going to happen then is when the file 1658.48s - 1663.28s | jump the segment selector is going to be added to it and once again we have our good old 1663.30s - 1669.66s | friends integer overflow. It's actually going to result in the physical address 7. And this is 1669.66s - 1673.94s | actually awesome because address 7 in the physical address space once again that's DRAM. We 1673.94s - 1679.18s | control DRAM. So we can take advantage of that. We can put our GDT at the beginning of DRAM 1679.18s - 1685.52s | and we can just overflow this thing like this. And afterwards uh from the GDT we control we 1685.52s - 1691.72s | set a nice base so that afterwards uh the code jumps wherever we want it to. So to summarize 1691.72s - 1695.66s | we have two types of wraparounds. One is between the GDT descriptor base and the file jump 1695.66s - 1701.10s | offset. And the


chunk_id: 166_chunk_31
chunk_text:
1652.10s | going to happen with tick codes is enabled uh the GDT register is going to be ordered with 1652.10s - 1658.48s | all Fs. Both the limits and the base. And what's going to happen then is when the file 1658.48s - 1663.28s | jump the segment selector is going to be added to it and once again we have our good old 1663.30s - 1669.66s | friends integer overflow. It's actually going to result in the physical address 7. And this is 1669.66s - 1673.94s | actually awesome because address 7 in the physical address space once again that's DRAM. We 1673.94s - 1679.18s | control DRAM. So we can take advantage of that. We can put our GDT at the beginning of DRAM 1679.18s - 1685.52s | and we can just overflow this thing like this. And afterwards uh from the GDT we control we 1685.52s - 1691.72s | set a nice base so that afterwards uh the code jumps wherever we want it to. So to summarize 1691.72s - 1695.66s | we have two types of wraparounds. One is between the GDT descriptor base and the file jump 1695.66s - 1701.10s | offset. And the second one between the GDT register base and the file jump segment 1701.10s - 1707.54s | selector. And the nice thing about this is we can actually reuse the same fake GDT for both 1707.54s - 1715.42s | core zero and core one. And the added bonus is we don't even need the spy bar anymore. The 1715.42s - 1719.90s | only thing that we really have to take care of is the SMM safe state once again for core one. 1719.90s - 1725.58s | For core zero we just do the same thing as before. But core one is going to be running in some 1725.58s - 1729.62s | unknown state. It could be running in ring three, ring zero, just in an unknown context. We 1729.62s - 1734.08s | have to bring it to the same controlled state as core zero. And we do so by using a kernel 1734.08s - 1739.32s | synchronization API. Which on Windows is the deferred procedure call. Or on Linux uh 1739.32s - 1745.80s | symmetric multiprocessing. And basically once that's done uh we have both cores in a known 1745.80s - 1751.60s | state. And we can use the same trick


