sandbox
# PREFACE:
审洞,chroot 以后没有 chdir,会保留当前文件夹下的状态信息,可以直接到需要的目录下运行读取,sendfile 可以跨 chroot 把东西读出来
#define _GNU_SOURCE 1 | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <stdbool.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <string.h> | |
#include <time.h> | |
#include <errno.h> | |
#include <assert.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <sys/socket.h> | |
#include <sys/wait.h> | |
#include <sys/mman.h> | |
#include <sys/sendfile.h> | |
int main(int argc, char **argv, char **envp) | |
{ | |
assert(argc > 0); | |
printf("###\n"); | |
printf("### Welcome to %s!\n", argv[0]); | |
printf("###\n"); | |
printf("\n"); | |
setvbuf(stdin, NULL, _IONBF, 0); | |
setvbuf(stdout, NULL, _IONBF, 1); | |
puts("This challenge will chroot into a jail in /tmp/jail-XXXXXX. You will be able to easily read a fake flag file inside this"); | |
puts("jail, not the real flag file outside of it. If you want the real flag, you must escape.\n"); | |
puts("The only thing you can do in this challenge is read out one single file, as specified by the first argument to the"); | |
puts("program (argv[1]).\n"); | |
assert(argc > 1); | |
char jail_path[] = "/tmp/jail-XXXXXX"; | |
assert(mkdtemp(jail_path) != NULL); | |
printf("Creating a jail at `%s`.\n", jail_path); | |
assert(chroot(jail_path) == 0); | |
int fffd = open("/flag", O_WRONLY | O_CREAT); | |
write(fffd, "FLAG{FAKE}", 10); | |
close(fffd); | |
printf("Sending the file at `%s` to stdout.\n", argv[1]); | |
sendfile(1, open(argv[1], 0), 0, 128); | |
} |
level2
#define _GNU_SOURCE 1 | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <stdbool.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <string.h> | |
#include <time.h> | |
#include <errno.h> | |
#include <assert.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <sys/socket.h> | |
#include <sys/wait.h> | |
#include <sys/mman.h> | |
#include <sys/sendfile.h> | |
#include <capstone/capstone.h> | |
#define CAPSTONE_ARCH CS_ARCH_X86 | |
#define CAPSTONE_MODE CS_MODE_64 | |
void print_disassembly(void *shellcode_addr, size_t shellcode_size) | |
{ | |
csh handle; | |
cs_insn *insn; | |
size_t count; | |
if (cs_open(CAPSTONE_ARCH, CAPSTONE_MODE, &handle) != CS_ERR_OK) | |
{ | |
printf("ERROR: disassembler failed to initialize.\n"); | |
return; | |
} | |
count = cs_disasm(handle, shellcode_addr, shellcode_size, (uint64_t)shellcode_addr, 0, &insn); | |
if (count > 0) | |
{ | |
size_t j; | |
printf(" Address | Bytes | Instructions\n"); | |
printf("------------------------------------------------------------------------------------------\n"); | |
for (j = 0; j < count; j++) | |
{ | |
printf("0x%016lx | ", (unsigned long)insn[j].address); | |
for (int k = 0; k < insn[j].size; k++) printf("%02hhx ", insn[j].bytes[k]); | |
for (int k = insn[j].size; k < 15; k++) printf(" "); | |
printf(" | %s %s\n", insn[j].mnemonic, insn[j].op_str); | |
} | |
cs_free(insn, count); | |
} | |
else | |
{ | |
printf("ERROR: Failed to disassemble shellcode! Bytes are:\n\n"); | |
printf(" Address | Bytes\n"); | |
printf("--------------------------------------------------------------------\n"); | |
for (unsigned int i = 0; i <= shellcode_size; i += 16) | |
{ | |
printf("0x%016lx | ", (unsigned long)shellcode_addr+i); | |
for (int k = 0; k < 16; k++) printf("%02hhx ", ((uint8_t*)shellcode_addr)[i+k]); | |
printf("\n"); | |
} | |
} | |
cs_close(&handle); | |
} | |
int main(int argc, char **argv, char **envp) | |
{ | |
assert(argc > 0); | |
printf("###\n"); | |
printf("### Welcome to %s!\n", argv[0]); | |
printf("###\n"); | |
printf("\n"); | |
setvbuf(stdin, NULL, _IONBF, 0); | |
setvbuf(stdout, NULL, _IONBF, 1); | |
puts("This challenge will chroot into a jail in /tmp/jail-XXXXXX. You will be able to easily read a fake flag file inside this"); | |
puts("jail, not the real flag file outside of it. If you want the real flag, you must escape.\n"); | |
puts("You may open a specified file, as given by the first argument to the program (argv[1]).\n"); | |
puts("You may upload custom shellcode to do whatever you want.\n"); | |
assert(argc > 1); | |
puts("Checking to make sure you're not trying to open the flag.\n"); | |
assert(strstr(argv[1], "flag") == NULL); | |
int fd = open(argv[1], O_RDONLY|O_NOFOLLOW); | |
if (fd < 0) | |
printf("Failed to open the file located at `%s`.\n", argv[1]); | |
else | |
printf("Successfully opened the file located at `%s`.\n", argv[1]); | |
char jail_path[] = "/tmp/jail-XXXXXX"; | |
assert(mkdtemp(jail_path) != NULL); | |
printf("Creating a jail at `%s`.\n", jail_path); | |
assert(chroot(jail_path) == 0); | |
int fffd = open("/flag", O_WRONLY | O_CREAT); | |
write(fffd, "FLAG{FAKE}", 10); | |
close(fffd); | |
void *shellcode = mmap((void *)0x1337000, 0x1000, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, 0, 0); | |
assert(shellcode == (void *)0x1337000); | |
printf("Mapped 0x1000 bytes for shellcode at %p!\n", shellcode); | |
puts("Reading 0x1000 bytes of shellcode from stdin.\n"); | |
int shellcode_size = read(0, shellcode, 0x1000); | |
puts("This challenge is about to execute the following shellcode:\n"); | |
print_disassembly(shellcode, shellcode_size); | |
puts(""); | |
puts("Executing shellcode!\n"); | |
((void(*)())shellcode)(); | |
} |
./flag