セキュリティキャンプ2016 選択問題(※一部)
追記(2016/6/14)
選考通ってました。
全国大会2016行きます!講師・参加者各位よろしくお願いします!
(あとで選択問題の解答を全部晒す記事書きます)
去年落ちたセキュキャン。
リベンジでありラストチャンスとして臨んだセキュキャン。
余裕を持って応募用紙を埋めていこうと思っていたセキュキャン。
結局、徹夜で仕上げました。
ちゃんと計画しておけばよかった。
今回挑んだ選択問題は、1,3,4,5。
文章量を書けそうな問題ばかり選んだら、似たようなものばかりに。
特に面白そうだと思ったのが、RHプロトコル。
コーディングしてる途中で、心がぴょんぴょんしてた。
設問の本質は、C/C++での文字列処理だった。
とりあえず動けばいいという思考なので、セキュリティは全く考慮していない。(セキュキャンへの応募なのにそれでいいのか...)
以下が、今回書いたCでのRHプロトコルアナライザー。一応ちゃんと判定できてるはず。
大文字小文字を区別せずにマッチングする処理が面倒だったので、ネット拾ってきた関数そのまま使ってます。
勝手に使ってすみませんでした。
www.c-tipsref.com
ソースコード
#include <stdio.h> #include <string.h> #include <stdlib.h> #define BUF_SIZE 2048 #define MAGIC_SIZE 2 #define SOURCE_SIZE 20 #define DEST_SIZE 20 #define LENGTH_SIZE 4 #define HEADER_SIZE MAGIC_SIZE + SOURCE_SIZE + DEST_SIZE + LENGTH_SIZE int checkMagic(char* data); int checkSource(char* data); int checkDestination(char *data); int checkCocoaChino(char *source); unsigned int calcDataLength(char *dataLength); int validOrderBrand(char *data); int invalidOrderBrand(char *data); // 引用した関数 int strcmp_ignorecase(const char *s1, const char *s2); int main(int argc, char* argv[]){ printf("Start RH Protocol analyzer\n"); FILE* fp; if ((fp = fopen("pyonpyon.rh", "rb")) == NULL) { printf("file cannot open!\n"); exit(EXIT_FAILURE); } int i = 1; while(1) { char header_buf[BUF_SIZE]; char data_buf[BUF_SIZE]; int flag = 0; int n = fread(header_buf,sizeof(char), HEADER_SIZE, fp); //printf("n = %d\n", n); if (n < HEADER_SIZE) { printf("[INFO] file reading is finish!\n"); break; } if (checkMagic(header_buf) != 1) { printf("[INFO] %d REJECTED in Magic\n", i); } else if (checkSource(header_buf + MAGIC_SIZE) != 1) { printf("[INFO] %d REJECTED in Source\n", i); } else if (checkDestination(header_buf + MAGIC_SIZE + SOURCE_SIZE) != 1) { printf("[INFO] %d REJECTED in Destination\n", i); } else if (checkCocoaChino(header_buf + MAGIC_SIZE) != 1) { printf("[INFO] %d REJECTED in Cond.4\n", i); } else { flag = 1; } unsigned int length = calcDataLength(header_buf+MAGIC_SIZE+SOURCE_SIZE+DEST_SIZE); //printf("length = %u\n", length); n = fread(data_buf, sizeof(char), length, fp); if (n < length) { printf("[INFO] file reading is finish!\n"); break; } if (invalidOrderBrand(data_buf) != 1) { printf("[INFO] %d REJECTED in invalid order\n", i); } else if (validOrderBrand(data_buf) != 1) { printf("[INFO] %d REJECTED in valid order\n", i); } else { flag += 1; } if (flag == 2) printf("[INFO] %d PASS!\n", i); i++; } fclose(fp); printf("Finish RH Protocol analyzer\n"); return 0; } int checkMagic(char *magic) { if (magic[0] == 'R' && magic[1] == 'H') { return 1; } else { return 0; } } int checkSource(char *source) { if (strcmp_ignorecase(source, "rise-san") == 0) { return 1; } if (strcmp_ignorecase(source, "cocoa-san") == 0) { return 1; } return 0; } int checkDestination(char *dest) { if (strcmp_ignorecase(dest, "chino") == 0) return 1; if (strcmp_ignorecase(dest, "chino-chan") == 0) return 1; return 0; } unsigned int calcDataLength(char *dataLength) { unsigned int length = 0; int i; for (i = 0; i < LENGTH_SIZE; i++) { length = length << 8; length += (unsigned)dataLength[i]; } return length; } int checkCocoaChino(char *header) { char* source = header; char* dest = header + SOURCE_SIZE; //if ((strcmp(source, "cocoa-san") == 0) && (strcmp(dest, "Chino") == 0)) if ((strcmp_ignorecase(source, "cocoa-san") == 0) && (strcmp_ignorecase(dest, "Chino") == 0)) return 0; return 1; } int validOrderBrand(char *data) { if (strstr(data, "BlueMountain") != NULL ) return 1; if (strstr(data, "Columbia") != NULL ) return 1; if (strstr(data, "OriginalBlend" ) != NULL ) return 1; return 0; } int invalidOrderBrand(char *data) { if (strstr(data, "DandySoda") != NULL ) return 0; if (strstr(data, "FrozenEvergreen") != NULL ) return 0; return 1; } // 以下のURLから引用 // http://www.c-tipsref.com/tips/string/o_strncmp_ignorecase.html int strcmp_ignorecase(const char *s1, const char *s2) { int i = 0; /* 文字が等しい間繰り返す */ while (toupper((unsigned char)s1[i]) == toupper((unsigned char)s2[i])) { if (s1[i] == '\0') { return 0; } i++; } return toupper((unsigned char)s1[i]) - toupper((unsigned char)s2[i]); }
実行結果
Start RH Protocol analyzer [INFO] 1 PASS! [INFO] 2 PASS! [INFO] 3 REJECTED in Cond.4 [INFO] 4 PASS! [INFO] 5 REJECTED in Cond.4 [INFO] 6 PASS! [INFO] 7 PASS! [INFO] 8 REJECTED in Cond.4 [INFO] 9 PASS! [INFO] 10 REJECTED in Destination [INFO] 11 PASS! [INFO] 12 REJECTED in Cond.4 [INFO] 13 PASS! [INFO] 14 REJECTED in Destination [INFO] 15 REJECTED in Magic [INFO] 16 PASS! [INFO] 17 REJECTED in Cond.4 [INFO] 18 PASS! [INFO] 19 REJECTED in Destination [INFO] 20 REJECTED in Magic [INFO] 21 REJECTED in Magic [INFO] 21 REJECTED in invalid order [INFO] 22 PASS! [INFO] 23 REJECTED in Cond.4 [INFO] 24 PASS! [INFO] 25 REJECTED in Destination [INFO] 26 REJECTED in Magic [INFO] 27 REJECTED in Magic [INFO] 27 REJECTED in invalid order [INFO] 28 REJECTED in Magic [INFO] 28 REJECTED in invalid order [INFO] 29 PASS! [INFO] 30 REJECTED in Cond.4 [INFO] 31 PASS! [INFO] 32 REJECTED in Destination [INFO] 33 REJECTED in Magic [INFO] 34 REJECTED in Magic [INFO] 34 REJECTED in invalid order [INFO] 35 REJECTED in Magic [INFO] 35 REJECTED in invalid order [INFO] 36 REJECTED in Magic [INFO] 37 PASS! [INFO] 38 REJECTED in Cond.4 [INFO] 39 PASS! [INFO] 40 REJECTED in Destination [INFO] 41 REJECTED in Magic [INFO] 42 REJECTED in Magic [INFO] 42 REJECTED in invalid order [INFO] 43 REJECTED in Magic [INFO] 43 REJECTED in invalid order [INFO] 44 REJECTED in Magic [INFO] 45 REJECTED in Magic [INFO] 45 REJECTED in invalid order [INFO] file reading is finish!