今回もリモート問題なので接続し、ソースコードを見てみると
長い。。。。
Stage5まであってそれぞれの値と比較してあってれば次のStageに行く感じ
そして、実際に値をいちいち入れるのは無理だから、ソースコードを書いて解いて行く
まず、ステージ1から
if(argc != 100) return 0;
if(strcmp(argv['A'],"\x00")) return 0;
if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0;
printf("Stage 1 clear!\n");
だから
argcが100で、argv['A']には\x00
argv['B']には\x20\x0a\x0dが入っていればクリアらしい
まず、argv_hを100個作って、
argv['A']には\x00
argv['B']には\x20\x0a\x0d
そしてargv[100]にはNULLを入れる(C言語の配列の一番最後にはNULL)
セッティングが終わったらexecveシステムコールで実行ファイルのパスとセッティングしたargv_hを渡す。
そして、実行して見ると
ステージ1はクリア!!
ステージ2は
char buf[4];
read(0, buf, 4);
if(memcmp(buf, "\x00\x0a\x00\xff", 4)) return 0;
read(2, buf, 4);
if(memcmp(buf, "\x00\x0a\x02\xff", 4)) return 0;
printf("Stage 2 clear!\n");
ステージ2がどうすればいいか分からなくて色々検索したらpipeを使えばいいと書いてあったので
pipeについて勉強もできた!!
簡単に言うとpipe関数を使うとプロセス間通信ができるということだ
順番に説明すると
1.両方向通信のために二つのpipeを作る
2.childプロセスを生成する
3.子プロセスはwriteは要らないからwriteを閉じて、read側を0(stdin)と2(stderr)に割り当てる
4.execveシステムコールでchildプロセスをinputプロセスに変える
4.親プロセスはreadは要らないからreadを閉じて、write側にクリア条件の値を書いてあげる
で、実行したら
ステージ2までクリア!!
次は、ステージ3
if(strcmp("\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef"))) return 0;
printf("Stage 3 clear!\n");
これは、execveシステムコールに環境変数を設定して渡せばOK!
childプロセスのexecveに追記して、実行すると
ステージ3もクリア!!
次はステージ4
FILE* fp = fopen("\x0a", "r");
if(!fp) return 0;
if( fread(buf, 4, 1, fp)!=1 ) return 0;
if( memcmp(buf, "\x00\x00\x00\x00", 4) ) return 0;
fclose(fp);
printf("Stage 4 clear!\n");
これは"\x0a"というファイルに"\x00\x00\x00\x00"を書いて置けばOKっぽい!
下から4番目からが追記したもの!
ファイルをオープンしてwriteで"\x00\x00\x00\x00"を書いてあげて、実行すると
ステージ4もクリア!!
次はステージ5
int sd, cd;
struct sockaddr_in saddr, caddr;
sd = socket(AF_INET, SOCK_STREAM, 0);
if(sd == -1){
printf("socket error, tell admin\n");
return 0;
}
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = INADDR_ANY;
saddr.sin_port = htons( atoi(argv['C']) );
if(bind(sd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0){
printf("bind error, use another port\n");
return 1;
}
listen(sd, 1);
int c = sizeof(struct sockaddr_in);
cd = accept(sd, (struct sockaddr *)&caddr, (socklen_t*)&c);
if(cd < 0){
printf("accept error, tell admin\n");
return 0;
}
if( recv(cd, buf, 4, 0) != 4 ) return 0;
if(memcmp(buf, "\xde\xad\xbe\xef", 4)) return 0;
printf("Stage 5 clear!\n");
ソースコードをみると
saddr.sin_port = htons( atoi(argv['C']) ); ここでargv['C']の値を設定するから
任意の番号をargv['C']に設定して、ソケットに"\xde\xad\xbe\xef"を書いてあげれば良い
int sock; からが追記したソースコードだ
これで、実行するとステージ5までクリアはできるけど、flagが出力されない。。。
調べたら、現在の経路(実行ファイルがあるところ/home/input2には権限がないため、/tmp/私が作ったフォルダーの中)
にはflagファイルがないためだという。。
解決方法はシンボルリンクを作ればOKだという記事をみたので
やってみたらflagが出力された!!
でも、スクリーンショット取るの忘れた。。










