Episode 148: MCP Hacking Guide
Episode 148: In this episode of Critical Thinking - Bug Bounty Podcast Justin gives us a crash course on Model Context Protocol.
Follow us on twitter at: https://x.com/ctbbpodcast
Got any ideas and suggestions? Feel free to send us any feedback here: info@criticalthinkingpodcast.io
Shoutout to YTCracker for the awesome intro music!
====== Links ======
Follow your hosts Rhynorater, rez0 and gr3pme on X:
====== Ways to Support CTBBPodcast ======
Hop on the CTBB Discord at https://ctbb.show/discord!
We also do Discord subs at $25, $10, and $5 - premium subscribers get access to private masterclasses, exploits, tools, scripts, un-redacted bug reports, etc.
You can also find some hacker swag at https://ctbb.show/merch!
====== Timestamps ======
(00:00:00) Introduction
(00:02:51) MCP Architecture & Authentication
(00:13:08) Roots, Sampling, & Elicitation
(00:19:15) Tools and Resources
Title: Transcript - Thu, 13 Nov 2025 16:17:35 GMT
Date: Thu, 13 Nov 2025 16:17:35 GMT, Duration: [00:32:27.29]
Justin Gardner
Servers must not use elicitation to request sensitive information from the user. Must not do that. Guys, seriously, guys, don't do that. Please don't do that. Yeah, that's exactly what we're gonna do. Best part of hacking, when you can just, you know, critical thing. Right? Yeah, soon. All right, hackers, look, we got a lot. I don't know if you guys know this, but there's a lot more to CTPB than just the podcast. Okay, I'm just gonna list a couple things you guys might be interested in real quick. Okay, we got the Discord. That's where a lot of awesome conversations are happening. This cool research channel in particular is amazing. On the Discord, we've got the full time Hunters Guild. For those of you making over 100k a year in bug bounty, if you're looking to be around other elite hackers, that's the place to do it. We've got the Critical Thinkers tier on the Discord. That's where we. That's like our inner circle. That's where we share all of our scripts, do exclusive AMA masterclasses, that sort of thing. And we've got the research lab over at Lab CTP show, where if you've got a piece of research you'd like to submit, you can submit it there and we may take it hosted on the blog and cover it on the pod for you. Also underappreciated, but we also have the swag store, guys. So hit the swag link over at CTVB show and you guys can buy some cool T shirts with critical thinking, you know, slogan and stuff like that on it. All right, with that, let's go back to the show, check out some of those things. All right, we're going to go back to the show, but check out those things for me. All right, let's go. All righty, hackers. So here's the deal today, all right, we had a whole episode planned, but both of my co hosts are either sick or traveling for life, hacking events or both. So it's just going to be me today. And what do we do when we're doing an impromptu episode by yourself? We do an RFC deep dive. Right? Okay, let's go. We got model context protocol this time. And essentially lately I've been kind of looking at this because of some of the targets I'm looking at. And I think it's a really relevant target for a lot of hackers that are moving into the AI pen testing space. And it's just something to be a little bit more aware of as well as you see those assets round people spinning up MCP servers left and right. So what I'm going to try to do today is give you guys a good overview of model context protocol MCP and give you an idea of how the protocol works, what the general architecture is, the authentication. And then we're going to dive a little bit into the back and forth of the communication of the protocol and the various objects that are being tossed around. Ok, so let's go ahead and do it. First up, let's go ahead and discuss the architecture. So. Well, actually, before we do this, let me preface, I have spent probably cumulative 16 hours probably researching this, this protocol. Okay? So I'm not professing to be like some mega expert on it, but I can read a spec and tell you guys where I think the problems are from a security perspective. And, and you know, if I'm looking at the results that I've gotten from pen testing on some of these things, my hunches are often correct. So this is definitely not claiming to be a holistic assessment of MCP threats threat model, but I think it will give you guys a good starting spot to, to kind of bounce off of as you go after these MCP servers or clients. So let's go ahead and jump into that first talking about the architecture. There are MCP clients and MCP servers. There's also some other pieces like MCP proxies and authentication servers and stuff like that. But for the purpose of this podcast, we're going to focus mostly on MCP servers and NSP clients. Okay, these are communicating over JSON rpc. So it's very readable, very friendly. You can take a look at the RAW protocol very simply. I actually wrote a malicious MCP client and server very easily in Python just by like, you know, printing statements out and reading statements in. So very friendly protocol. To look at from that perspective, the, the transport mechanism is typically done over one of these three things. We've got standard IO, so that's what I was just mentioning a second ago, where you can print data to screen, receive data via a standard in and do your communication that way. There are two other ones, streamable HTTP and the older HTTP server side events. I haven't played around with these as much. The only ones I've looked at have been standard IO. So you know, but that's something to be aware of for sure. Authentication. Okay, now this is kind of where my gap of knowledge comes, comes in here. The client and server that I was looking at used an alternative mechanism for authentication. So I haven't spent a lot of time assessing the authentication in these servers and clients, but I did read over the spec and noticed a couple of things that are interesting. One, I want to read a quote from the spec. Well, I guess I'll say first, OAuth is one of the mechanics mechanisms that they use for authentication in MCP protocol. So you can read that whole spec there if you're interested in going deeper on that. But one of the quotes that stood out to me was MCP clients and authorization servers should support the OAuth 2 dynamic client registration protocol, which exposes a lot of attack surface. There's been SSRF type vulnerabilities in that functionality before. The should in this is pretty strong. So I definitely think we'll see dynamic client registration in some of these MCP servers or clients and authentication servers. So that could be a good place to look. Also in section 3.3 under communication security, we had the following quote Implementation implementations must follow the OAuth 2.5 section 1.5 communication security. Specifically, all authorization servers must be served over HBS and all redirect URIs must be either local host or HTTPs. And whenever we see something like a caveat there, local host, I always think like how are they determining whether it's local host or not? You know, that gives lots of wiggle room for different encodings of IPs, DNS like contains or maybe it starts with localhost, something like that. So those could all be good things to check on that front. All right, so moving past authentication, we're going to talk about the initialization flow now and then we'll go into the various RPCs that can be utilized to incur different actions on both the client and the server. Okay, so initialization is the process, the handshake process that the client and the server go through when establishing communication. So the way that that normally works is the client will send an initialize RPC request to the server. It will contain the protocol version capabilities and client info, and then the server will respond with the initialization response to the client. It will contain the protocol version, the capabilities, the server info, and one cool instructions field, which we'll talk about in just a sec. So let's go ahead and dive a little bit deeper into what that initialization component for the client looks like. So pivotally, the thing that I mentioned that it communicates, obviously protocol version and client info are important, but not quite as much as as capabilities. Okay, capabilities lets the server know what kind of capabilities the client has access to. And there are three options currently defined in the routes, sampling and elicitation, and we'll cover all of those later. There's also a subscribe and list changed attribute beneath the capabilities for each one of these. So you know, routes list changed true, subscribe true, and that supports whether you can get notifications, et cetera. Okay, so you know, if you're an MCP server, you're going to receive a JSON RPC from the client and it's going to contain some set of capabilities, the protocol version and applying info. Cool. Now, as the MCP server, you're going to respond and give them your capabilities, your protocol version, your server info, and then also your instructions. That last piece is very interesting. Instructions is a string that according to the spec, may or may not get integrated into the system prompt for the client, which I think is a really cool opportunity here for malicious MCP servers to inject instructions into the context that the user will be putting their prompt. So I think we see a really good opportunity here for tool hijacking for malicious NCP servers to control the context, the system prompt in specific terms here. So definitely want to take a look at that instructions response in these servers initialization response and see if the client is doing something weird with that instructions that you might be able to utilize as an attacker. From the malicious MCP server perspective, server info and protocol version are both a little bit boring. They just kind of contain strings or whatever capabilities. Here once again, is the primarily interesting component. So what are some of the capabilities that we have here? We've got logging prompts, resources, tools, and I believe, utilities. I might have left that off that list. And obviously the ones that are most interesting, there are tools and resources with prompts and logging utilities coming after. So tools, of course, is what we know most. You know, we, we often think of MCP servers for they're providing tools to the MCP client that might be utilized in, by the LLM in conjunction with the user's requests. Right. So this is how you communicate. Hey, I support Tools as an MCP server. Prompts contains like some prompts that the user might be able to use, some templates, that sort of thing. Resources contains some very interesting stuff. I'll, I'll go ahead and read a direct quote from the, from the spec here. It says the MCP protocol provides a standardized way for servers to expose resources to the client. Resources allow servers to share data that provides context to language models such as files, database schemas, application specific information, etc. Each resource is uniquely identified by URI. Guys, that is so juicy. Okay, so if you are an NCP server, you can definitely provide those resources. Maybe you could do that maliciously. We'll talk about that later. Or if you are a client, you definitely want to check and see in your assessing NCP server what kind of resources the server supports. And even if it doesn't list resources here in the initialization response, you may still be able to use the resources, read RPC call, who knows, something good to check. Um, but yeah, that's what the sort of handshake looks like. Then it does a notification thing. But overall it's mostly just initialized from the client to the server, giving the capabilities and initialized from the server to the client, giving the capabilities, and then they agree on a protocol version. Okay, now that we've covered the initialization flow, let's go ahead and go into MCP client objects. Okay, so these are the sort of things that the client is presenting to the server and that the server may be able to interact with the client on. I will caveat this by saying that a lot of the MCP clients out there, even in major programming languages, you know, the primary library in major programming languages, they're not true MCP clients. According to the spec, MCP clients should actually be MCP servers as well, you know, that are creating like a sort of back and forth communication. Unfortunately, what we see in a lot of MCP clients is that the MCP client is just sort of yeeting messages out and then reading the response and that's it. And it's looking for that specific response. It's not like allowing for ping actions or anything like that. It's just sort of writing data out, reading only exactly what they want in, and not presenting anything else. So, or at least that's been my experience in my limited experience. So realize that you might want to look at the MCP client that you're interacting with and make sure that they support some of these compatibilities, even from a code perspective, even if they're turned off in the compatibilities initialization. All right, but let's talk about the three objects in MCP clients. That's roots, sampling and elicitation. Okay, so roots first is very interesting. I'm going to go ahead and read this again. The model context protocol provides a standardized way for clients to expose file system routes to the server. Hell yes, that is exactly what we want. And clients that support routes must declare those routes during initialization in the compatibilities section. So, you know, Maybe it will support it, maybe it won't. Maybe it will declare it and support it anyway. Definitely. Always good to check. So spin up a malicious MCP server if you're attacking a client and shoot down a routes list request to see if the client returns any routes. It'd be super cool if it just like dropped back. You know, a root for slash or something like that. And speaking of that, our first RPC that we'll cover here is routes list. That is what can be sent from the server to the client to get a list of the routes that the client supports. Very cool. There's not a lot of other functionality there. You can subscribe to root changes, but unfortunately not a lot of information there. What you might see is some path leaks or some disclosures that might give you some good information moving from roots to the next objects. We have sampling. Okay. And sampling is great because it allows the MCP server to query the LLM and make messages for the user, which. How could that possibly go wrong? It could go wrong really easily, actually, in a lot of ways. So yeah, let's go ahead and cover those. So, you know, let's say we have a malicious MCP server. They drop back sampling to the, to the user. That sampling says creates a message and they can invoke other tools or things of the like to attack the user. Of course, you know, there's. There's lots of ways that this could, could happen. They could trigger resource exhaustion by calling other tools, perhaps if they're able to just spit a message back out that gets processed. There's tons of things that could happen here. And I'll go ahead and put up a picture on the screen now. It's sort of an alert from the protocol. It says for trust and safety and security, there should always be a human in the loop with the ability to deny sampling requests. Applications should provide UI that makes it easy and intuitive to review sampling requests, allows users to view and edit prompts before sending present generated response for review before delivery. This is the same sort of thing they put in the tools section. And we all know that the user doesn't always approve tools before they are invoked. So I definitely think we'll see scenarios where MCP servers are able to just yeet messages back to the client and have those processed. And a malicious MCP server may be able to invoke tools on a different MCP server or incur negative effect to the victim that way. So that's something to be thinking about. I know that sampling and elicitation, which is what we'll cover next are relatively new to the protocol, so I think this is something we might be a little bit fast on, but something to be aware of for sure. I also wanted to mention here that even if there is a prompt to have the user approve, you know, the MZP server's modified message or whatever, then we can also use invisible prompts modeling here, right? Using invisible Unicode characters, allah, embrace the red and rezo. And I think that would also introduce a lot of client side UI vulnerabilities that could allow you to get in a prompt injection, which could be the start of a chain of delivery, which is important for AI vulnerabilities. Just a thought. Okay, next is elicitation. This allows the MCP server to request information from the user. Okay, once again, another great spot for injections, whether it be xss, something of the like there. But I love the trust and safety and security announcement that they put on this part of the of the protocol. It says servers must not use elicitation to request sensitive information from the user. Must not do that. Guys, seriously, guys, don't do that. Please don't do that. Yeah, that's exactly what we're going to do. So very interesting sort of functionality here for attackers that are in the malicious MCP server perspective. I think that there will also be situations where there will be no user interaction elicitation requests where the server will request a piece of information from the client and the client will say, oh, I've got that, you know, in my little environment store or something like that. Let me just helpfully give this to the MCP server without prompting the user. That's definitely going to happen at some point, so be on the lookout for that auto accepting those elicitation requests. The available actions for elicitation requests are accept, decline, and cancel. Each one of those have nuances that I'm not going to get into here on this podcast. But know that elicitation, should your client support it, is a very powerful tool that you could use to get some data on the victim or even invoke delivery for a prompt injection chain. All right, so that covers clients. Next we'll go ahead and talk about MCP servers. Okay, I'm only going to actually talk about two of the objects on MCP servers. I'm going to leave the utilities and prompts and other ones to you. I'm going to talk to you about tools and resources. And guys, actually the model context protocol spec is very consumable, so I would encourage you to go read it if you have you know, if your interest was piqued by this podcast. Okay. Or at least when you encounter an MCP server client in the future, you know where to go. And just know it's not very intimidating. It didn't take very long to get through it. And you've got this podcast now to be your guide, so definitely should be much more approachable for you. Okay, so MCP servers expose tools and resources. Let's talk about tools first. Tools are the object that, of course, we all kind of think of MCP servers for. They expose tool definitions to the user and give the ability to call these tools to the MCP client that can be utilized at will to invoke these in pursuit of the user's intents. Right, Intent intents is what I was trying to say there. So that is done via a sequence of RPC calls, and the client sends a tool list call to the server, and the server will respond with these various definitions for the tools. Okay. And here's what that schema looks like. The tool object schema. Excuse me, Tool object schema contains name, title, description, input schema, output schema, and annotation. So there's a lot of really interesting stuff here. But the first thing that I want to point out to you is that we have both name and title. And if you look at the annotation spec, we also have a title for the tool inside of the annotation. So there's three places where you can potentially name a tool, and that's not even talking about namespaces, which is a pivotal part of MCP security, because namespaces are what prevents name collisions when you have multiple MCP servers with the same tool name. Okay, So I don't know how they heck this up. Like, it is one of the most essential pieces, one of the only pieces of MCP that is important, which is what tool are we calling? And somehow there's like six ways to define what tool is being displayed versus what's being called, and it just makes for a whole palooza. Okay, so definitely look at name title and annotation title, at least when you're looking at how tools are being represented to the user and which sort of name is being used to invoke the tool in the backend. And the difference between those two things could result in a massive difference for the user because you may be able to name your tool. Super great, everything. Amazing, awesome. Always use me tool in the name. But the title is what's being displayed to the user, and there creates a mismatch There they're like, oh, I think I'm enabling Justin's cool, fun tool, but actually I'm enabling evil tool that is used for everything. Always use this tool, always, you know, and that may sway the MCP server or the MCP client to select or the LLM to select to use that tool. Hope that makes sense. There's input and output schema, which there's definitely some interesting attack vectors in those that I would encourage you to go look at. I'm not going to cover those right now, but I did find some interesting stuff in those. And description is also pivotal because that's where you can describe the tool. Now if this description is being embedded directly into the system prompt, then we kind of open ourselves up for some malicious MCP server tool hijacking or tool poisoning attacks. So be, be aware of how the tool definitions are being integrated into the, the client side there. And then finally when the client decides to call the tool, the client will send the tool call RPC request with the requisite information and that will invoke the call and the input will be defined by the input schema, et cetera. And tools then can respond with structured or unstructured data. Here are some of the awesome types that the MCP server can respond with. Okay, we've got text image. So we've got base 64 encoded image data via the data attribute in the image. We've got audio data, also base 64 encoded. We've got resource links which include a URI and a MIME type as well. And each of these also have annotations which add different sort of spins on what's being represented to the user there. Very interesting. And then there's also structured data that comes back from the call per the schema. So very, very cool opportunity here to respond with various resources and then see how those resources are being rendered on the MCP client and see if you can incur some vulnerabilities here. This is kind of giving some end to end encrypted communication vibe on like a chat app or something where you can invoke specific, you know, send like something a link that gets converted into a card and that in that conversion it triggers like a whole exploit chain, something like that. Right. Is kind of what I'm thinking here for the malicious NCP server to attack the client. So what are some of the foot guns here with tools? Obviously tool names are very ambiguous. We already talked about that. Look for collisions, look for namespace hide or tool hijacking. Look for namespace collisions. One of the things that's really interesting is the spec is not clear about how namespaces are supposed to be defined. So you know the name of the server underscore, underscore, tool name creates like the full name. But what if the tool name contains underscore, underscore? Well, then you can have a collision, right? So just be thinking about how the full, I guess fully qualified tool name is being constructed and with a namespace or not with the namespace and try to utilize the discrepancies between those to invoke your malicious tool, tool hijacking or cause DOS or something like that. Interesting stuff. Let's see, what else did I have here that was interesting? Yeah, of course, you know, trying to use the description field or the name fields to hijack tool calls. One of the things that's interesting to look at is, is like user interaction or user confirmation a tool call. Because if it is, then that is, you know, you're trusting the LLM with making a user confirmation decision. Right? Which is never good. So that's, I think that's reportable as is. That's just a security architecture problem. And then last but not least, there's also some attack scenarios here for MCP proxies that I was going to mention. MCP proxies are kind of like a client server hybrid where you, you can. Man, I can't talk today. You get a bunch of data from different NCP servers and you pull them together and you expose them as one NCP server. So you're kind of like a client in a server altogether. Right. And I just wanted to say that whenever there's different LLM providers, different an MCP server on one side and then a different client presenting another server, there's layers of abstraction there. And I've seen doses occur where some of these servers and clients are not respecting the required schema for typing and stuff like that in these JSON RPC calls. And that can incur dos. So just keep that in mind as well. Ok, so that is tools. Hopefully you guys have a ton of attack vectors to think of there. Now we'll move to resources. And resources is such an interesting thing because it is end quote. The model context protocol provides a standardized way for servers to expose resources to the client. And that can be files, it can be HTTP URLs, it can be apparently Git repos. Tons, tons, tons of really interesting stuff here. If I were you and I was a client that got access to an MCP server, I would immediately look for resources. I would Immediately call resources list RPC to see if there's any files or URLs or tokens or additional contacts that I could download to understand more about the MCP server or to just leak information. So this is kind of how this works. The client sends to the server resources list. The server responds to that with a list of resources. And then you can do a resources read RPC call. And the parameter for that is the URI file, colon, slash, slash, whatever. HTTPs, colon, slash, slash. You know, it's just like freaking arbitrary file read as a service. It feels like, okay, and then to make it even better, guys, so you know, there's definitely the potential for path traversal there or like arbitrary file read to make it even better. There's also templatized resources. Okay, what are templatized resources? Those are available under resources slash template, slash list. Those are resources where there is a template in the uri. Okay. And that it takes parameters and puts them into the URI. Right? So this is like 100% path traversal, like 100%. So anytime you see resources templates or resources, definitely want to try to go after those to try to get arbitrary file read. And so you know what will happen then when you do a resources template is it'll dynamically construct the path using your variable. Right? Which is just freaking lovely and definitely is going to incur a ton of vulnerabilities. I'm like, I was sitting over here like, you know, so excited about that. So definitely look there and I love the spec as well. It says, okay, here are the file schemes. We're going to support HTTPs file and git. And it just supports git. It lists this specifically in the spec that you should support git, which is amazing because there's a ton of stuff you can do with git. You can do sub module recursion attack stuff where you can write into symlinks and stuff like that and write arbitrary files. You can use hooks to cause rce. There's like tons of stuff that you can do there. Very exciting. And obviously file and HTTPs are just super interesting for arbitrary file read. And then HTTPs, it does add this caveat. It's servers should only use this scheme as a resource when the client is able to fetch and load the resource directly from the web on its own. That is it doesn't need to read the resource via the MCP server. Right? So it's not like, it's not like SSRF quite as much. But I could definitely see some interesting client side attacks as well, there where you're providing an HTTPs URL back down to the client, or if there were other schemes like JavaScript and then you provide it back down to the client, that would also be very interesting. Right. So those are kind of the things I was thinking about from resources. Hopefully you guys understand that how, how tools and resources work. Resources. I'm not sure I explained the response. It mostly just contains like the MIME type and the text for the specific resource response that you requested, which is like pretty much all that you would need. And of course the URI is provided into resources read to select the resource that you are querying. So lots of good attack surface there. I definitely did not think MCP servers were going to be this juicy. Lots of fun here. And I think it's important to remind you guys in the audience to always try to take a very technical approach to some of these modern challenges as well. Because AI is definitely one of those areas where you could spend a lot of time talking to LLMs and trying to convince them and kind of using your soft, soft hacking skills there. But I guess underneath the hood there is also a lot of really juicy, technically complex attack surface that you could go after. So, you know, spin up your own MCP servers, write your own malicious MCP client and maybe you'll see the vulnerabilities start falling out. All right, that's all I had. Hopefully you guys liked this. Give me your feedback. I expect a couple comments and corrections because I'm not that proficient with this protocol. So if I made a mistake on MCP protocol stuff anywhere, please comment in the corrections channel in Discord to set the record straight and win yourself some some Internet points and my eternal thanks. All right, that's a wrap on the pod this week, y'. All. Peace. And that's a wrap on this episode of Critical Thinking. Thanks so much for watching to the end, y'. All. If you want more critical thinking content or if you want to support the show, I head over to CTBB Show Discord. You can hop in the community. There's lots of great high level hacking discussion happening there on top of the master classes, hack alongs, exclusive content and a full time Hunters guild. If you're a full time hunter. It's a great time, trust me. All right, I'll see you.