Episode 28: In this episode of Critical Thinking - Bug Bounty Podcast, the CSRF’s up, dude! We kick off with a debate about whether or not deep link vulns in mobile apps can be considered CSRF. We also talk browser extensions and tools like Hackbar, PwnFox, and JS Weasel, and Justin tries to invent a whole new vuln term. There’s plenty of good stuff here, so what are you waiting for? Jump on in!
Follow us on twitter at: @ctbbpodcast
We're new to this podcasting thing, so feel free to send us any feedback here: info@criticalthinkingpodcast.io
Shoutout to YTCracker for the awesome intro music!
------ Links ------
Follow your hosts Rhynorater & Teknogeek on twitter:
https://twitter.com/0xteknogeek
https://twitter.com/rhynorater
rez0's latest tip
https://twitter.com/rez0__/status/168134822190014466019
Hackbar
https://addons.mozilla.org/en-US/firefox/addon/hackbartool/
PwnFox
https://twitter.com/adrien_jeanneau/status/1681364665354289152
JS Weasel
Charlie Eriksen
https://twitter.com/CharlieEriksen
Link to talk by Rojan
https://twitter.com/uraniumhacker/status/1681381857383030785
Bypassing GitHub's OAuth flow
https://blog.teddykatz.com/2019/11/05/github-oauth-bypass.html
Great SameSite Confusion
https://jub0bs.com/posts/2021-01-29-great-samesite-confusion/
Check out Nahamsec's Channel
https://www.youtube.com/c/nahamsec
Timestamps:
(0:01:45) The deep link debate
(00:08:00) LHE and in-person interviews
(00:09:25) SQLMAP and raw requests
(00:11:11) Hackbar, PwnFox, and browser extensions
(00:16:45) JS Weasel tool and its features
(00:25:28) Rojan's Research and Public Talks
(Start of main content)
(00:28:36) Cross-Site Request Forgery (CSRF)
(00:35:00) Bypassing GitHub's OAuth flow
(00:45:00) A Small SameSite Story
(00:48:50) CSRF Exploitation Techniques
(01:07:15) CSRF Bug Stories
(01:15:30) NahamSec and DEFCON
Justin Gardner (@rhynorater) (00:01.073)
No, Joel, you're sitting, man. This is, this is, if we're gonna, if we're gonna debate this, you need to stand up. Like, get the, oh, that is good looking, man. You get a new chair?
Joel Margolis (teknogeek) (00:06.078)
Okay, I just wanted to show off my new headrest, that's all.
Yeah. No, no, same chair, so... Oh my god, sorry, I have something in my mouth.
Justin Gardner (@rhynorater) (00:15.953)
Yeah, sorry, I started it like right as you put something into your mouth. But what is it like car caramel or something like that? You're chewing like a maniac.
Joel Margolis (teknogeek) (00:19.678)
Yeah, so, um, yeah, it's like a, it's a chewy, it's a ginger thing. Anyways, anyways, um, this company Atlas, they make like the Herman Miller, like third party headrests and the embody headrest has been in like pre-orders for like six months. So I ordered mine back in December and it finally came like a week or two ago. So it's been like a huge, nice improvement to an already amazing chair. So yes, but that, that's it. I'll, I'll stand up.
Justin Gardner (@rhynorater) (00:33.444)
Mm-hmm.
Justin Gardner (@rhynorater) (00:47.913)
All right, that's like the geekiest thing I've ever, you pre-ordered a headset or a headrest for your chair. There we go. Now let's rise and let's debate, okay? So, all right, so you say, so before we ran the live recording, Joel was saying there's no such thing as a C-Surf on mobile. I suspect this is a terminology difference, but yeah, all right. So here's what it is, all right? C-Surf on mobile.
Joel Margolis (teknogeek) (00:58.092)
Alright.
Justin Gardner (@rhynorater) (01:16.733)
Let's say, for example, we talked about this sort of on the mobile episode. It's like a deep link or like a, what are they called? The app links that you can trigger that will trigger some sort of functionality in the app. So for example, if I can craft a link that has, I've seen this before, has a base64 encoded, you know.
data blob in it and that file gets like downloaded and put onto the user's device or something like that And you know that that's not the perfect most perfect example. Maybe it's something on the lines of like add friend You know equals one two three four and then like when you click that link you automatically send them a friend request, right? I feel like that's a mobile see surf. Is that not?
Joel Margolis (teknogeek) (02:02.626)
I mean, so like yes and no, I think to some extent, you could count that as a C surf, but it's not really. Like in the classical sense, if you think about what a C surf is, like a C surf is a cross site request forgery, right? And so.
Justin Gardner (@rhynorater) (02:09.321)
Why?
Justin Gardner (@rhynorater) (02:14.297)
Okay, okay Joel, like it's not a site, come on, but it's an app.
Joel Margolis (teknogeek) (02:17.71)
Well, yeah, but it's not a site, but it's also like, there is no restriction that you can put in place to like stop this. Like if you click a deep link, for example, like you said, if I click a deep link from my browser, nothing that gets passed through tells the app that I clicked that from attacker.com. And
Justin Gardner (@rhynorater) (02:35.249)
Okay, okay, but like you could just not write functionality where someone can have a deep link that does something in the app Unvalidated like there should be a screen that pops up and says are you sure you want to add? You know Jimmy Jim as a friend
Joel Margolis (teknogeek) (02:50.33)
Uh yeah, sure, but like how do you detect that?
Justin Gardner (@rhynorater) (02:53.661)
Well, no, there's no detection that's needed.
Joel Margolis (teknogeek) (02:55.426)
No, yeah, exactly. So like the reality is that like, if you don't want this to be a thing, it has to be not exposed at all. Like that functionality cannot exist, right? If you want for somebody to be able to add a friend, either you have to have a separate route that is exposed, that's like add a friend confirm. And then like when they click that, then the app does different functionality where they confirm it explicitly. But the fact that deep link exists means that it will always be reachable if it's exposed. So either it can't be exposed or you have to
Justin Gardner (@rhynorater) (03:04.879)
I see what you're saying.
Joel Margolis (teknogeek) (03:25.194)
You know, or it either is or it isn't, right?
Justin Gardner (@rhynorater) (03:25.969)
Okay, so what you're saying is like, even though that functionality, you're saying there's no way to make that functionality secure if you wanna have that functionality. Is that what you're saying?
Joel Margolis (teknogeek) (03:39.038)
Yeah, and so I think like the caveat to this and the bug that I picked as like an example for this, I think the best caveat I can think of is like JavaScript bridges. So that's like kind of the closest you can get to like a CSRF type of behavior where say like within a browser, within a web view, within the app, you are able to either call out to a different internal only URL schema or a JavaScript bridge or something like that to...
Justin Gardner (@rhynorater) (04:03.797)
JavaScript, yeah, or JavaScript object. Mm-hmm.
Joel Margolis (teknogeek) (04:07.566)
trigger functionality within the app from an attacker website, that is something that you can stop. You can detect origin and stuff from a JavaScript bridge, you can do all that kind of stuff, but if, you know, it's just the fact that the deep link exists and is callable externally, I wouldn't really call that a CSRF so much as an abusive intended functionality because it's not like blockable.
Justin Gardner (@rhynorater) (04:26.385)
Okay, so maybe that's my web brain trying to apply it to mobile. That's the way that I've categorized it in my head to try to get it to fit into my little context. So I could see that. But I am a little disappointed though, because I definitely wanted there to be CARF cross app request forgery. I feel like CARF, we could just like, can you make that a vulnerability? Okay, is that a real thing?
Joel Margolis (teknogeek) (04:39.035)
Yeah.
Joel Margolis (teknogeek) (04:49.99)
Yeah. Okay. So like that kind of exists too. I mean, like, yeah. So, yeah. So I think like, that's also a thing, for example, like intents, right? If like you create an intent from a third party app and you call an intent, like that's going cross app, but you know, and you can stop that stuff just like you came with the CSRF, but
Justin Gardner (@rhynorater) (04:59.095)
Right, right.
Justin Gardner (@rhynorater) (05:06.902)
Do you remember that bug from Hollyfield in LA? That was, I feel like that's kind of like a carf, am I right?
Joel Margolis (teknogeek) (05:15.53)
Yeah, yeah, I would say that that's pretty, that's like a pretty good example of like a cross app request forgery, a carf. Yeah. If you want to call it that, um, where it's basically, yeah.
Justin Gardner (@rhynorater) (05:21.777)
Yeah, Akarff. Dude, all right, dude. Just came up with a new vulnerability name right here.
Joel Margolis (teknogeek) (05:27.326)
Yeah, yeah, it's I mean, it's basically and now I think it's a really common exploitation scenario with within mobile apps and it totally breaks CVSS because it's like local only because like you need another app on the system for it to be exploitable. But, but yeah, no, that's like a really common thing where you have some functionality that's, you know, accessible from other apps on the system that is then exploitable to do all sorts of different functionality that I mean, we've seen full RCE from that. So,
Justin Gardner (@rhynorater) (05:32.605)
Yeah.
Justin Gardner (@rhynorater) (05:39.441)
Yeah, yeah.
Justin Gardner (@rhynorater) (05:56.875)
Yeah, where's?
Joel Margolis (teknogeek) (05:57.164)
You can go anywhere from super basic stuff to full RCE.
Justin Gardner (@rhynorater) (06:02.325)
Where's our notes on the mobile episode? Because isn't there like, so like for example, if you're doing like a carf, right? And you need to craft like an intent, there are the intent URLs though, right? That you can like almost embed it into a URL and it like still sends the intent.
Joel Margolis (teknogeek) (06:19.658)
Yeah, if I recall correctly, that is no longer supported in Chrome and Chromium. I believe it's an older Android thing, and it's up to implementation, essentially, about whether or not it's supported. But I might be misremembering that.
Justin Gardner (@rhynorater) (06:36.797)
Yeah, I'm looking back through the notes. We'll have to find that and sus it later. All right, cool.
That's our nice little debate to start us off today, whether or not mobile C-surf exists or whether carf is a thing, cross app request. Carf is a thing, man. All right, you know what, that's gonna be, I'm gonna have to go send out a tweet right after this episode, carf is a thing. That's all I'm gonna say. Carf is a thing. Yeah, no context, just carf is a thing. All right, man, let's get back to the news, yeah? All right.
Joel Margolis (teknogeek) (06:52.802)
Yeah, Carp is definitely a thing. Yeah.
Joel Margolis (teknogeek) (07:03.103)
Carve is a thing, no context. Cool.
Joel Margolis (teknogeek) (07:14.12)
Yeah, for sure.
Justin Gardner (@rhynorater) (07:15.421)
Let's see. News is looking, I'm not gonna lie, man. News was a little bit thin this week.
Joel Margolis (teknogeek) (07:22.026)
Yeah, I think it's just stuff's leading up to DEFCON. People are holding their cards close to their chest. They don't wanna let everything fall just yet, but I would recommend within like two weeks, we're gonna have some really crazy amounts of news that we're gonna have to go through.
Justin Gardner (@rhynorater) (07:24.661)
Yeah.
Justin Gardner (@rhynorater) (07:30.429)
I don't doubt that a bit.
Justin Gardner (@rhynorater) (07:37.113)
Yeah, dude, are you gonna try to do like any Joel solo episodes at Def Con you think or at the H1702 event?
Joel Margolis (teknogeek) (07:46.114)
Um, I might. I'm not going to be at DEF CON. I'm only going to be at the H1 event. So, um, we'll see whether or not anybody wants to do like some recording sessions. I'm trying to grab like an extra handheld mic that I can, you know, use as sort of like an interview type thing, um, that I wouldn't feel bad about traveling with. Like this mic I probably wouldn't travel with cause it's expensive and if something happened during travel, I would be very mad at myself. Yes. Yeah.
Justin Gardner (@rhynorater) (07:49.741)
Okay.
Justin Gardner (@rhynorater) (07:56.17)
Yeah, well.
Yeah, that'd be good.
Justin Gardner (@rhynorater) (08:09.629)
Yeah, be very sad. Yeah, no, I believe that, man. I just think the in-person interviews have such a good vibe with Cosmin and with Mystery Guest. We did record two episodes when we were in London. One of them hasn't been cleared for release yet, so we've got an awesome episode in the backlog that you guys are really gonna enjoy. But yeah, I feel like those were sick, so if we can do more of those, that would be really good, I think.
Joel Margolis (teknogeek) (08:24.65)
Mystery, yes. Yeah, that's true.
Joel Margolis (teknogeek) (08:38.41)
Yeah, yeah, I do plan on bringing the recorder. So we'll definitely see hopefully I'll get at least one in there
Justin Gardner (@rhynorater) (08:40.869)
Sweet, I have to set something up. All right, so the first news item on the list today was actually something that Rezo tweeted out like a couple minutes before we started recording. I was like, oh, we should just throw this in there. He says, here's a bookbinding tip that I just learned from TCM Securities YouTube live stream. SQL Map can use the same syntax as Curl. So if you do copy as Curl in any tool, paste it into a terminal, exchange Curl to SQL Map, it just works.
Joel Margolis (teknogeek) (09:10.634)
That's crazy. I built a SQL, SQL map also lets you do like raw request inputs, right? So you can literally just, that's one of my favorite features is you can basically just copy paste a full raw HTTP request into a text file and then you just pipe that into SQL map. Yeah, I think so. And then it just parses it and it will do all the magic. You don't have to set a different flag for cookies or any of that kind of stuff. So yeah, it's awesome.
Justin Gardner (@rhynorater) (09:11.337)
That is sick.
Justin Gardner (@rhynorater) (09:15.355)
It does, yeah.
Same.
Justin Gardner (@rhynorater) (09:23.197)
Yeah, I think it's like dash R.
Justin Gardner (@rhynorater) (09:33.041)
I want to see, I want to say Fuff also does raw request, doesn't it? Rep raw. Yeah, it does. Dash request, file containing the raw HTTP request. I love that, man. That's so helpful.
Joel Margolis (teknogeek) (09:37.866)
I believe it does, yeah.
Joel Margolis (teknogeek) (09:47.882)
Yeah, I mean, it just makes it so much easier for testing when you don't have to look up all the different flags and if you like run it once and something's not working or maybe it looks like it's working but it's not actually working. Just knowing that for sure it's using the exact request that you were using makes it so much easier to do your testing.
Justin Gardner (@rhynorater) (10:01.801)
Mm-hmm. Yeah, and easy to insert insertion points, both in SQL map and FUF. But, you know, it is very convenient when you've got a curl request as well, or when you're, for example, if you're finding an SQL, if you're one of those freaks that finds SQLs via just the freaking inspector tool, then you can right click and copy to curl and then just.
Joel Margolis (teknogeek) (10:26.714)
I will say the first the first SQL injection I ever found was using what is it hack bar the old? Yeah, yeah, the old old. Yeah. Yeah, this is like way back in the day. Yeah hack bar like the Firefox extension
Justin Gardner (@rhynorater) (10:33.609)
Hack, oh no way, dude, hack bar? Oh my gosh. I cannot believe that, man.
Dude, I just got like freaking teleported back to like early college, man. Hack bar, are you serious? Yeah, yeah, I just looked it up. It's still a thing. Seems like they've actually added some pretty cool features to it. That's pretty sick, man. A lot of reviews too, 50,000 plus users. This is a good extension. This is not related to security stuff, but I heard someone on a podcast the other day talk about
Joel Margolis (teknogeek) (10:49.778)
Yeah, hack bar. Yeah, I think that's what it was called, right?
Joel Margolis (teknogeek) (10:56.29)
Yeah.
That's really cool.
Joel Margolis (teknogeek) (11:05.67)
So crazy.
Justin Gardner (@rhynorater) (11:13.081)
marketing a product by buying Chrome extensions for like one cent per user, right? Yeah, so they're buying like, you know, 40,000 plus install apps for like 400 bucks, you know? And it's like, wow, I don't know how you'd even market to it. I guess maybe you'd like do some sort of invasive little pop-up ad thing, you know, push code to it, but I don't know, man.
Joel Margolis (teknogeek) (11:20.78)
Really?
Joel Margolis (teknogeek) (11:39.102)
Yeah, that's really interesting. I wonder if that violates any of the Chrome web store rules, because I know that when you uninstall an extension, there's a report this extension type thing. And I don't actually know if I've ever reported an extension, but I assume they ask for more info about why you're reporting it. So perhaps they're, yeah.
Justin Gardner (@rhynorater) (11:44.604)
Ooh, I wonder.
Justin Gardner (@rhynorater) (11:50.652)
Mmm.
Justin Gardner (@rhynorater) (11:55.561)
Yeah, so what you gotta do is get the Chrome extension, use the Chrome extension to install a service worker on that page and just automatically say no to that. Actually, that's an interesting, I feel like Chrome extensions shouldn't be able to install service workers on specific sites, right? I don't know, I gotta look into Chrome.
Joel Margolis (teknogeek) (12:06.36)
Well, yeah, just take over their computer.
Joel Margolis (teknogeek) (12:21.726)
Yeah, it might be a specific permission, because even when you install one, you have to grant it specific site by site, whatever it's requesting access to. So I do wonder.
Justin Gardner (@rhynorater) (12:29.201)
Yeah, yeah. Okay, yeah, that makes sense. I gotta look into that though. That would be a fun attack vector.
Joel Margolis (teknogeek) (12:35.498)
Yeah, there was this there was this tweet you made today actually, where you were like, I'm so annoyed like when you find an IDOR and your sessions get swapped. So I wrote this JS bookmark that puts a cookie on the TLD of the target. And then I use request highlighter to highlight each browser a different color. And I do that as well, by the way. That's like, that's the easiest way that I have for like
Justin Gardner (@rhynorater) (12:54.163)
Yeah.
Yeah, thank you. That makes me feel a little bit better.
Joel Margolis (teknogeek) (13:00.77)
two-person testing is I have an incognito window and I have a normal window in the same browser and I just, you know, do the request highlighter extension to highlight different colors for those two sessions if it's like really, really complicated and I haven't both open at the same time. But if it's something super straightforward, I'll usually just like copy paste my auth header or whatever it is.
Justin Gardner (@rhynorater) (13:04.437)
Right.
Justin Gardner (@rhynorater) (13:21.725)
Yeah, yeah, so that's what I do. And then a couple people from the freakin' Twitter went on here and were like, yo, there's already extensions to do this.
Joel Margolis (teknogeek) (13:35.149)
Yeah.
Justin Gardner (@rhynorater) (13:35.797)
Apparently one of them is, so there's browser profiles, there's auto chrome, I think is the other one. There's, what was the one that they said? Something hack fox? Yeah, Pone Fox, that's what it is. And actually I clicked on the Pone Fox one, I can't say it. I clicked on the Pone Fox one and it looks pretty sick. Like if you look at the highlighting within that, looks really good. So definitely could be worth using, but you know, if you're using Firefox, yuck.
Joel Margolis (teknogeek) (13:44.866)
Pwn Fox? Pwn Fox, yeah.
Joel Margolis (teknogeek) (14:05.906)
Yeah, yeah, for sure. There's it says that it's.
Justin Gardner (@rhynorater) (14:06.707)
Yeah. What is that, like the.03% of the population that uses freaking Firefox? Same.
Joel Margolis (teknogeek) (14:12.582)
Yeah, way lower than I would have expected. But actually, PoneFox also listened to ReadMe that if you're using Chrome, you can use this NCC group tool called AutoChrome, which does a lot of default setups and stuff. I used to do something very similar to this where I had a shortcut, like an alias in my terminal that I would use to spin up a new...
Justin Gardner (@rhynorater) (14:20.676)
Mm-hmm.
Justin Gardner (@rhynorater) (14:24.603)
Autochrome, yeah.
Joel Margolis (teknogeek) (14:38.062)
Chrome instance that would run without the XSS auditor and would have the proxy args and all that kind of stuff. Nowadays, it's so easy to proxy Chrome. And I really don't want the XSS auditor turned off, if I'm being honest, because that is such... And it's such like a bar in terms of like, if something is getting caught by the XSS auditor, which like you're saying, I don't actually know if it does anything anymore, then...
Justin Gardner (@rhynorater) (14:40.979)
Mm-mm.
Justin Gardner (@rhynorater) (14:52.433)
Mm-hmm. Well, it doesn't do anything anymore. Like, yeah.
Justin Gardner (@rhynorater) (15:04.958)
Yeah.
Joel Margolis (teknogeek) (15:05.706)
I probably don't want to submit that because what's the attack scenario where somebody has XSS Auditor disabled and I'm able to exploit their Chrome or whatever?
Justin Gardner (@rhynorater) (15:13.413)
Yeah, I feel like XSS Auditor got removed. And the only case that I can think of that it actually, I'm not sure if this is XSS Auditor, if it's something else, but is like when you click a link that has target equals blank on it, right? So it's supposed to open up a new tab and that your injection is in that href, right? Then I think it says, no, can't do that.
Joel Margolis (teknogeek) (15:42.294)
Yeah, I was just looking, it's been fully removed as of Chrome 78.
Justin Gardner (@rhynorater) (15:45.201)
Okay. Dude, that's so clutch, man. Like, I do remember for a brief period when that was around, and it's just like, please, like, just please stop. Like, you know that I can bypass you. Like, please just don't make me do it, you know?
Joel Margolis (teknogeek) (15:54.123)
Yeah, yeah, yeah. Yeah.
Yeah, for sure. Hold on one second, my dog's barking, let me let him outside. We can pause here.
Justin Gardner (@rhynorater) (16:02.163)
You're good, you're good man. Yeah.
Justin Gardner (@rhynorater) (18:09.289)
So dude, did you see this JS weasel thing that got released earlier this week?
Joel Margolis (teknogeek) (18:14.41)
didn't see it get released, but I saw it in the notes. And when I clicked into it, I was like really kind of blown away by like, I mean, one, I think I'd like toyed around with something like an idea like this for the longest time, but yeah, yeah. And it's really, really cool to see it pop up. Um, I was like, who created this? And I did like some digging and it was created by Charlie Erickson. Um, he's pretty big in the bug bounty community. I don't.
Justin Gardner (@rhynorater) (18:26.889)
Right. I feel like everyone has.
Justin Gardner (@rhynorater) (18:37.525)
It was Charlie, dude. Yeah.
Joel Margolis (teknogeek) (18:44.098)
I'm sure a lot of people kind of know who he is or have heard his name. He is definitely very active in Bugmany Forum. And yeah, that's where I know him from as well. It looks like he's kind of done a bunch of startup stuff in the past based on his Twitter bio and stuff. I hadn't realized all these companies and stuff that he'd done. So it's a really cool product to see kind of pop up. I would love to try it out. I saw the price and I don't really want to pay that. But...
Justin Gardner (@rhynorater) (18:50.174)
Yeah, that's where I know I'm from.
Justin Gardner (@rhynorater) (19:09.673)
Yeah, dude, I got my hands on it, man. I got my hands on it. I did, yeah. He actually sent me the beta for it like months ago. And I was like, wow, this is sick. Like I gotta talk about this on the podcast. And we decided to hold off at the time because it was just kind of a beta mode. He was gonna do a release around Defcon, but now is the time to talk about it, man. And I have to say, the price is high for sure. Like $1,000 per user per year.
Joel Margolis (teknogeek) (19:13.435)
Oh, did you? Awesome.
Joel Margolis (teknogeek) (19:18.241)
Oh cool.
Justin Gardner (@rhynorater) (19:39.337)
That's pricey, man, that's pricey. And I feel like he kinda needs a freemium of this, you know? Like I feel like he needs to release some part of it that's free and then, you know, or maybe even like a short trial to get you hooked on it because it's hard to take the bite to go straight into a thousand dollar a year product. However, even the beta version that I played around with was pretty freaking sick. Like it was quite good. And he's added a lot of features since then.
the one that kind of blows me away the most, go to the website, right? And go to features in the tab, scroll down and then look at the fetch packed chunks, right? He says, yeah, so I feel like everyone who's ever like deep dived a JavaScript file or anyone who does that on a regular basis will know what this looks like. Essentially, it's a function that will, has a specific like name, it's normally like,
Joel Margolis (teknogeek) (20:21.682)
Oh yeah, I know what this is.
Justin Gardner (@rhynorater) (20:37.977)
it number colon, you know, name, you know, three colon PDF make seven colon XLS. And then there's another block and then there's a dot in that. And then it has a bunch of hashes and then at the end it has dot JS. So just from looking at it, you can clearly see they're loading, they're constructing what a normal JS file looks like with like the hash and then the dash and then the actual name of whatever it is dot JS or whatever, right?
And so I, time and time again, have written scripts to decode this and get me access to these JavaScript files that are being, apparently they're being lazy loaded. That's what the technical term is for that. Like loaded, you know, sort of dynamically on the fly when needed. And so if you never access, you know, the weird admin part of the application that actually loads it, then you'll never actually get the contents of that JS file, you know, in your browser. But JS weasel somehow,
Joel Margolis (teknogeek) (21:20.043)
Yeah.
Justin Gardner (@rhynorater) (21:34.889)
parses the JS code that does this, figures out how to, maybe there's like a common structure to it or something, figures out how to reverse this and auto download those JS files, which is really sick.
Joel Margolis (teknogeek) (21:46.666)
Yeah, it's super interesting. I would be really, really curious to see how good it does, especially with obfuscated and minified JavaScript. I think that's generally the case where I find stuff has the biggest difficulty, just generally like any sort of like parsing tool, whether it's symbol recognition or anything like that. Obfuscated JavaScript generally throws a real big wrench into that. It seems like it was kind of designed.
Justin Gardner (@rhynorater) (21:51.701)
same.
Justin Gardner (@rhynorater) (22:11.209)
I don't see obfuscated JavaScript that much though. I mean, obviously you could just get.
Joel Margolis (teknogeek) (22:15.406)
who like literally just a target I was looking at yesterday uses obfuscated job like obfuscated and minified. Yeah. I thought it was malware at first. I was actually blown away.
Justin Gardner (@rhynorater) (22:19.921)
Are you serious? Oh my gosh dude, that sounds terrible. I thought it was malware. That's good. Yeah, no, I mean, I feel like maybe one in 50 targets that I look at use actual obfuscated JavaScript, which for any of you blue teamers out there, that is a sure fire way to piss off anyone who's trying to hack your app. If there's like, if all of your strings in the app are in hacks, frick you.
Joel Margolis (teknogeek) (22:28.684)
Pfft
Justin Gardner (@rhynorater) (22:49.745)
Like, I hate that. So, yeah. I definitely, I'd like to get my hands on the latest version. I'm kinda, even, you know, with Bug Bounty being my full thing and, you know, pulling in a decent amount each year with money to allocate to tools and stuff like that. I don't know, man. I don't know if it's worth the 1K, but I might see if I can figure out. But I also don't blame him for anchoring high, you know? Like, if the price comes down, then great.
Joel Margolis (teknogeek) (22:50.926)
Yeah. Yeah, a hundred percent.
Joel Margolis (teknogeek) (23:12.631)
Yeah.
Joel Margolis (teknogeek) (23:17.214)
Yeah, I feel like maybe it would be better if he like framed it like, you know, $75 a month or something like that. Because I think what's a thousand divided by twelve? It's $83 a month. Like if it was $83 a month, I might be more willing to click it instead of seeing $1,000 a year per user or something like that. And I totally agree. Like you got to make a profit somehow. Like work isn't free. But I think if you look generally at like the Bug Bounty community and so many tools are free.
Justin Gardner (@rhynorater) (23:25.505)
Yeah.
Justin Gardner (@rhynorater) (23:32.852)
Yeah.
Justin Gardner (@rhynorater) (23:37.786)
Mm-hmm.
Joel Margolis (teknogeek) (23:46.142)
Or have like a trial or something like that. Like there's very few tools that bug bounty hunters pay for and so I think having a Something that's useful like this that you have to pay for and having it at such a high bar Might be difficult to get bug bounty people to get on board with that You could probably sell it for like a quarter of this and get five times as many people signing up
Justin Gardner (@rhynorater) (23:48.031)
Yeah.
Justin Gardner (@rhynorater) (23:51.793)
Yeah, absolutely.
Justin Gardner (@rhynorater) (23:59.626)
Mm-hmm.
Justin Gardner (@rhynorater) (24:03.994)
Yeah.
Justin Gardner (@rhynorater) (24:09.453)
Oh yeah, a lot.
Joel Margolis (teknogeek) (24:10.602)
So there's probably some sort of tweaking he's gonna have to do with that pricing and all that kind of stuff. But in terms of product and functionality and features, this looks really amazing.
Justin Gardner (@rhynorater) (24:15.21)
Mm-hmm.
Justin Gardner (@rhynorater) (24:20.285)
Yeah, dude, I'm excited. I hope the price does come down a little bit because I would definitely use this. There's definitely, you know, product market fit here with, you know, the Burp Suite plugin. And, you know, it's pushing right into this app. That's how it works, by the way, for any of you that aren't at the website. You have a Burp Suite plugin. It shoves everything down to a VS Code plugin that just sucks it all up, beautifies it, adds a bunch of really cool
highlighting and like you know various layers of pulling stuff out of it. Yeah.
Joel Margolis (teknogeek) (24:56.546)
Yeah, it'll beautify it. It'll deal with source maps. It'll deal with obfuscated JavaScript. It'll deal with chunks. Like, so yeah, it's really interesting. It's funny because whenever I do JavaScript audits, I have like my own internal like brain system that I use where like I figured out certain patterns that I notice within obfuscated or minified JavaScript or webpack JavaScript, whatever you want to call it. And those, I'll like use those patterns to identify how stuff is working, but I never...
Justin Gardner (@rhynorater) (25:03.155)
Mm-hmm.
Justin Gardner (@rhynorater) (25:13.395)
Mm-hmm.
Joel Margolis (teknogeek) (25:24.586)
really go further than that. I never end up like writing scripts or stuff. I just like, I see like, yeah, like, so yeah, so like, there's this like one thing that I notice a lot where webpack stuff, they'll often, when stuff gets packed together into one giant file, they'll name all the modules as numbers, like incremental numbers, so that they'll be like, you know, module one, which was actually FS or something is now one, and then there'll be some function called like N.
Justin Gardner (@rhynorater) (25:27.127)
Okay Joel, you've piqued my interest. What are these internal brain patterns?
Justin Gardner (@rhynorater) (25:49.12)
Right.
Joel Margolis (teknogeek) (25:53.774)
and it'll be like N with an argument one. And then you know that it's importing module number one. And so you can search backwards and so you can say, okay, where is the module with one colon? Where is that in the module dictionary? And then you can go and find the source and you can figure out what module is what. And that's kind of like the system that I've always used, but this feels so much cleaner and more organized and more concrete than...
Justin Gardner (@rhynorater) (25:54.881)
I just hate this man.
Justin Gardner (@rhynorater) (25:59.934)
Oh, I know what you're talking about. Yeah.
Justin Gardner (@rhynorater) (26:08.328)
Yeah.
Yeah.
Yeah.
Joel Margolis (teknogeek) (26:19.158)
that and I think it would probably make for a lot less guesswork if it really works the way that it claims it does. So yeah, this is really, really awesome. And I also like that the website looks just like a GitHub product launch. It really does. Yeah. Yeah, exactly.
Justin Gardner (@rhynorater) (26:25.172)
Yeah.
Justin Gardner (@rhynorater) (26:31.621)
Oh, does it really? Let me see. Oh yeah, with the big text, right? With one word, you know, highlighted, it's true. You're not wrong, man. That's a good call. All right, let's see, what else we got? Okay, the only other thing that I really had on the list today was this, like literally right before we started recording.
freaking rogen tweeted out a link to a talk that they had done at Tinder security labs about an RCE in various services via largely via GitHub actions workflows and excluding those, which is like pretty much the most rogen thing I've ever heard in my life, right? Like he always goes after this like out there, you know, bespoke stuff.
And so, yeah, I don't know, did you see this at all? Because I actually didn't get the chance to actually check out the talk. I just clicked through the slides before we launched the pod. Mm-hmm.
Joel Margolis (teknogeek) (27:36.966)
Yeah, I didn't really get to check it out. It's kind of crazy. I don't know if I should say, but maybe we'll cut this out. But I work with Rojan. And he's always doing really amazing research. So it's cool to see some of this go public and see it be talked about sort of on a more public stage than all the internal communications that we have about it. But yeah, I mean, Rojan is obviously a very, very talented hacker. Him and all the other people
Justin Gardner (@rhynorater) (27:44.721)
Yeah. Right.
Justin Gardner (@rhynorater) (27:56.274)
Yeah, for sure.
Joel Margolis (teknogeek) (28:06.882)
that we have on our team are just some of the best like bug bounty folks as well as just hackers as a whole that I know. And so it's really awesome to have them on the team and see them do this kind of research and then you actually get to talk about it publicly at conferences.
Justin Gardner (@rhynorater) (28:21.993)
Yeah, dude, not gonna lie. I'm jealous of y'all's team over there. Rogan hit me up the other day about, wow, this is a while back actually, about an opening on y'all's team, and I was like, shoot, man, like if there's anything to pull me away from freaking full-time Bug Bounty, it would be a full-time research role on that team. And I was like, ugh. So.
Joel Margolis (teknogeek) (28:42.686)
Yep. Yeah. I mean, I was just reading through one of their internal reports today and it's very like, I think you would enjoy it if, you know, there was another opportunity that came up. I think it would be something that would totally be your vibe because it's literally just like hacking. It's just, yeah.
Justin Gardner (@rhynorater) (28:52.938)
guys.
Justin Gardner (@rhynorater) (29:01.129)
Heck man, that sounds awesome. So we'll link this report down in the description for the podcast or these slides and YouTube video talk.
Yeah, should be some really high quality content. Also, I just, I love injecting into the supply chain, right? Rather than doing other stuff, you know, later after the product's been pushed, anything with like dependency confusion, attacking the continuous integration pipeline, all of that stuff, super cool. And I happen to know a couple of other players in the space that are getting ready to launch products or will be launching products within the next year, surrounding this that I think are gonna really be very helpful.
Joel Margolis (teknogeek) (29:40.394)
Yeah, yeah, actually now that I'm looking through all of the slides on this, yes, I did know a little bit about this. Yeah. But seeing the slides and seeing it talked about definitely gives you a lot more context than what I had. So I'm going to have to check out the actual video of the talk later.
Justin Gardner (@rhynorater) (29:44.686)
Yeah.
Yeah.
Justin Gardner (@rhynorater) (29:57.865)
Yeah, for sure. I'll go watch this as well. All right, as we alluded to in the beginning of this episode with our debate, we are talking about Csurf today. And yeah, essentially I feel like Csurf is a vulnerability that a lot of people feel like got deleted with same site cookies and it's just not the case. And there are some stringent conditions that you gotta be on the lookout for.
Joel Margolis (teknogeek) (30:04.971)
Whoa.
Justin Gardner (@rhynorater) (30:27.721)
But I still see this all the time on all levels of hardenedness of target. So I was thinking we'd kind of dive into that today, discuss some techniques that we've seen, just to have some technicalities and see where it takes us.
Joel Margolis (teknogeek) (30:45.142)
Yeah, yeah, 100%.
Justin Gardner (@rhynorater) (30:47.357)
Alrighty, let's see. Okay, so first thing that I kind of wanted to talk about was for any of you that are out there that haven't heard of a C-Surf, let's just go ahead and give a little of a debris for that. That is cross site request forgery. This attack occurs when the victim clicks on the link from the attacker. The attacker has control of the user's browser inside of the page, and the attacker...
somehow, either by doing a window.open or by doing a redirect or submitting an HTML form is able to push the user via redirection to some specific page on the victim application. You know, it could be a get request or it could be a post request. And that request will trigger some sort of functionality in that application and perform some action on behalf of the user since that request is being done with the user's cookies.
And yeah, go ahead.
Joel Margolis (teknogeek) (31:45.346)
Yeah, well, I was just gonna say, I think like the most like basic example that I can think of just going back to like my very, very early security days was bank account. The typical example is that you are using bank.com and there's a transfer endpoint that you can call to transfer money from your account to someone else's account. And if there's a C-Surf there, then another website could force you to call that transfer endpoint using your own cookies in your own session.
Justin Gardner (@rhynorater) (31:52.149)
Yeah.
Justin Gardner (@rhynorater) (31:57.098)
Mm-hmm.
Joel Margolis (teknogeek) (32:14.15)
and transfer money somewhere else. And if there's no CSRF check, then that could happen completely without anybody stopping that. And that's what always made it click for me, is just like, oh, it's you performing actions by yourself, but someone else is causing you to do it implicitly.
Justin Gardner (@rhynorater) (32:20.105)
Yeah, for sure.
Justin Gardner (@rhynorater) (32:28.521)
Yeah, yeah, and dude, I'm pretty sure that example is in literally every piece of C-Surf education literature out there, so I wonder if that ever happened. Like I wonder if the person that created, you know, or invented C-Surf was like, whoa, like, I can make, what if I force the user, let me log into my bank and see if this works, you know, like, and that's like the original write-up, you know, it's like passing around material on the dark web, like.
Joel Margolis (teknogeek) (32:38.312)
Yeah.
Joel Margolis (teknogeek) (32:43.958)
Yeah, like 2002. Yeah, it's like, yeah.
Joel Margolis (teknogeek) (32:51.319)
Yeah.
Justin Gardner (@rhynorater) (32:56.573)
for bank.com you can trigger transfers. I don't know why that's my voice for early day hackers. Like maybe it's, see, yeah, exactly. Like I don't know, but yeah, that would be interesting. Okay, so everything was fine and dandy for years. We were finding C-Surf's as they're affectionately named, left and right. And then one fateful day, the same site cookie.
Joel Margolis (teknogeek) (32:57.038)
Hehehehe
Joel Margolis (teknogeek) (33:03.166)
Hey man, it's me, early 2000s hacker. Heheheheheheheheh!
Justin Gardner (@rhynorater) (33:26.185)
default lax setting was imposed by Chromium, the monster browser that destroys all of our hopes and dreams. And since then, it has been a lot trickier to do that. And the reason for that is that same site cookies are any cookie that's set now is being explicitly set to or implicitly, excuse me, set to...
Joel Margolis (teknogeek) (33:29.783)
Dun dun dun.
Justin Gardner (@rhynorater) (33:50.785)
lack, same site lacks by default. What that means is that there's only a very, there's a very specific set of conditions that must be completed before you can trigger a request to be, with those cookies to be sent. Those conditions are that you have to be making a top level navigation.
So that means that essentially the URL bar up at the top has to be changing in order for those cookies to be sent. It can only be done with a get in a post request. And with the post request, it can only be done within a two-minute window of that cookie being set. That is called the lax plus post sort of caveat. It's a temporary thing. We don't know how long it's going to last. I think it's probably going to last for a while.
fade and fail us.
Joel Margolis (teknogeek) (34:46.314)
Yeah, that's really interesting behavior that it's like, it feels almost very arbitrary that it's a two minute window and that it just kind of works because what happens like after like say that happens in the first five seconds. Okay, what about the other minute and 55 seconds?
Justin Gardner (@rhynorater) (34:53.158)
Yeah.
Justin Gardner (@rhynorater) (34:59.955)
Right.
Yeah, yeah, I think it was just sort of a catch all for very slow loading single sign-on services. So I'm not exactly sure why they chose two minutes arbitrarily, but I do think it's a cool, I think it's a cool technique, and if you can still use it, it's very helpful for this technique. You've probably seen this before, but exploiting that where you...
Joel Margolis (teknogeek) (35:11.51)
Mm-hmm.
Justin Gardner (@rhynorater) (35:29.297)
trigger a login or a re-login, right? And what that will do is get the cookie reset, right? And even if the user's already got an established session, this can be done oftentimes with a get request in a window.open, right? And then once the cookie is reset, that timer's got refreshed, and then you can do a top-level post, which will trigger the C-Surf. So it's very important nowadays, if you're gonna try to find a post-based C-Surf, to have some sort of gadget which will refresh the session, get that cookie reset.
so that you can take advantage of the lax plus post window.
Joel Margolis (teknogeek) (36:03.426)
Yeah, yeah, that's really interesting. I mean, it's not like the biggest blocker, but it is kind of like an additional part of the chain that you now have to be aware of. And I think if you were coming from a more traditional background and you just went to Expo to see us, or if you'd be like, why isn't this working? And I think it's just because like there's new, there's new levels that are now at play here.
Justin Gardner (@rhynorater) (36:22.513)
Yeah, for sure. And so go, do you see this link that I put in there by Teddy Cats, do you see that? Yeah, click on that really quick, we can talk through this one. I think this one's really cool. So I wanna add, so before we jump into that, I'm gonna go ahead and talk about the conditions for the modern conditions, the now conditions for a SCSurf, right? And those are this. The content type must be text plain.
Joel Margolis (teknogeek) (36:28.805)
Yes.
Justin Gardner (@rhynorater) (36:51.537)
xww form URL encoded or multi-part form data. One of those three, right? There might be other ones. I feel like I've seen text slash JSON being used before. NSE surf, I could be wrong about that. And we're not talking about any of this flash stuff that you can do with flash. That's outdated. No one uses that anymore. So it must be one of those three. The request must be a get or a post request.
And it must be a top level navigation. So the URL bar at the top needs to change as a result. And that will result in the cookies being sent under the same site, under the rule of this cruel monarch, the same site cookie. The exception to that is this cool blog post that I linked here, so let's take a look at that.
Joel Margolis (teknogeek) (37:34.611)
Yeah.
Joel Margolis (teknogeek) (37:41.546)
Yeah, this is by Teddy Katz on his blog about GitHub OAuth bypass.
Justin Gardner (@rhynorater) (37:43.561)
Yeah, dude, this guy's rocks.
Justin Gardner (@rhynorater) (37:49.181)
Yeah, so this guy is pretty much exclusively a GitHub hacker as far as I can see. And I just freaking loved this bug. So did you get a chance to see it before the pod or am I preaching to you as well?
Joel Margolis (teknogeek) (38:03.494)
I think I've actually, I feel like I read this a long time ago because I've hacked GitHub since this blog post came out in the years since this has come out. And so I feel like I have seen something along the lines of this, but I don't know if I've read it specifically. So go ahead. You're not totally preaching to a choir here.
Justin Gardner (@rhynorater) (38:08.839)
Yeah.
Yeah.
Justin Gardner (@rhynorater) (38:20.533)
Dude, I feel kind of bad because I do this thing where I go to people's blogs before a life hacking event that are really good at hacking the target that we're gonna hack, and I just read all of them. Very fresh, very fresh in my memory. And twice in 2022, I found Volms and...
Joel Margolis (teknogeek) (38:33.262)
Hehehehe
Justin Gardner (@rhynorater) (38:45.929)
the people that wrote about those, using the techniques from those blogs, and the people that wrote those blogs duped to me. So I got the main report and they got the dupe report. And they're like, bro, I should never have blogged about this. Which is very sad, you know, cause it's like, we do like to see sharing in the community and stuff, but also like, you know, can't, what do they say? Don't hate the player, hate the game, hate the.
Joel Margolis (teknogeek) (38:53.95)
Oh no. You're stealing their techniques. Yeah.
Yeah.
Joel Margolis (teknogeek) (39:12.274)
Yeah, yeah, exactly. Yeah.
Justin Gardner (@rhynorater) (39:13.245)
hate the game, don't hate the player, something like that. All right, so yeah, this specific one, pretty cool. We'll link it, it's called bypassing GitHub's OAuth flow. This is an example of C-Surf that does not use get or post. This is a C-Surf done with a head request, which was really interesting to me. Essentially, the TLDR of this is that the...
the head request gets routed to the same spot in the application. I wanna say this is, is this Rails? Yeah, it's Rails. So the way that the Rails router is defined, it says, you know, match the specific path, and then there's via, and then you provide a list of, you know, valid HTTP verbs. Yeah, thank you, I couldn't come up with it. Yeah, you provide get and post. And then,
Joel Margolis (teknogeek) (39:51.01)
Yeah, it's reals.
Joel Margolis (teknogeek) (40:05.578)
methods you have get, post, et cetera. Yeah.
Justin Gardner (@rhynorater) (40:11.865)
So there's just get and post in this array, in the blog post. But there's also some quirk in Rails where they just want head to kind of work seamlessly. They don't want you to have to be able to, have to like, you know, work on head being something different than get. So head also gets routed to wherever get is routed to. And inside, yeah, I thought so too. And inside the request, it's inside the function that deals with this route.
Joel Margolis (teknogeek) (40:33.762)
That's super interesting.
Justin Gardner (@rhynorater) (40:42.321)
there is this if statement that says if request.get, then do this, right? Otherwise, do that. So it's not checking, you know, it's a pretty safe, to be honest, I would have definitely not caught this in code review because it's like, okay, only get and post are allowed, but, and we've got get, so the only alternative can be post, right? But that's not quite the case. The head method can also,
Joel Margolis (teknogeek) (40:59.949)
Yeah.
Justin Gardner (@rhynorater) (41:10.965)
trigger this and it actually in this case it was triggering the same thing as a post request would do which allowed for the oauth bypass Which landed him a pretty sick back. I think there was a 25k bounty, right? Yeah
Joel Margolis (teknogeek) (41:25.318)
Yeah, yeah, it was. Yeah, that's really interesting. Honestly, I would have expected that a head request would behave more like a get request than a post request. So I would have expected it, if it was going to be an implicit thing like this, it would go through the get handler. But maybe it was actually coming through as like request.head or something. So if you look in the check where it says, if it's request.get, it's a request.head.
Justin Gardner (@rhynorater) (41:34.95)
Exactly.
Justin Gardner (@rhynorater) (41:45.241)
Exactly, it was. Yeah.
Joel Margolis (teknogeek) (41:47.562)
and then else is catching everything else. And so it doesn't even have to be behaving like a post request. It's just if it's not a get request, then it does this alternative behavior, which would be to grant permissions. I wonder if options does the same thing. I assume it probably does, because I had an options are special cases, right? Where those are really meant for the browser to do pre-check requests and that kind of stuff to make sure that the end points exist or are reachable and that kind of stuff, right?
Justin Gardner (@rhynorater) (42:00.752)
Yeah.
Justin Gardner (@rhynorater) (42:12.509)
Yeah, I thought the same thing before I, while prepping for this episode, and I looked into it, and I think options, at least normally, they're sent by the browser without any authentication attached to them. I'll have to double check on that, because this is a while back, but if they are sent with authentication attached to them, that could be a really interesting way to potentially exploit some of this behavior.
Joel Margolis (teknogeek) (42:24.875)
Hmm.
Joel Margolis (teknogeek) (42:36.67)
Yeah, I would imagine that the browser won't be sending it now, but maybe they have to, you know, because maybe like an option or options request would fail if it doesn't have the right authentication on it. I don't really know. But that might be an interesting area to target.
Justin Gardner (@rhynorater) (42:47.486)
Yeah.
for sure. Yeah, so this is also just a good, I feel like this is just a good quirk to, to know about in Rails as well is, is that head will get routed to the same point place that get will. And if there is this sort of, you know, if get else do this sort of mentality, then this bug could very well, I absolutely anticipate that this bug has, is present in other code bases as well.
Joel Margolis (teknogeek) (43:17.662)
Yeah, yeah, I mean, it's gotta be. I can't imagine that.
I mean, Ruby is very, very commonly used and this seems like a strange type of implicit behavior for it to be there. So I wouldn't be surprised if it has other implications. As you can tell in the blog post, this is actually down to how GitHub is implementing it, where it's not really like an implicit vulnerability. It's just that the fact that how they're handling whether or not it's a get request or some other type of request is influencing the behavior of the app. And so...
Justin Gardner (@rhynorater) (43:29.589)
Yeah.
Justin Gardner (@rhynorater) (43:37.568)
Right.
Justin Gardner (@rhynorater) (43:46.217)
Mm-hmm.
Joel Margolis (teknogeek) (43:50.878)
If there's other services that are written in Rails that aren't doing an explicit check for a head or an options or they're doing some sort of fallback behavior like this is, then you'd be able to exploit that in the same way.
Justin Gardner (@rhynorater) (43:59.847)
Hmm.
Yeah.
Yeah, I totally agree. So just as a takeaway, list a couple takeaways here. Rails definitely play around with head requests for that. For CSURF, you need to have content type text plane, XWWForm URL encoded or multi-part. It needs to be get a post or a head likely request and it must be a top level navigation. That's kind of interesting to me though, because this was before, now that I'm saying all of this together,
this was 2019. So I'm wondering if head requests, I'm wondering if that even works anymore because I don't know that you can send a head request via top level navigation. So how would you get the cookie to send?
Joel Margolis (teknogeek) (44:39.758)
Hmm
Joel Margolis (teknogeek) (44:48.662)
Yeah, I wonder, let's see.
Justin Gardner (@rhynorater) (44:49.457)
It might have to be coupled with a, yeah, it might have to be coupled with a, with a like insecure configuration for same site or something like that in order to actually get this to work.
Joel Margolis (teknogeek) (45:01.682)
Yeah, yeah, because when did same-site come out? That was like, yeah, I do see an article from, yeah. Super interesting.
Justin Gardner (@rhynorater) (45:04.169)
It's 2020. February 4th, 2020, stab in the heart, man.
Justin Gardner (@rhynorater) (45:14.125)
Yeah, so those are the takeaways there. Let's talk a little bit about some exploitation techniques and then we'll kind of jump. I mean, do you have anything you want to talk about for mobile CSURF? I'm not sure if you're, or I guess CARF as we affectionately named it.
Joel Margolis (teknogeek) (45:32.47)
Yeah, so a lot of that stuff we talked about during the mobile app episode, but I think generally it's the same kind of stuff that you'd already be looking for. So JavaScript bridges, exposed URL schemas. If there is any kind of internal web view, the non-exposed URL schemas are also a good target for that because if you can find some way to point the internal web view to an arbitrary URL, then you can potentially exploit those internal
Justin Gardner (@rhynorater) (45:34.888)
Yeah.
Justin Gardner (@rhynorater) (45:50.091)
Mm-hmm.
Justin Gardner (@rhynorater) (45:57.823)
Mm-hmm.
Joel Margolis (teknogeek) (46:01.778)
URL schemas that would be only accessible from within the app. And you may be able to escalate that further to do who knows what. But I'll actually talk a little bit about that when we talk about our specific bugs, because the specific bug I have is very similar to that.
Justin Gardner (@rhynorater) (46:15.369)
Sweet, solid, we'll wait for that then. So I wrote down a bunch of exploitation techniques here. Let's just kind of roll through them one by one. Oh, well actually, okay, actually before we get into this section, I do wanna add one more thing about same site. If you have any questions or concerns about same site, definitely check out the Jewbob's post, the great same site confusion, we've talked about it on the pod several times before, really good stuff.
Justin Gardner (@rhynorater) (46:46.873)
So on the note of same site though, there is this thing, same site strict, which is rare, but I actually have seen it and I've got a funny story about it, dude, actually. So did you meet So Sakaguchi? Did you meet one of my friends that was from Japan that I feel like you might've met him in Vegas or in Austin?
Joel Margolis (teknogeek) (47:07.122)
I wasn't at either of the Las Vegas or Austin events. So maybe, no, I was supposed to come, but then I had to cancel last minute because I had a thing happen last year. Yeah. Did you, was he one of the people that flew over and stayed with you? Okay, so yeah, we might have chatted a little bit.
Justin Gardner (@rhynorater) (47:10.771)
You were in Vegas, weren't you?
Justin Gardner (@rhynorater) (47:16.173)
Ah heck man, well you might not have met him then, but I-
Justin Gardner (@rhynorater) (47:24.025)
Yeah, yeah. So he was, we were hacking together. I was, yeah, he's one of my friends from Japan. Um, great hacker now. I was training him, you know, with some stuff and there's this, there's this app that I guess I can't specify. Um,
And it looks very vulnerable to CSURF, right? But here's the thing, it deletes your account and he actually uses the app, right? So I was like, so we caught the request, right? We caught the request in verb and we're like, okay, you know, like, look, there's no.
Joel Margolis (teknogeek) (47:46.347)
Wait.
Justin Gardner (@rhynorater) (47:56.029)
you know, CSRF tokens, there's no origin checks, it doesn't look like there's an origin check, I guess you can't know until you submit it. But you know, it looks good, and we found other bugs that look similar to this in the past on that website. So I was like, okay man, here's the deal, we gotta. We gotta.
We got to just build the POC and give it a shot. Like this is a Several thousand dollar bug here like and oh and the process for creating an account was really long and hard and Had a hat required phone numbers and all sorts of garbage, right? So we can't really just create another So so we run the exploit on his account Fully expecting to be getting you know to cheat hearing cha-ching noises
Joel Margolis (teknogeek) (48:31.111)
Ugh, okay, yeah.
Justin Gardner (@rhynorater) (48:48.27)
And I don't know how it ended up being this way, but they had same site strict, right? So we deleted his account with something else to try to prove it, that the origin check wasn't working. It's like, okay, great, this is good. And we go back to do it again with another account and the same site strict cookies, they have same site strict on, which means that there's that you will never, it will never send a cookie.
to a from one site to another site. There's no, not a get request, not a POT request. It just doesn't happen, right? And so at the end, it wasn't vulnerable to C-Surf. And we deleted his whole account on this app. Yeah, it was so bad. It was on a music app that was popular where he lives. So I felt really bad, man.
Joel Margolis (teknogeek) (49:25.742)
Are you just deleting his whole account? Oh no.
Joel Margolis (teknogeek) (49:33.806)
It's so interesting. Yeah, it's funny because I was actually looking back at, I did have like a really low impact CSRF that I reported like many, many years ago. And it was like, I don't even think I tested it like in the traditional way because same site wasn't a thing. So all I did was check if I set origin to null, then does it work? Yes. And like it redirected me to an arbitrary domain.
Justin Gardner (@rhynorater) (49:43.221)
Mmm.
Justin Gardner (@rhynorater) (49:49.141)
Right.
Justin Gardner (@rhynorater) (49:54.997)
Yeah.
Justin Gardner (@rhynorater) (49:59.687)
Well, if there's no other checks, if there's no referrer check, which can be circumvented, if there's no CSERV tokens in the request, you'd think it would be, you know? All right.
Joel Margolis (teknogeek) (50:08.478)
Right. Yeah. Vulnerable, but not exploitable.
Justin Gardner (@rhynorater) (50:12.381)
Yeah, exploitation techniques. So just a couple things I just wanna note on this. These are just kind of pro tips section on C-Surf. Look at the same site values for your cookies, okay? So one thing that I will notice, Joel, did you just literally just OCD out? What is wrong with you? So literally in the doc, I wrote same site. No, you're getting called out for that, dude. I literally wrote same site with no capitalization and no dash in the middle in the notes. And while we're talking about this,
Joel Margolis (teknogeek) (50:26.954)
No, listen, I'm sorry. Damn, I wasn't expecting to get called out about this.
Joel Margolis (teknogeek) (50:40.95)
It was just one lowercase word, same site.
Justin Gardner (@rhynorater) (50:43.658)
Joel goes in here and capitalizes it and adds the dash like a total maniac.
Joel Margolis (teknogeek) (50:49.486)
I was like, look, now I know that it's, it's same site, not, not same site.
Justin Gardner (@rhynorater) (50:52.953)
now it's same site, not some site, you know? Some site. But yeah, so the tip that I was gonna say with this is make sure you're checking your cookies. Note that same site, if same site is not set, if the same site attribute is not set on a cookie, then that will be same site lax by default, which is different than same site lax explicit, okay? Same site lax when it's explicitly set.
does is not subject to the lax plus post sort of accommodation that they've made for people transitioning because if you're setting it explicitly then you obviously you're not one of the people that's transitioning to a architecture that supports this. So that can be a gotcha. That can get you some NAs or some informatives if you don't check that. So yeah keep an eye on that.
uh... let's
Joel Margolis (teknogeek) (51:47.786)
Yeah, another thing was the method params. I've seen this a lot on Ruby especially There's like a really weird functionality. We're like Yeah, Ruby super weird. I think this is specifically Some like weird rails configuration or something, but there's like a method parameter that you can put in the URL
Justin Gardner (@rhynorater) (51:55.037)
Oh really? Man, Ruby's getting wrecked today.
Justin Gardner (@rhynorater) (52:04.125)
Mm-hmm.
Justin Gardner (@rhynorater) (52:07.602)
Yeah.
Joel Margolis (teknogeek) (52:07.914)
and it will allow you to change the method of your request. Even if it's sent as a get request, you can have it send it as a, like a post request instead. It gets interpreted on the backend as like a post request. And that adds all sorts of different levels of complexity now because you can send a get request with a potty, right?
Justin Gardner (@rhynorater) (52:24.689)
Yeah, I'm not sure if you can make the browser do that though, can you?
Joel Margolis (teknogeek) (52:29.682)
Yeah, I know that's the one caveat is again, it's like vulnerable, but not exploitable where yeah.
Justin Gardner (@rhynorater) (52:34.253)
Yeah, I'm not sure. That would be a kind of interesting area to research because it would be, but I feel like most of the, you know, routing software, most of the web servers would just kind of consider those body, either just delete those body params on a get request.
or just stick them as they were a query parameter. So I'm not sure how that would get parsed. But like you said, there's definitely the option of sending a get request and then setting this method equals post, right? And then having the server parse it as a post request. That's a really good method. Let me grab some water.
Joel Margolis (teknogeek) (52:59.307)
Yeah.
Joel Margolis (teknogeek) (53:19.522)
You're out of water.
Justin Gardner (@rhynorater) (53:20.906)
Yeah, I'm just gonna cough into the mic real quick here. Yeah, this is how we know when we need to wrap up the episodes is like, Justin's out of water, his third is dying. Yeah, so let me look at some of these other... Yeah, so obviously, you know, you want to be looking for any GET-based requests that will result in some change in the application, right? Because if you have that, you're pretty much just set anyway.
unless they're setting some weird header or something like that. So be on the lookout for that. And then the other thing which we alluded to earlier is I feel like, and this is sort of, I'm gonna release something else on the pod about this later, but I...
I feel like not enough people when they look at applications are keeping in mind various gadgets that they need. These are parts of chains. These are links in your chain that you need to find. So for example, if you hack all day and you don't find anything, you can feel like garbage. Or you can look back and you can say, okay, well, now I know that if I go to this specific area of the application, I'll get this error that will tell me, you know...
this about the application, or if I provide a valid ID here and an invalid ID, then it allows me to validate which IDs are valid or not valid. Or I found this endpoint that I can force the user to refresh their session cookie. That's the most applicable in this scenario. Those gadgets are very valuable. So even if you haven't found a bug, make sure you're noting down these gadgets. And if you are, and you're keeping those in the front of your mind, your brain will figure out a way to utilize these and figure out a way to chain these
you know, different bugs. If you're skipping over them, if you're not emphasizing these, then you know, you're never just gonna get the full chain into play. So that's another tip, that sort of gadget-based methodology.
Joel Margolis (teknogeek) (55:13.826)
Yeah, for sure. And we've talked about notes. You need to take notes, just like if you find something that's weird or strange behavior, probably not quite a bug, but could be used with something else to become a bug. IDOR ID leaks, anything like that. If you're using a UUID and you find something at least leaks a list of UUIDs, that's a great thing that you can chain together as a gadget where by itself, maybe it's not the most severe thing. But if you can then find an IDOR that uses that ID, that makes it so much more severe.
Justin Gardner (@rhynorater) (55:16.85)
Yeah.
Justin Gardner (@rhynorater) (55:24.16)
Mm.
Justin Gardner (@rhynorater) (55:41.706)
Yeah.
Joel Margolis (teknogeek) (55:42.23)
So anything that's along those lines, just be keeping notes of the different weird behaviors that you're seeing. And this is about, as we say, becoming intimate with the application. This is part of the process of understanding how does the application work, what are the different moving parts, what are the different functionalities that exist. Is one specific part not secure that can then be used with another specific part that's not secure to then leverage that further?
Justin Gardner (@rhynorater) (55:51.025)
It is man, it is. Mwah.
Joel Margolis (teknogeek) (56:11.714)
Those are the types of things that we really want to look for.
Justin Gardner (@rhynorater) (56:13.693)
Yeah, yeah, for sure. I think, yeah, and so there's lots of different ways that you can approach these.
these vulnerabilities, these applications that you're trying to find. And we're not trying to say everyone needs to take notes, everyone needs to keep in mind the gadgets, but that's something that's definitely worked for me quite a bit in the past and I think it's a helpful methodology. Let's see what else we got here. Okay, well this is an interesting one. So if you, and we've tweeted about this a little bit as well when Rezo mentioned something like this, but one of the main ways that I find CSRF nowadays is servers that are used
using just plain JSON requests. And as we know, JSON as a content type is not vulnerable to cross-site request forgery. However, excuse me.
However, if you change the content type from JSON to text plain or to xww form URL encoded, then it may be vulnerable. It could be that the server is parsing that content type, or if you're sending text plain, it could just consider that as JSON. So those are good areas to check. It normally only takes one or two different checks because...
I guess maybe this is my experience. I won't prime you otherwise, but in my experience, I don't check every single endpoint for this. I check one or two endpoints for this to see if the server actually just at all just does not mess with XWW formula encoded or TextPlane. I don't test all of them, but I could be missing some there. So whatever testing style fits you best, as long as you're checking if you can convert content types.
Joel Margolis (teknogeek) (57:58.038)
Yeah, for sure. I, you know, I think it's, if you think about it from a developer's perspective, it's probably gonna be implemented in like one place. So it's gonna be added as a middleware or a content type handler for the entire server versus being on an endpoint by endpoint basis because usually it's being processed at a lower level than it is like at the route handler. It's probably gonna be on the server level. So I think your testing methodology there probably makes sense to just like see if
Justin Gardner (@rhynorater) (58:06.467)
Mm.
Justin Gardner (@rhynorater) (58:09.786)
Yeah, exactly.
Joel Margolis (teknogeek) (58:26.786)
this host is vulnerable to that type of confusion or changing of types and see if it's flexible in that way of parsing. And then if it's not, I wouldn't waste too much time. I think it's really interesting to think about how CSRF is one of the more like old school type of vulnerabilities because the way that it gets exploited is still using a form element. You know what I mean? It's not like anything crazy. It's not like custom modern JS. It's literally just a form.
Justin Gardner (@rhynorater) (58:30.622)
Mm-hmm.
Justin Gardner (@rhynorater) (58:43.762)
Yeah.
Justin Gardner (@rhynorater) (58:48.045)
Mmm. Yeah. Yep.
Joel Margolis (teknogeek) (58:55.038)
You know, it's just a form HTML element. And so you do get restricted by some of those bounds in terms of how a form element actually works, what capabilities it has, what content type it is, how it encodes data, all that kind of stuff, which is why it needs to be either text plain or form URL encoded because forms don't send JSON. And apps that are sending JSON are typically JavaScript based where you're clicking a button and that's triggering an on click handler, which is then making a fetch request or whatever it is.
Justin Gardner (@rhynorater) (58:55.648)
Yeah.
Justin Gardner (@rhynorater) (59:03.958)
Mm-hmm.
Justin Gardner (@rhynorater) (59:14.867)
Right.
Joel Margolis (teknogeek) (59:24.286)
in the back end that's actually triggering the API request versus sending a very, you know, traditional HTML form.
Justin Gardner (@rhynorater) (59:32.817)
Yeah, yeah, and I like what you said about HTML sort of being limited by.
by old HTML in that capacity, because we do still exploit Csurf via form elements. And I'm looking right now, you can set the content type on a form element using the ENC type attribute and the method, via the method attribute. I'm a little salty because I went and looked into this ENC type attribute the other day, and it would be really cool if we could specify
but the character encoding in here as well, you know, because you could do, because we were looking into, this is a little bit of a rabbit trail, but we were looking into bypassing WAFs, you know, payloads using encoding. I think Sourouche tweeted something out about that. And we were just kind of going back and forth on it. I was like, man, I wonder if we can force the browser to send a request using UTF-7 or something like that, right? And I was thinking, man, that the ENC type should ENC type
should do it and I think even the HTML spec mentions that it should be able to do it but it freaking doesn't do it man it is salty
Joel Margolis (teknogeek) (01:00:46.634)
Well, I mean, this wouldn't be the first time where the HTML spec says one thing and every single thing on the internet says that the spec follows this one thing and it doesn't. So maybe it's worth looking into and actually verifying. Honestly, since that thing that we found with the base element, it really has me wondering how much of HTML is strictly enforced to what the spec says it should be and how much flexibility there is in terms of weird edge cases and stuff like this.
Justin Gardner (@rhynorater) (01:00:55.406)
Yeah.
Justin Gardner (@rhynorater) (01:01:04.083)
Yeah.
Justin Gardner (@rhynorater) (01:01:09.51)
Yeah.
Justin Gardner (@rhynorater) (01:01:14.109)
Yeah, I'm sure there's tons. Just more and more to uncover. So the other, a couple other little things I had here. Obviously, making sure you're.
changing your post request to get request. I pretty much forced Kaido to do that. Because I told them, hey, this is one of the main features I use in burp, this change request functionality. So they did put it into Kaido, which is great. And so converting your post request to your get request makes it really easy to check. And then, so.
The other thing that I kind of wanted to mention was sometimes they'll, companies will do sneaky stuff like check the origin header and check the referr header to ensure, to further see serve checks. And those
Joel Margolis (teknogeek) (01:02:05.026)
Which is technically proper CSRF protection. That plus the CSRF token is really, I believe the recommendation, or at least it was.
Justin Gardner (@rhynorater) (01:02:11.633)
It can be, it can be. There is ways, there are ways to bypass that. So for the origin, and I guess if it's configured properly, there's not ways to bypass it, but for the origin, you can get the origin to be set to null for a request by doing it within a iframe that is the source of that iframe, the source attribute of that iframe is a data.
URI. And that will remove the origin from that iframe and allow you to just run your HTML document that you've defined inside of that data URI inside of there, and then you can try to trigger it that way. I'm wondering now that I'm saying it, because a lot of these techniques are a little antiquated, I'm wondering that isn't going to...
That isn't going to pass the same site checks now though. Right? I don't know. I'm gonna research that.
Joel Margolis (teknogeek) (01:03:13.054)
Right. And with cores, with cores and CSP, you'd also get blocked a lot of the time by not having the right URL or not being able to even open data URLs because of CSP.
Justin Gardner (@rhynorater) (01:03:26.161)
Yeah, I need to look that up and see if there's any way, is there, yeah, I'm gonna research this afterwards, any way to send a request with the null in the origin with nowadays same-site stuff. That's kind of interesting. I sort of didn't apply the same-site stuff in my brain to this technique. So that's that. Perhaps maybe an origin check might be enough nowadays, especially if you are
handling the null case, it would definitely be enough, like you were saying. But if you're not handling the null case, it could still be enough, because the browser may not allow you to do it. The only other one was the referrer, and I was going to say this one. This is not as... Excuse me.
this is not a secure technique for CSURF because we have the ability to control the refer policy, which determines what is set, right? And actually, oh, I didn't even write this down, Joel, but I actually had a cool bug that I found the other day because of this, because what it was doing was it was sending this, gosh, I love this bug. I can't believe I didn't get this in the
So here's what it was. I'm just gonna drop everything and tell you about it right now. So it was a C-Surf. It was a C-Surf, of course. And it was doing the C-Surf check via the refer, right? And so I was like, OK, easy peasy. And all it was doing, it was checking to make sure that site.com slash was in the refer. So I was like, OK, easy peasy.
Joel Margolis (teknogeek) (01:04:49.038)
I want ground breaking.
Joel Margolis (teknogeek) (01:05:08.767)
Mm.
Justin Gardner (@rhynorater) (01:05:10.245)
I should just be able to create a folder called site.com slash and execute my exploit from there. And then that should pass the check, right? Wrong, because you can't, whenever you're sending, they deleted the refer parameter, the paths from the refer parameter nowadays, right? Yeah, so it just sends by default, it just sends HTTPS.
Joel Margolis (teknogeek) (01:05:33.767)
Oh yeah. Oh, interesting.
Justin Gardner (@rhynorater) (01:05:41.5)
the top level, the FQDN slash to cross origin requests.
Joel Margolis (teknogeek) (01:05:45.303)
interesting. I thought that was only for origins. I thought only origin headers did that behavior. I didn't know that referrers... because that was a big problem for a long time where API tokens and stuff would get leaked through a referr header because referr is the exact referr URL, whereas origin would be just the origin URL.
Justin Gardner (@rhynorater) (01:05:48.309)
What do you mean?
Justin Gardner (@rhynorater) (01:05:53.054)
Yeah.
Justin Gardner (@rhynorater) (01:06:04.505)
Exactly. And I think that's the reason why they removed it was because it was lit, because what you could do is you could get an HTML injection with an image tag and then redirect the user to that specific page with their access token and URL, and that access token would get leaked by the referrer to your image that you inject into the page and you're boom, you got an ATO. But anyway, they removed that. And so I bypassed it.
because you can actually set the referrer policy on your own page to send the full URL. It doesn't have to be, you know, since you control the page that you're sending from, you can use it, I think it's a meta tag. You should look that up really quick. See if you can find anything. But the meta tag, I believe, allows you to set the referrer policy. And there are several options for that. One of those is send the full URL in the referrer. And so,
popped that into my page, sent the user to that page, and it sent the full URL, which allowed me to bypass the CSRF check and got the bug. So I don't know, man. That sort of fringe stuff like that just gets my blood pumping, I love it.
Joel Margolis (teknogeek) (01:07:18.446)
Yeah, yeah. So there's actually two ways to do it. There you can set it as a header, refer dash policy with either like no refer, origin, same origin, strict origin, unsafe URL. And then you can also set it with HTML through a meta tag like you thought. Meta, the name is refer and then the content would be like origin, for example.
Justin Gardner (@rhynorater) (01:07:20.886)
Mm-hmm.
Justin Gardner (@rhynorater) (01:07:25.307)
Mm-hmm, okay.
Justin Gardner (@rhynorater) (01:07:39.353)
interesting. Yeah, I think I'm looking at the same page that you are. Man, yeah, the meta, the meta tag is so interesting, dude. Like, because I, yeah, we were kind of deep diving this last time with like, you know, when we were looking into bass and stuff like that. But um,
Joel Margolis (teknogeek) (01:07:42.37)
The Mozilla Ducks.
Joel Margolis (teknogeek) (01:07:48.206)
That's a lot of functionality.
Justin Gardner (@rhynorater) (01:07:57.313)
This doesn't even use the HTTP equiv attribute to pretend like it's an HTTP header, right? This is actually just a different thing. So I gotta go, I gotta find some way to just read everything that a metatag can do because I'm sure there's some weird stuff there.
Joel Margolis (teknogeek) (01:08:05.612)
Right.
Yeah.
Joel Margolis (teknogeek) (01:08:16.954)
Yeah, yeah. And I'm not really sure where the best, like the right place to look either, because I feel like even if we look at the HTML spec, it's not really what you need to look at. It's you should probably look at like the Chrome source code or something like that. Me neither. Yeah, me neither. Cool.
Justin Gardner (@rhynorater) (01:08:26.333)
Yeah.
Dude, I don't wanna look at the Chrome source code, man. That hurts my eyes. Don't like that. All right, so that's, yeah, that's all I had for the actual content of the C surf stuff. Yep, yeah, that's all I had. Yeah, let's do it, man. Okay, so I already presented one bug because I just got hype. I just...
Joel Margolis (teknogeek) (01:08:46.954)
Yeah, me too. You want to go into bugs real quick? Cool.
Justin Gardner (@rhynorater) (01:08:55.909)
I love that man. But this next one is actually really cool too. So this is a C-Surf that I found at a live hacking event in 2022.
And there was this obscure domain that was way out there, right? That, that no, you super old legacy garbage and there's some like weird trickery, I figured out a way to get an account on that domain. Um, there's like a hidden signup page that was like, I found in like a way back archive thing, right? So I got there, got into that app and I'm like seeing dollar signs at this point, right? Cause it's like, it was in scope too. It, they had star in scope. So I was like, wow, this is clutch. And, and I did get like.
Joel Margolis (teknogeek) (01:09:33.048)
Nice.
Justin Gardner (@rhynorater) (01:09:35.897)
five figures worth of bounties from that specific domain. One of them was the C-Surf, which was cool. Now, how this one worked was it sort of had four parts of the chain, okay? So I needed to send two top level requests. This required one click, so you come to the Attacker's Page and it triggers one click. From that, I could trigger two pieces of code.
Okay, I could trigger, there's a little hack here. You can use the form, the button within the form. You can harvest one click and get two actions to be triggered. You can get a form submission because the button got clicked, and you can also use the on click. So this actually allowed me to open up two pages with one click. And...
Joel Margolis (teknogeek) (01:10:27.691)
Nice.
Justin Gardner (@rhynorater) (01:10:29.113)
So the first thing that I did was I log in, CSURFed the victim into this old legacy website from the main website. I found a way to do that where you can, you know, transfer the user in, okay? Then the second request, which was still pending, by the way.
That was sent to a PHP script on my server that was set to sleep for like two seconds or whatever, right? So it sort of delays and makes sure that the user is actually authed into the website first. Then it redirects the victim. I think I had to do a 307, too, because I think it was a post request. I'd issue a 307, which redirects the user to it with the same method, post method.
to a different URL where the CSURF actually occurred. And all of this was happening when the user came to the attackers page. And it was actually a CSURF to affect the user's account in that sort of weird obscure domain, which is not very impactful. And I thought that they wouldn't like it. But through the data pipelines, that data actually ends up back on the main application and had some pretty painful effects on the main application.
So that ended up getting accepted. It used a couple of cool tricks, which is why I mentioned it. It used this double sort of onclick thing, and then also the delay script, I think, was a nice piece as well.
Joel Margolis (teknogeek) (01:11:50.59)
Yeah, that's super interesting that aspect of sort of the double action where you click a button and you take advantage of the onclick as well as the native form element behavior.
Justin Gardner (@rhynorater) (01:11:56.981)
Yeah.
Justin Gardner (@rhynorater) (01:12:02.193)
Yeah, yeah, it's an interesting little trick. I have to refresh that in my mind, because there are definitely scenarios where you need two click triggered actions. Yeah. All right, what you got for yours?
Joel Margolis (teknogeek) (01:12:11.626)
Yeah, yeah, super interesting. Yeah, so for mine, okay, so for mine is more like the kind of thing that I talk about where it's basically the closest you can get to a C-Surf without it being a carf where it's not cross app. Yeah, so it's not cross app, but it is cross domain within the app. So essentially, I think I can talk about this. Yes, they're public. Okay, so TikTok, everybody knows TikTok. This was way back.
Justin Gardner (@rhynorater) (01:12:24.753)
Okay, wait, without it being a carf? Okay.
Nice.
Joel Margolis (teknogeek) (01:12:41.194)
before TikTok was popular, this was in 2019. And so TikTok, I don't know if they still have this functionality, but essentially, you could scan a QR code within the app, and that would, I think, take you to somebody's profile or take you to a post or something like that. It was built in. But the thing is that QR codes can have a lot of different data encoded to them. And so I realized that you could just encode an arbitrary QR code pointing to a URL,
Justin Gardner (@rhynorater) (01:12:51.498)
Hmm
Joel Margolis (teknogeek) (01:13:10.454)
and it would open it within the app, in the internal web view within the app, because the way that it routed was that it would try and use the internal URL schemas, and typically it would be encoded with some, you know, internal schema that would open someone's profile or something like that. But if you put just HTTP in there, then it'll open it in an internal web view.
Justin Gardner (@rhynorater) (01:13:14.412)
Mmm. Ah.
Justin Gardner (@rhynorater) (01:13:29.754)
So wait, so this is, do you have to scan it within the TikTok app or can you just scan it with your phone? You have to scan it with an app, right? Yeah, yeah.
Joel Margolis (teknogeek) (01:13:36.394)
Yeah, within the app. Yeah, so the attack scenario would be like, you know, you open your TikTok app, you go and scan some QR code to go to someone's profile, you get popped. And so basically, this would open up an internal web view that then had access to this JavaScript bridge and a bunch of other internal functionality that you could then take advantage of because typically they weren't expecting that you would be within this context. And so there was a whole bunch of different checks in terms of like the functions and stuff that you could call, but there was this caveat, which is that the,
Justin Gardner (@rhynorater) (01:13:44.287)
Right.
Justin Gardner (@rhynorater) (01:13:50.874)
Dude.
Joel Margolis (teknogeek) (01:14:06.494)
If you were calling the JavaScript bridge, it had this check called is safe host, and it would essentially had a list of allowed URLs. The problem is that it was checking if host.equals or host.endswith blank, then proceed. And you may have picked up on this already, but.endswith is not safe. If it was just.equals, that would have been fine, but.endswith is very, very flexible.
Justin Gardner (@rhynorater) (01:14:30.773)
dot ends with, and then with no preceding dot. Is that correct? Ah, got them, got them.
Joel Margolis (teknogeek) (01:14:35.01)
Correct, and so a lot of the domains in the list did have subdomains, however, for example, TikTok.com did not, and so I purchased the domain, not TikTok.com, and I registered it, yes, and it was like $5, and so I put together a POC, and basically, if you scan a URL, it points to not TikTok.com with my POC, it would open it up, and then from there, because it passes the host check,
Justin Gardner (@rhynorater) (01:14:42.645)
Ayyoooo
Justin Gardner (@rhynorater) (01:14:47.129)
Nice. ExploitTikTok.com.
Justin Gardner (@rhynorater) (01:14:52.117)
Yeah.
Joel Margolis (teknogeek) (01:15:03.65)
you're able to talk with the JavaScript bridge. And so there was a ton of functionality behind this. Once you get past that check, where you could create pop-ups within the app, you could install APKs, you could prompt the user, you could pull down user information about who the current user is. So there was like a ton of functionality that you could do from that point. And that's kind of like the CSRF aspect where it's on my host, it's on nottek.com.
Justin Gardner (@rhynorater) (01:15:13.365)
Dude... What the heck?
Justin Gardner (@rhynorater) (01:15:27.509)
Mm-hmm.
Joel Margolis (teknogeek) (01:15:28.898)
but I'm talking with the app over the JavaScript bridge, over the internal URL schemas, and I'm getting information across app that I really shouldn't be able to. So it's kind of like cores, kind of like CSRF, you know? But yeah, that's kind of my mobile example. And I think there's a ton of other examples out there that are more the carf stuff that we talked about where it's like creating intents from a third party app that then do something similar where it's exploiting
Justin Gardner (@rhynorater) (01:15:39.454)
Hmm.
Justin Gardner (@rhynorater) (01:15:43.029)
Dude, that's pretty freaking sick.
Joel Margolis (teknogeek) (01:15:56.982)
app functionality that you normally wouldn't be able to reach unless you were coming from a third party app or from some third party standpoint, like a web view within the app or something like that.
Justin Gardner (@rhynorater) (01:16:06.101)
for sure. That's a really, that's a cool technique because...
There are a lot of apps that have built-in QR code scanners, so I bet other apps that have Bunk Bounty programs out there are vulnerable to opening the web view via QR code like that, with just a domain. And you might have to double-click into the code a little bit to see if there are an origin check or something like that. But dude, I love those moments when you get in there, and you're like, ah, shoot, there's an origin check. Ah, I'm in trouble. And then you look at it, and it ends with,
Joel Margolis (teknogeek) (01:16:21.835)
Yeah.
Joel Margolis (teknogeek) (01:16:31.852)
Yeah.
Joel Margolis (teknogeek) (01:16:36.334)
that
Oh, nevermind. Yeah, yeah, exactly, exactly. Yeah. Yeah, yeah, so don't, you know, if you see something, look into it fully until you're for sure that it can't be exploited, because lots of times there'll be weird checks like that.
Justin Gardner (@rhynorater) (01:16:40.175)
Yes! I love that! Oh man, it just freaking gets the blood pumping.
Justin Gardner (@rhynorater) (01:16:55.061)
Good stuff, man. All right. Anything else we want to cover before we wrap up today?
Joel Margolis (teknogeek) (01:17:03.242)
Oh, yes one thing so you may have seen on Twitter Nahamsec Ben our buddy. He is on his way. He's very close to a hundred thousand subscribers on YouTube So I think he's let me double check where his actual number is But I think he was at like 95 K 94 K 95 K So he has a goal he'd love to hit a hundred K before DEF CON and if he does he's gonna shave his whole beard he's gonna shave his whole head and
Justin Gardner (@rhynorater) (01:17:08.897)
true.
Justin Gardner (@rhynorater) (01:17:12.843)
Yeah.
Justin Gardner (@rhynorater) (01:17:18.023)
Yeah.
Justin Gardner (@rhynorater) (01:17:30.057)
Dude, he's gonna be hairless. Dude, I wonder if we can get him to do the eyebrows too.
Joel Margolis (teknogeek) (01:17:32.674)
Yeah.
Yeah, maybe eyebrows too. So definitely if you aren't already go check out Nahomsec's channel. It's at Nahomsec on YouTube and give him a subscription. He's pumping out amazing content. He live streams. He does so much insightful stuff, kind of similar to the stuff that we do, but like on another level. And yeah, definitely, definitely would recommend going and looking at his channel and looking at his content and checking it out. Yeah, subscribe to Ben.
Justin Gardner (@rhynorater) (01:17:45.909)
Yeah.
Yeah.
Justin Gardner (@rhynorater) (01:17:57.673)
Absolutely. That's the call to action for today, y'all. Today, go to Nahum's Sex channel, hit that subscribe button. We wanna see a bald and eyebrow-less Nahum Sex, so please do that for us. It's actually a win-win for Ben, right? Because he gets, you know, he's got like 100K subscribers, right? So he's like...
Joel Margolis (teknogeek) (01:18:09.253)
Hahaha
Yeah.
Joel Margolis (teknogeek) (01:18:19.149)
Yeah.
Justin Gardner (@rhynorater) (01:18:19.569)
you know, pretty well known. And I'm sure if he goes to Def Con, people are gonna be like, ah, Nahomzak, you know, awesome. Let's get a picture together or something like that, right? So if he does get up to 100K subscribers, then he gets 100K subscribers, and he also gets to shave his head and his beard and his eyebrows, and no one's gonna notice him, so he can just kinda skate around Def Con like he's not famous.
Joel Margolis (teknogeek) (01:18:25.741)
Yeah.
Joel Margolis (teknogeek) (01:18:38.774)
Yeah.
Joel Margolis (teknogeek) (01:18:43.23)
Yeah, yeah, then all the photos will be great memories of. Yeah.
Justin Gardner (@rhynorater) (01:18:46.589)
Yeah, oh that's true, but the people that do recognize him will have a priceless photo forever. That's good stuff. Living in a jit-jit ball in the homsec. Dude, frick, it's got not a good year for me to skip Defcon, heck.
Joel Margolis (teknogeek) (01:18:52.857)
Exactly. It's like a limited edition, the homsex skin.
Joel Margolis (teknogeek) (01:19:00.114)
Awesome. Yeah, yeah, you're really missing out. But I understand there's, uh, there are more important life events that, uh, yes. Yeah. Cool. Yep. That's a pun. Peace.
Justin Gardner (@rhynorater) (01:19:07.765)
There are, man. There are. For sure. All right, with that, that's a wrap, yeah? Peace.