We were provided a ruby source file(simple-260e49e58afc505131f19cd348b435c4.rb).
According to this file, our input(username and password) would be converted to the JSON format like this( {"username":"XXX","password":"YYY","db":"hitcon-ctf"}) and encoded by AES-128-CFB. Because this cryptosystem used CFB mode (https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation) , we could modify one block’s plaintext by modifying next block’s ciphertext. “(ciphertext) xor (true plaintext) xor (fake plaintext)” gave us the modified next block. Ofcourse next block would be decoded messy, but once we quote the messy text by double-quote(“), it was treated as a part of JSON data and thanks to CFB mode, the block after the next block was decoded properly.
In our payload, we set username = "A"*19 + '!,!admin!:true,!' + "A"*13 and password = "a". All we need was changing (!) into (“) to get the “admin” JSON data (“admin”:true)! The problem was, due to the encoding problem, if some wrong charactor was included in ciphertext, not only our payload but sometimes genuine ciphertexts were not accepted by remote server. We needed some bruteforce to get a good IV which did not make ciphertext with wrong charactor. Once we got good IV and modified ciphertext was accepted by the remote server, the flag appeared promptly. (This problem was corrected by admins later in the competition: “auth = auth.b”)