åå ã¯ãCpawCTF ã®ç¶ãã§ãã CpawCTF2 ãéå§ãã¾ããã
ä»åã¯ãåºç¤åãä»ããããã«ããmallocé¢æ°ã¨freeé¢æ°ãç解ãã¦ããã¾ããèå¼±æ§ãè¦ã¤ããå¾ãå®éã®ä¾µå
¥ã«ç¹ããã¨ãã«ãmallocé¢æ°ã®ç解ãæ±ããããå ´åãããã¾ãï¼Use After Freeã¨ãï¼ã
å®éã«ä½¿ããã¦ãã glibc ã® mallocãfree ãèªããã¨ããã®ã§ãããããã«æ«æããï¼ç¬ï¼ã®ã§ãã¾ãã¯ãåºæ¬ã¨ãªã K&R ã® mallocé¢æ°ãfreeé¢æ°ããç解ãã¦ããããã¨æãã¾ãã
ããã§ã¯ããã£ã¦ããã¾ãã
åèæç®
ã¯ããã«
ãã»ãã¥ãªãã£ãã®è¨äºä¸è¦§ã§ããè¯ãã£ããåèã«ãã¦ãã ããã
ã»ãã¥ãªãã£ã®è¨äºä¸è¦§
åèæç®ã®ãããã°ã©ãã³ã°è¨èªCã¢ã³ãµã¼ã»ãã㯠第2çãã®åèã§ãããC Programming Language (Prentice Hall Software)ãã¯ãPDF ããã¦ã³ãã¼ãã§ãã¾ãã
https://seriouscomputerist.atariverse.com/media/pdf/book/C%20Programming%20Language%20-%202nd%20Edition%20(OCR).pdf
ããã§ã¯ããã£ã¦ããã¾ãã
åèã«ããã¦ããã£ããµã¤ã
ããã¤ãåèã«ãªããããªãµã¤ããè¦ãã¦ãããã¾ããããããã1çªè©³ããã£ãã¨æãã¾ãã
Memory Allocator for embedded system (K & R Ritchie book)
gnuchops.wordpress.com
æåã®åã£æããã¨ãã¦ã¯ãããã®ãµã¤ããåãããããã£ãã§ãã
www.ei.fukui-nct.ac.jp
以ä¸ã¯ãglibc ã® malloc ã®è©±ãã¡ã¤ã³ã®ããã§ãããå
é 㯠K&R ã® malloc ã®å
容ãããã¾ãããã®è³æã¯ãé常ã«æåãªè³æãããã§ãã
www.slideshare.net
ä¸ã®è³æãæ¸ãããæ¹ããçºè¡¨ãã¦ã YouTube ãããã¾ãããããæåãããã§ããä¸å¿ãå
¨ã¦è¦ããã¦é ãã¾ããã確ãã«ãglibc ã®æ·±ãã¨ããã¾ã§ãåããããã解説ãã¦ããã¦ããã®ã§å¿
è¦ã ã¨æãã¾ãã
www.youtube.com
åãã½ã¼ã¹ã³ã¼ããç¨æãã¦ãããã¬ã§è¿½ãããã¦ç解ãã
K&R ã® mallocé¢æ°ã¯ãã¨ã¦ãã½ã¼ã¹ã³ã¼ãéãå°ãªãã§ãããããã§ãåè¦ã ã¨ããªãé£ããã§ããã½ã¼ã¹ã³ã¼ãã ãè¦ãããããããã¬ã§åããã¦ãå¤æ°ã®å¤ãè¦ãªããç解ãé²ããæ¹ããå¹çãããã¨æãã¾ãã
åèãC Programming Language (Prentice Hall Software)ãã® 8.7 Example - A Storage Allocator ã«ãmallocãfree ã®ã½ã¼ã¹ã³ã¼ããããã¾ãã
Cè¨èªã¨ãã¦ãå°ãæ¸ãæ¹ãå¤ãã¨ãããã¨ã¨ãã¿ã¤ããã¹ãããã¤ããã£ã¦ãã³ã³ãã¤ã«ãéããªãã®ã§ããããä¿®æ£ãããåãã½ã¼ã¹ã³ã¼ããç¨æãã¾ããã
https://github.com/dk0893/experiment/blob/main/c/k_and_r_org.cgithub.com
ã³ã³ãã¤ã«ã¨å®è¡æ¹æ³ã¯ä»¥ä¸ã§ããæ«å°¾ã«ãã mainé¢æ°ã§ãmalloc/freeé¢æ°ãã³ã¼ã«ãã¦ãã¾ãããããããããå¤ãã¦ãmallocé¢æ°ã®ç解ãé²ãã¾ãã
$ gcc -D DEBUG -o k_and_r_org.out k_and_r_org.c
$ ./k_and_r_org.out
0, 0
0, 0, 0, 0
0, 0, 0, 0, 0, 0
mallocé¢æ°ã¨freeé¢æ°ã®ç解
以éã¯ãç§ãç解ããå
容ãæ¸ãã¦ããã¾ãã
å
é ã®å®£è¨ãå®ç¾©é¨å
unistd.h ã¯ãsbrké¢æ°ã使ãã®ã§å¿
è¦ã§ãã
Header ã«ã¯ã次ã®ãããã¯ã®ã¢ãã¬ã¹ã¨ãã®ãããã¯ã®ãµã¤ãºï¼ã¦ãããåä½ï¼ãå
¥ã£ã¦ãã¾ããAlign x ã¯ãã¢ã©ã¤ã¡ã³ããå¼·å¶ããããã«å®ç¾©ããã¦ãã¦ãå®éã«ã¯ä½¿ããã¾ããã
#include <unistd.h>
typedef long Align;
union header
{
struct
{
union header *ptr;
unsigned size;
} s;
Align x;
};
typedef union header Header;
static Header base;
static Header* freep = NULL;
static Header *morecore(unsigned nu);
void myfree(void *ap);
mallocé¢æ°
æ¨æºé¢æ°ã¨ååããã¶ãã®ã§ãé¢æ°åã malloc ãã mymalloc ã«å¤ãã¦ãã¾ãã
æåã¯ããªã¼ãªã¹ããåå¨ããªãã®ã§ãã°ãã¼ãã«å¤æ°ã® base 㨠freep ãåæåãã¾ãã
ãã®å¾ã® foræã§ã¯ãæåã¯ã¡ã¢ãªãç¡ãã®ã§ãforæã®æåã®æ¹ã¯å®è¡ããããmorecoreé¢æ°ãã³ã¼ã«ãã¾ãããã®ä¸ã§ãã·ã¹ãã ãã大ããã®ã¡ã¢ãªã確ä¿ãã¦ãã¾ãã
foræã®å
é ã«æ»ããããªã¼ãªã¹ããã空ããæ¢ãã¾ãã空ãã¦ããããã¯ï¼ãããã¯ã¯é£ç¶ãã¦ç©ºãã¦ãã¡ã¢ãªã®ãã¨ï¼ãè¦ã¤ãããããã®ãããã¯ã®æ«å°¾ããå¿
è¦ãªéã®ã¡ã¢ãªãåãåºãã¦ä¸ä½ã«å
é ã¢ãã¬ã¹ãè¿ãã¾ããè¦ã¤ãããããã¯ã®ãµã¤ãºãå¤ããã®ã§ããµã¤ãºãæ´æ°ãã¦ãã¾ãã
void* mymalloc (unsigned nbytes)
{
Header* p;
Header* prevp;
unsigned nunits;
nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
if ((prevp = freep) == NULL)
{
base.s.ptr = freep = prevp = &base;
base.s.size = 0;
}
for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr)
{
if (p->s.size >= nunits)
{
if (p->s.size == nunits)
prevp->s.ptr = p->s.ptr;
else
{
p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
}
freep = prevp;
return (void *)(p + 1);
}
if (p == freep)
if ((p = morecore(nunits)) == NULL)
return NULL;
}
}
morecoreé¢æ°
æåã¯ç©ºãã¡ã¢ãªãç¡ãã®ã§ãã¾ãããã®é¢æ°ãã³ã¼ã«ããã¾ãã大ããã®ã¡ã¢ãªï¼1024 * 16 = 16384 byteï¼ã確ä¿ããã¾ãããã®å¾ãfreeé¢æ°ãå¼ã³åºãã¾ããfreeé¢æ°ãå¼ã³åºããã¨ã§ã確ä¿ããã¡ã¢ãªãããªã¼ãªã¹ãã«èªèããã¦ã使ããããã«ãã¦ãã¾ãã
#define NALLOC 1024
static Header *morecore(unsigned nu)
{
char *cp;
Header *up;
if (nu < NALLOC)
nu = NALLOC;
cp = sbrk(nu * sizeof(Header));
if (cp == (char *) -1)
return NULL;
up = (Header *) cp;
up->s.size = nu;
myfree((void *)(up + 1));
return freep;
}
freeé¢æ°
æ¨æºé¢æ°ã¨ååããã¶ãã®ã§ãé¢æ°åã free ãã myfree ã«å¤ãã¦ãã¾ãã
freeé¢æ°ã§ããæåã® foræããã¾ã ç解ãä¸ååã§ããããããããããªã¼ãªã¹ããããªã¹ãããã©ã£ã¦ï¼pï¼ã解æ¾ããé åï¼bpï¼ã®è¿ãã«è¨å®ãï¼é£æ¥ããã¦ï¼ã解æ¾å¾ã«ç©ºãã¡ã¢ãªå士ãé£çµãããããã«ãããã ã¨æãã¾ãã
void myfree(void *ap) {
Header *bp, *p;
bp = (Header *)ap - 1;
for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
break;
if (bp + bp->s.size == p->s.ptr) {
bp->s.size += p->s.ptr->s.size;
bp->s.ptr = p->s.ptr->s.ptr;
} else
bp->s.ptr = p->s.ptr;
if (p + p->s.size == bp) {
p->s.size += bp->s.size;
p->s.ptr = bp->s.ptr;
} else
p->s.ptr = bp;
freep = p;
}
mainé¢æ°
æå¾ã«ãmainé¢æ°ã§ããããããªãã¿ã¼ã³ã§ãmallocé¢æ°ã¨ freeé¢æ°ãã³ã¼ã«ããããã«ç¨æãã¾ããã
#ifdef DEBUG
#include <stdio.h>
int main( int argc, char *argv[] )
{
char *p0, *p1, *p2;
p0 = (char *)mymalloc( 2 );
printf( "%d, %d\n", p0[0], p0[1] );
p1 = (char *)mymalloc( 4 );
printf( "%d, %d, %d, %d\n", p1[0], p1[1], p1[2], p1[3] );
p2 = (char *)mymalloc( 6 );
printf( "%d, %d, %d, %d, %d, %d\n", p1[0], p1[1], p1[2], p1[3], p1[4], p1[5] );
myfree( p1 );
myfree( p0 );
myfree( p2 );
}
#endif
ãããã«
ä»åã¯ãåºæ¬ã® K&R ã® mallocé¢æ°ã¨ freeé¢æ°ã«ã¤ãã¦ããããã¬ã§å®è¡ã§ããã½ã¼ã¹ã³ã¼ããç¨æãã¦ãç解ãé²ãã¾ãããä½åº¦ãè¦ç´ãã¦ç解ãé²ãã ããglibc ã® mallocé¢æ°ã¨freeé¢æ°ã®ç解ã«é²ã¿ããã¨æãã¾ãã
æå¾ã«ãªãã¾ããããã¨ã³ã¸ãã¢ã°ã«ã¼ãã®ã©ã³ãã³ã°ã«åå ä¸ã§ãã
æ°æ¥½ã«ãããã¨ãããããé¡ããããã¾ãð
ä»åã¯ä»¥ä¸ã§ãï¼
æå¾ã¾ã§ãèªã¿ããã ãããããã¨ããããã¾ããã