Hacker Time
Join Evan Johnson as he speaks with security professionals about recent security news!
Transcript (Beta)
Hello and welcome to Hacker Time, the number one security show anywhere in the world.
I am Evan Johnson from the Cloudflare product security team and today I'm rocking my JMU, James Madison University hat.
Go Dukes. The Dukes won in the Women's College World Series yesterday against number one ranked Oklahoma and so I am cheering for my Dukes this weekend.
Go Dukes. And that's why I'm rocking my JMU hat today.
But today, very, very important day in our honeypot, in the lifetime of our honeypot project we've been working on.
We are going to get it actually end-to-end working and I'm really excited about that.
And so without further ado, I'm just going to jump into it.
So we're going to get this thing working end -to-end.
We're going to clean it up a little bit. We're going to talk about what features to add next, talk about the utility of the whole thing as a whole, like what's really the point.
And then we might start to talk about what to add next.
And the first thing I need to do is I need to sort out why my integration with Twilio isn't working.
And so, oh boy, this isn't good. I got to log into my one password here.
And so I will copy and paste this in here.
Whatever what you want to be doing, logging into things live on stream, but I'll just change it all later.
So they've texted my phone for two-factor authentication.
Very important stuff here. And it's totally fine to share that on stream actually, because it's time-based token.
It has a short life cycle, those specialized two-factor authentication tokens.
And so the thing I need to do, this is the phone number I am renting from Twilio, and we need to make sure that this is in our code.
Because I realized last week, the issue we were having is at the very end of the show, we got all the code right.
And we were sending the web request to Twilio to send me the text message about an intruder alert, and it didn't work.
And the reason was because I had the wrong phone number here.
So I got to sort that out. And I think that'll work, actually.
So let's see. So we just need to make sure that the Bash RC is sourced and run our honeypot.
We've got it running.
I'll bet when I curl this, a two phone number is required. Oh no, I did the wrong phone number.
Wait, no, that's the right phone number. Phone here.
Let's double check this. I have a two phone number is one of the environment variables, and a from phone number.
And so I have two phone number here, phone. And then, oh, I wonder if this is case sensitive.
Let's see. Weird one. But it's worth taking that 10 seconds to debug it.
A two phone.
Okay, so it's not case sensitivity here. Oh.
So we know that phone.
Okay, so what is happening here? The Twilio API, when I call it, is saying that two, the phone number we're sending a text message to isn't set.
But that can't be the case. Well, it clearly is the case. But based on our code, we're reading two phone from here.
We're checking to the phone variable.
We're checking to see if phone variable is empty. And if it was, typo here, it should be two phone.
If it was empty, we would return an error. And we're setting it here.
So what could be the issue? Very strange.
And I can verify up here that the two phone number is set. Yep. So the two phone number is set.
And yet, it's not happy with us.
So I wonder if it's an issue with the API.
Let's look up the Twilio SMS API. And this might be able to help us.
Let's just make sure that what we're doing is the right stuff.
We've got the authentication handled. Send message with SMS API.
Post to the message resource. That sounds right. So what we're trying to do here, we've got, it's a post, trying to send a message with curl.
So to should be in this format.
To body from. And that should be enough.
So body says security notification from is from phone here.
To is to phone here. I wonder what this could be.
Two phone is set.
Let me just try it again.
That normally helps. This is a real stumper. OK.
Well, they give us some more info. Maybe we should read that earlier. Make sure to specify a valid phone number as the recipient of the message.
Is the phone number that's specified not a valid phone number?
Yeah, this should.
That is a valid phone number. So let's just debug it here.
We added just a debug statement just to make sure that it's actually set.
Yeah. It is actually set.
So what could this possibly be? Post endpoint.
Let's make sure that all of this is set properly. I'm going to move the two up higher.
This really shouldn't be the reason. I'm just going to move where we set to a little higher.
Let's actually print out the data, this encoded data here.
See exactly how.
So the way that this should work is when we send the post request, we're encoding data into a bunch of URL values and then it gets encoded into a big long string in the post request.
And so the HTTP request will look, the HTTP request we send to the server will look like post the URL here, 2010, all of this stuff, right?
Messages .json, HTTP 1.1. And then it should have the host header, https://api.triplio.com.
And it should have this thing will create a header here that looks like this, and it'll be a bunch of stuff.
And then there will be a new line.
And then it should say from equals this. It should have all of the data that we put here and it should be encoded into one big line, how it should look.
And this is how the HTTP request will look over the wire and the space will become 20 and all will be right with the world.
All of this data will get decoded server side. And this is like a normal form submission, how this looks.
And so I'm not really sure what could be going wrong.
I expect if we print out the string, if we add this debug statement, it should look exactly like this.
This looks wrong.
That could be it.
So let's try to read this.
This should print it out.
I didn't have that code correct, but it should print out.
Oh, boy. We need to cast this as a string. Okay.
Yeah. Okay. That's the exact thing that I expected. Ah. Is it this thing?
Okay. It's replacing my plus sign as a 2B, as a percent 2B.
That shouldn't be the issue though, should it?
That's odd.
Well, what I'm going to try to do first is remove the plus signs. It's always weird when you're interacting with somebody else's API.
There's a perfectly good reason, I'm sure, for them to be doing this the way they are, but I'm not really sure.
Just remember this is a, oh, there's a, this API was made in 2010. And so based on the URL here, so you're going to have some legacy cruft because APIs that you offer to the public are forever.
You can't really change them once people start using them.
And so more modern might be JSON, but this works just fine. But it's a little wonky today.
I need to resource the file.
Oh, wow. We spent 15 minutes on this bug.
This is like real programming. Sometimes you spend days on a bug.
A two number is still required. Okay. Why is that?
I have a two number. I have a from number. Ah, it's lame.
I had this working earlier with curl, but translating into Go hit some problems.
Let's go to the good old Stack Overflow.
Oh, my cat's here to debug with me. Okay.
So you want to send them an SMS with, hey, they got it.
They're doing the same thing that I am. So they're doing the same exact, here's their code.
Look at this.
Their code looks the same as ours. Their example code. They have data URL values.
They've got URL values. They set to from body and then strings, reader, message, and code.
They've got, and then I do the same thing. Strings, reader, new reader, data, and code.
And then they send it as a post. I'm sure. You know what? I may want to set this content type.
Content type is usually very important with APIs. I wonder if that's the problem.
I'm going to add back the plus signs here. It's angry about me copying and pasting.
My cat thinks we're close to, hey, calm down.
We're just debugging here. There's no reason to get excited. We need to, where's our request?
New request is down here. So we just have to set the header here.
I would bet this actually works. Hey, please calm down. She wants to join me.
I think she wants to be on my lap if she keeps meowing. We'll have a special visitor today on Hacker Times.
And I would bet this actually works.
I would bet a dollar, not more than, hey, I think it worked. And I've gone full end to end.
I have a security notification from Honeypot, Honeypot D. Okay, so it worked.
We spent 18 minutes on that one bug, but sometimes that's real programming.
Let's go over exactly what I tried and what worked, what didn't work here.
So the big blocker here was I did not have this line of code, content type application XWWW form URL encoded.
And so the big problem there is that the server probably supports a lot of different encoding types and content types.
And the server wasn't reading my form submission properly because it didn't know how to read it.
It might support JSON. I bet if I sent application JSON and a JSON blob instead of a form submission, I bet it would have worked too.
Most APIs support a lot of different, especially if bigger companies support a lot of different types of methods for content types.
So we need to clean this up immediately because we've got print statements everywhere.
That's not production ready. We need this, that's for sure.
Good for us to figure out. And then we no longer need this. We've got our code.
Maybe we want to maybe we want to take in some data about the person who made the request.
So whoever accessed our honeypot, we can find out who they are or where they're coming from.
And we can do that with honeypots, just something really basic.
Let's read from the client. We call notify here immediately, but let's actually get the HTTP request.
And this should have something inside of it that tells us what the client IP is probably called client IP.
Post form, post form trailer, remote adder. No, it's remote adder.
I remember now. R.remote adder. Remote adder is a string, so we should do it here.
And the next time I run this code.
Whoa, what did I do?
I've got all these debugging statements that I'm not using. That's from Jay.
That's random buff.
How you still anymore reports here and then REST 36 for HTTP response.
I'm not actually looking at this response. No new variables, huh?
24 and 25 on honeypots.
Okay, that's what the sprint F we just added. There we go.
Right, brace. And then our program's already running. I can't count. And okay, so when this runs, when I access localhost here, what we will see is I will get a text message saying access from localhost.
Oh, whoa.
I got two text messages. Neither of them say access from localhost. And I know exactly why that is.
So we just, in honeypots, we pass the string here, access from whoever, but we've got to pass that string in to Twilio.
We forgot to do that. So, this should be S.
And now when I load it in my browser, I'm going to get two text messages.
I know why that is actually.
So I got a text, access from, I wonder how I can show it on camera.
Access from left, too blurry, too blurry. Access from left square bracket, colon, colon one, right square bracket, colon 52, 140.
So that is an IPv6 address for localhost. And it's coming from port 52, 140 is the remote adder.
And so what this is telling me is the access came from inside the computer.
And so this is, pretty interesting overall.
We have built a system and it's kind of basic. It's just a website that sends a text message when it gets accessed.
But now, there's a lot we can do with this though.
As a security mechanism, there's so much you can do with this because you can deploy more than just a website.
So we could add a MySQL interface. We could add a FTP interface.
We could add an SSH interface. We could add all sorts of different server side protocols that a Honeypot supports that will then alert when they're accessed.
And so you might be wondering, won't we get a lot of alerts if that happens?
Well, if you expose it publicly to the Internet, definitely. But if you expose it privately to your own network, it is a pretty inexpensive mechanism for looking for people trying to traverse your network.
So if you deploy this within your network on in a trusted area where few people have access to, or you're deploying a service that basically isn't, a lot of tech companies have tons of services talking to each other.
And there's all of this service to service connection and authentication authorization happening.
And that's part of the service that those companies are offering to others.
But by deploying a Honeypot or something in there, there's nothing else that should be talking to it.
There's no reason any other service should randomly start reaching out to it.
So you can assume 100% that it is worth investigating if your Honeypot ever gets accessed.
So really cheap mechanism to deploy.
The bad news is it means somebody is already in your network, but very good at detecting things once they've gone wrong.
So I would like to, I'm glad we got this working in the end, even if it took me 18 minutes to debug a simple issue.
But I would like to add to this. Let's go to, I just realized the text might be a little small for you.
Within Honeypots, I would like to add, for example, a MySQL Honeypot, an SSH Honeypot.
Let me actually make the best directories.
So MySQL Honeypot and SSH Honeypot and FTP Honeypot.
And that might be it.
Those are good ones to add. And so you can see how with a little bit more support for, you can have a little bit more support for other services that aren't HTTP, you start to have a really powerful detection tool.
So I hope that you all consider Honeypots if you're on a blue team somewhere, if you're a defender out there trying to protect a company or assets, I hope you consider Honeypots as a really cheap and effective mechanism for detection because they work and they're great.
Okay. So we have about a minute left and I will do the most important part of all of this.
And I will add this message. Here are our git status.
You want to add notification here. Read me and honeypots.go.
And it's working.
Honeypot. Additionally, instead of Twilio, Twilio is a good case if you're a single person doing something, but you can integrate with PagerDuty, you can integrate with a lot of other things.
And so our software is fleshed out to add a lot of different services and a lot of different notification mechanisms.
And so, yeah, I appreciate you joining me on Hacker Time. I'm glad we got this working.
Thanks for debugging with me and I will see you all next week. Thank you so much.
Adios.