Thursday, July 28, 2016

How to import "raw" IPs into Burp

If you need to test a list of IPs and *any* domains that may be on those IPs, burp doesn't exactly make it easy to enter in a large number of IPs. If you try to use the "load" button with a file of just one IP per line, it will import it, but it will also do something extremely annoying:

Those regexes? They mess up everything. Before if you entered 1.2.3.4, ANY domain name that resolved to that would show up in the filtered sitemap, now only instances of "1.2.3.4" show up, and if you visit the domains, they no longer appear, because they don't match the regex.

I finally figured out how to upload a "raw" list of IPs into the scope listing unmodified. Burp has a feature on a tiny button that allows you to "load options", which is really just a json formatted file with a bunch of different Burp settings:
So I decided to take a look at the format, and holy crap, "raw" IPs are actually recognized properly in this settings file. So I wrote a quick python script to create a proper settings file from a supplied list of IPs:


#!/usr/bin/env python
#@atucom
#this script takes in a one-per-line file of IPs and adds it to Burp without any stupid regexes
#  This mimics the same thing as hitting the "add" button in the Scope tab
#  to load the resultant file, you need to go to the Scope tab, hit the little gear button in the 
#  top left and click "load settings", choose the jsonout.txt file and rejoice.
import sys
import json
basejson = """
{
    "target":{
        "scope":{
            "exclude":[
                {
                    "enabled":true,
                    "file":"logout",
                    "protocol":"any"
                },
                {
                    "enabled":true,
                    "file":"logoff",
                    "protocol":"any"
                },
                {
                    "enabled":true,
                    "file":"exit",
                    "protocol":"any"
                },
                {
                    "enabled":true,
                    "file":"signout",
                    "protocol":"any"
                }
            ],
            "include":[
            ]
        }
    }
}
"""
ipfile = open(sys.argv[1]) #open file of IPs (one per line)
iplist = ipfile.readlines()
dictjson = json.loads(basejson) #load base json data structure
for ip in iplist:
  newip = {"enabled":True, "host":ip.strip(), "protocol":"any"}
  dictjson['target']['scope']['include'].append(newip) #appends new IP entry to python dict

jsonout = open("jsonout.txt", "w")
jsonout.write(json.dumps(dictjson))
print("wrote to jsonout.txt")

To use it, run the script and supply the file with you one-per-line IP list. It will dump out a "jsonout.txt" file. In Burp, go to Target > Scope > Gear Button > Load Options > select jsonout.txt > Open

That should be it, your IPs should now show up in the "include in scope" box like below:


I also saved it to my gist for posterity: https://gist.github.com/atucom/b083d1f3b12606aaf4076a689d200939

I always assumed there had to be a supported way of doing this but after asking several people, nobody could find a way. This seems to be the only way that works for what I need done. Now, I just need to write up a Burp extension for it...

UPDATE:
Thanks to the help of a friend of mine with the Burp plugin code, I've been able to create a burp plugin that accomplishes this task:
https://gist.github.com/atucom/eabf35f344f46ffbd2f8d25b018f88c9

Friday, July 22, 2016

My "secrets" to scripting more and feeling like I type less

Motivational Disclaimer: 
I'm not a programmer. I don't fully understand all the nitty gritty computer science concepts of different programming paradigms, or "patterns", or "best-practices". Everything I know is self taught. Everything I know I've learned through trial and error, googling, or some simple online tutorials. I'm sure if a programmer looked at what I produce they could find a thousand different things to do better or faster. To a certain degree, I care about that. I care about producing what others consider to be "good" code. I also know my limitations. "Learning" to code (or scripting, but I'll just say coding) is not something to do, and THEN start do it very well. Coding is ugly. Your baby, the thing you will be proud of, WILL be ugly. But fuck that, honestly, because you actually HAVE something. That's more than a large percentage of the population can claim.
PS. I word-battle sailors. Take care if you have "delicate sensibilities"
----------

So I'm not a programmer in the least sense. I have, however, recognized that I do try to write a lot of code. My code revolves around efficiency. I wish to reduce how much typing I do. If I can do that by typing a little more now, so I can save it later, than that's an awesome reason to write a script.

We all have an inferiority complex to some degree, and for the longest time I thought nothing I produced was worthy of another's eyes. But I realized something, people kept asking for my scripts. People kept using my dotfiles (mostly for the scripts). People kept making use of the things I was creating. That feeling is actually rather addicting. People now look at me and have said things like "wow, I wish I could script". Well I'm here to share with you some things I've learned throughout my journey, things I haven't seen anyone else suggest for newbies. This is intended for fairly technical people who understand basic things like what a variable or function is but just haven't made the plunge to actually get more into it (people who stop at hello world). This is not for people looking to get into programming/development as a job. This is for people who have peers that script and feel that its "something they should get better at" (e.g. lots of infosec people). So bite the pillow, this is going to be a wall of text.

1. Learn to recognize WHEN to write a script
     This is probably the most important skill to first get. You need to set what I call a "mental breakpoint" when you encounter certain thoughts or emotions. You need to catch yourself right when you think "God I wish I could do this faster" or "Ugh, I keep typing the same shit over and over again". Train yourself to break out of that moment and trigger a whole new line of thought of "Wait a second, how COULD I make this faster?" or "Could I create something to actually reduce how many times I do this?"

2. Understand how to convert the problem into a program
     I watched a free programming video recording from Stanford (the ones you get for free on iTunes) and while most of it was rather boring and my ADHD took over, there was one statement the teacher made that has stuck with me and I remember every time I start to write a script. "All programs do the exact same thing, they take input, they do something with it, and they produce output" - now that is an incredibly generic and abstract thought, yes, but it frames your goal in a particular way which (to me, at least) was ground breaking. I now ask myself these questions every time:

  1.  What will be the input to my program? will it be text from some other command? will it be text I scraped from a website somewhere? Will it be some arbitrary file? will it be XML? will it be an image? What will the INPUT be?
  2. What will I do to this input? What's the body of the script? Really, what is the point of what I'm doing? Is it to analyze that text input for repeating patterns? is it to constantly check that website for changes and updates to it's content? is it to encrypt a file in some way? is it to add a watermark to an image? What is the "goal" you are trying to accomplish?
  3. What will this produce? what is the end result? Will it "produce" something like a file? or will it update a SQL record somewhere? Will it send you a text message when it notices a change on that website? or will it trigger a whole other script all together? What is the thing you want to walk away with?

     These questions can take all of 4 seconds to answer in simple cases, and weeks in the complex ones. Sometimes the answers to these questions will be obvious in certain cases and you don't even really need to think about it, but mostly, I like to keep that framework of "INPUT, DO, OUTPUT" in my head mostly all the time.

3. Is writing this script worth it?
     In my moments of wonder I like to think that computers are capable of anything, that they can solve the world's problems and make our lives infinitely better in all the ways that matter. Unfortunately the skill of a computer is at least limited by the skill of the programmer.
     Many times I'll come across a problem I swear I can easily solve by scripting, but as time goes on I find that the actual problem I'm trying to solve is way out of my ability as a programmer. It would be impossible for me to tell you what you can and cant do, I can say however, that the more you code and the more efficient you get at it, the smaller that list of "cant's" gets. Ideally it would shrink to where you become a greybeard wizard or something but thats just the magical fairy land I keep my head in.
     The instances in which I had a problem to solve, but couldn't find the solution I simply file it away in it's own project directory as something to look at again in the future. Many time I'll come across a new tool/module/gem/whatever that does the thing that my script needed to begin with. Sometimes, someone else solves the problem that I had, but I try to not rely on that "oh maybe in the future" line of thinking.

4. You can't do this alone
     Think about it for a second, you are starting out in a hobby/profession where there are millions of experts. If you ever sit down in front of a terminal and think "shit, I don't know how to get these two servers to talk" or "shit, I don't know how to search an array for a string" and start to feel discouraged that you're dumb and you don't know how to do "simple" things, stop. If that happens to you, you cant stop that internal reaction, but you can instantly distract yourself by actually GOOGLING your problem.
     You will need to read the docs. Like, a lot of docs. You will Google A LOT. You will read MANY stack overflow posts. You will read many man pages. You will google your google results. You will read both awesome and shitty blog articles. There will be a lot of "copy and paste that stack overflow post and change it to fit your needs". This is normal. This is OK. You are not awful because of this. You may be awful for other completely unrelated reasons, but not for this.
     Github is your friend. Read other people's code. Steal their code if it works. Just don't claim that you made that stolen code yourself, that's a dick move. There are enough self-entitled dicks who want to drama-llama everything so they get attention. Don't be a dick. Break the cycle, Morty, rise above, focus on science.
     Ideally, you'd have a friend or coworker who is willing to provide advice, or at least valuable links to websites that provide valuable advice. If you have that kind of friend than I VERY STRONGLY suggest you do the following:

  1. Roughly understand the problem you are trying to solve
  2. Do some basic work on trying to find a way to solve it
  3. Ask specific questions, but give context. Don't ask them "how can you delete every third entry in an array" ask instead "How can you delete every third entry in an array? Apparently garbage data keeps coming into every third entry that I store into an array". They may respond with "like this" or they may go on to tell you how it's a good idea to deal with the garbage data on input before the array and maybe log it properly in case you have problems later.
  4. Show your friend that you respect their time by illustrating that you've done some research beforehand. It's incredibly aggravating to get asked a question that the first google result answers.


5. Stop practicing and start doing
If I see another "hello world" script I'm going to punch a baby. Stop copying stupid scripts that don't actually DO anything. You know what a variable is, you know what a function is. Going through the 4th online tutorial that teaches you how to write yet another 1+1 python function isn't helping you. It's the equivalent of tracing an image on paper so you can FEEL like you are an artist. You already know the absolute basics (if you don't, then those tutorials are helpful). Identify a problem you have (using step 1) and start solving it (by using steps 2 & 4).
     It's going to suck. Your code is going to suck. You will be embarrassed of your ugly child.  But, if your child functions, then keep it. Improve on it if you have the time and energy or save the improvements for a later date.
     I recommend jumping into the "hard stuff" even if you're still at the "easy stuff", you will learn A LOT faster that way.

6. OK, actually you need to practice too
     I "practice" code all the time, often times before I actually do anything and sometimes just for fun. What I mean by that is I usually start up a Ruby or Python interpreter and start pasting in some code, changing random sections of code or variables, googling errors that result, trying out other's code from Github or StackOverflow.
     A perfect example is that I thought to myself a couple years ago "I read about XMLRPC, I wonder how I can actually make it do something in Ruby" so I found a free XMLRPC endpoint for testing on the Internet, fired up my Ruby interpreter and just starting pasting code I saw listed in the basic documentation. I saw how it made a connection, the syntax it expected, how to issue the XMLRPC method calls, how to play with the results and so on and so forth. I wiped my screen, and tried to do all that again from scratch with no pasting. I had no use for it, it was just for fun. One year later I needed to get a value from an XMLRPC endpoint and I thought to myself "Hey, I played with XMLRPC on Ruby a while ago, I'm pretty sure I can get this up and working".
     Bam, because of that "for fun" practice I did, I was much faster and more efficient at accomplishing that goal at the moment I needed it. I try to find ways to play with code for fun as often as I can.

7. Perfect does not exist
Nothing is perfect, your code definitely won't be. An old manager told me it takes 90% of the total time to accomplish the last 1% if you aim for perfection. I now aim for "get it working and mostly reliable". I don't create scripts that require 100% reliability, or that someone paid millions of dollars for. I write scripts mostly for myself, to save myself time. My "extra" aim is to write the same script so that my friends/coworkers can use it easily, that is, if I think they will benefit from it in the first place.
     I can say however, that as I have aimed for writing more well-documented and more reliable scripts, it has become easier to do so by default. This practice of aiming for your peers (once you can write for yourself) creates a habit of accounting for things you may not have thought of (bad input, not enough comments, bad parameter descriptions, overall ease of use, etc), which overall results in "better" scripts as I go on.

8. Don't stop
     You WILL forget the language if you don't keep it up. I'd say at the absolute least you should be reading code once a week and writing something once a month. That's absolute minimum. Please don't aim for the minimum, mediocrity doesn't look good on you.

9. You're a wizard, Harry
     Coding (IMO) is the closest humans can get to magic. This shit feels like magic most of the time. You just created a python script that can track peoples movements from a video feed? Holy shit are you a wizard? In order to feel like a wizard, you have to feel like your doing magic. Don't lose the wonder and amazement in training your abilities. You know that everything you can do isn't magic, you know how to perform edge detection and draw a certain pixel size box that colored red around that thing, and you know what functions to use to detect it's movement, but don't lose the feeling.
     We are motivated by desires and emotions. Train yourself to hold on those, to remember those, to remember why they got triggered in the first place. Often I have to remind myself to sit back at the end of something and think "yeah, I just did that, and it was awesome for me...I wonder what I could do next"
     So you may be year 1 Harry Potter, but you got a lot of learning and awesomeness ahead of you. Go be a fucking wizard.

So seriously, ingrain step 1 in your head, and go from there.

Wednesday, July 20, 2016

How to have a webshell over SMS

I consider this more of a "stupid trick" than actually being terribly useful. I recently thought to myself "How awesome would it be if I could text a phone number to run some commands" and I immediately answered that question with "super freakin' awesome".

You need the following:
  1. A number set up at Twilio - This is what is used to actually communicate over SMS
  2. A VPS - You need this to host a server application to accept the text string from Twilio servers. This will also be where the commands are actually run.
  3. Ruby with twilio-ruby and sinatra gems installed
Purchase a phone number in Twilio and have the "webhook" line in the SMS section point to your VPS URL, for example: http://myvpshere:8080/smscli or whatever you choose. Once you set that up, whatever SMS messages get sent to the phone number you purchased in Twilio will be sent as an HTTP Post request to the URL you specify. 

Now all you need is a server listening at that URL on your VPS to accept the HTTP Post requests from the Twilio servers and do something with the body of the request. In this case, we pass whatever text as a system command and reply to the phone number with the result of the command. The following example Ruby code starts up a sinatra web server to do all that:


require 'twilio-ruby'
require 'sinatra'

set :port, 8080
set :bind, '0.0.0.0'

post '/smscli' do
  puts "Message: #{params['Body']}!"

  result = `#{params['Body']}`

  twiml = Twilio::TwiML::Response.new do |r|
    r.Message result
  end
  twiml.text
end

Overall, this really isn't that different from any other webshell. The only real difference is you are leveraging Twilio to handle SMS communications.

Now you get to do something stupid like this:

PS.
     I shouldn't have to mention that taking in arbitrary text from untrusted sources and running them as commands under root is pretty much the worst thing you could do security wise. This is merely an example of how to get the pure task done. Implement some auth or something, I don't care... It's your funeral...