Non-stack format string exploit techniques-vulnerability warning-the black bar safety net

ID MYHACK58:62201995713
Type myhack58
Reporter 佚名
Modified 2019-08-29T00:00:00


On Linux the stack format string vulnerability in the use of online has many explanations, but non-stack format string vulnerability few people introduced. This is mainly over weekends SUCTF game playfmt topic, for example, detail about the bss segment or on the heap format strings the use of skills.

0x01 basic knowledge point Format string vulnerability in the specific principle is not described in detail, here a brief look at the formatting parameter of the calculated position and exploits often used to format characters. Parameters of the position computing linux the following 32-bit program is a stack to pass parameters, from left-to-right argument Order of$esp+4,$esp+8,...; therefore,$esp+x position should be the format x/4 parameters. under linux the 64-bit program is register Plus stack to pass parameters, from left-to-right argument order for$rdi,$rsi,$rdx,$rcx,$r8,$r9,$rsp+8,...; therefore$rsp+x position should be the format x/8+6 parameters. Commonly used formatting characters Used to address the leakage of the formatting characters are:%x,%s,%p, etc.; For the address to write the formatting characters:%hhn(write a byte, the%hn(write two bytes,%n, 32-bit write four-byte, 64-bit write 8 bytes; and %$type: the direct effect of the number of location parameters, such as:%7$x to read the first 7 positions of the parameters value,%7$n the 7 parameter position to write. %c: the output number characters, with the%n to an arbitrary address write, for example,"%{} c%{}$hhn". format(address,offset)is to offset0 parameter points to the address of the lowest bit is written into the address.

0x02 non-stack on format string exploit In General, the stack on the format string exploit is the first step leak the address, including the ELF program address and libc address; and then will need to overwrite the GOT table address passed directly to the stack, while the use of%c and%n of the method is rewritten into a system or one_gadget address, the last is the hijacking of the process. But for the BSS segment or on the heap format strings, not directly will want to rewrite the address of the pointer placed on the stack, there is no way to achieve arbitrary address write. The following SUCTF in playfmt, for example, introduce the commonly used non-stack format string vulnerability in the use of the method. Examples Topic description Program vulnerability point more obvious, straightforward to write a loop of printf format vulnerabilities, and the input data is stored in the buf pointer, and buf is located in the bss segment in the address for 0x0804B040 it. int do_fmt(void) { int result; // eax while ( 1 ) { read(0, buf, 0xC8u); result = strncmp(buf, "quit", 4u); if ( ! result ) break; printf(buf); } return result; } . bss:0804B040 public buf . bss:0804B040 ; char buf[200] . bss:0804B040 buf db 0C8h dup(?) ; DATA XREF: do_fmt(void)+E↑o Check out the program of protection can be found on the RELRO, that is unable to rewrite the GOT table, so the idea is to directly modify the stack on the return address, return the time of the hijacking process. ! Leak address First need to get the current stack address and the libc base address, these addresses can be very relaxing on the stack to find which esp+0x18 stored 栈地址, esp+0x20 store a libc address, you can get are the 6 parameters and 8 parameters, directly passed%6$p%8$p can be obtained 栈地址 and libc address. ! Any address write Here the main need to solve is how to overwrite the address placed on the stack. To achieve arbitrary address write need to rely on Stack the presence of a chain-type structure, such as 0xffb5c308->0xffb5c328->0xffb5c358, the three addresses are in the stack. ! The following figure is a simple 栈地址 space of the figure, offset represents the format of the parameter position. Through the first offset0 a parameter, use%hhn can control the address1 of the lowest bit, and then through the offset1 parameter, use%hhn can write address2 lowest position; then, by offset0 parameter, use%hhn to modify the address1 of the lowest bit of the original value+1, then by offset1 parameter, use%hhn can write to address2 to the second lowest position; turn the cycle to completely control the address2 value, again using the address1 and address2 in the chain type structure, can be realized on the address2 of the address space of any write. Corresponding to the above display of the address space, address0=0xffb5c308,offset0=0x18/4=6;address1=0xffb5c328,offset1=0x38/4=14;address2=0xffb5c358,offset2=0x68/4=26; ! The following is the address to write code to achieve, first get the address1 of the most significant bit of the original value, and then sequentially written address2 each byte. def write_address(off0,off1,target_addr): io. sendline("%{}$p". format(off1)) io. recvuntil("0x") addr1 = int(io. recv(8),16)&0xff io. recv() for i in range(4): io. sendline("%{}c%{}$hhn". format(addr1+i,off0)) io. recv() io. sendline("%{}c%{}$hhn". format(target_addr&0xff,off1)) io. recv() target_addr=target_addr>>8 io. sendline("%{}c%{}$hhn". format(addr1,off0)) io. recv() Renderings below, can be seen esp+0x68 location is already on the stack the return address of the storage location, which is another run screenshots, 栈地址 change it.

[1] [2] next