Rating: 5.0

The binary ask for a 64 bytes password then replace the last \n with a null byte. The buffer is stored at address 0x412000. Then comes a huge amount of operation on this buffer using xor, add,sub,ror and rol opcodes. The final result is compared to 64 bytes stored at address 0x412050, if it matches, we won.

The dirty way to solve it, is to start from the 64 bytes at 0x412050 and reverts all operations.
Here is the quick and dirty code:

```python
from pwn import *
from capstone import *

def process_operands(ods):
Os = ods.split(", ")
nOs = []
for o in Os:
if "ptr" in o:
address = int(o[o.index('[')+1:o.index("]")],16)
newo = o.replace("ptr","")
if address != 0x412090:
off = address - 0x412000
newo = newo.replace(hex(address),"var + "+str(off))
nOs.append(newo)
else:
nOs.append(o)
return ", ".join(nOs)

# get .text and .data
BIN = ELF("./runofthemill")
text = BIN.get_section_by_name(".text").data()
data = BIN.get_section_by_name(".data").data()
data = data[0x50:0x90]

# disassemble .text
md = Cs(CS_ARCH_X86, CS_MODE_64)
asm = []
for i in md.disasm(text, 0x401000):
if i.address > 0x401051 and i.address < 0x4117f7:
asm.append((i.mnemonic,i.op_str))

# reverse all ops
asm = asm[::-1]
out = []
i = 0
while i < len(asm):
oc, ods = asm[i]

ods = process_operands(ods)

if oc == "sub":
out.append("add "+ods)
elif oc == "add":
out.append("sub "+ods)
elif oc == "ror":
out.append("rol "+ods)
elif oc == "rol":
out.append("ror "+ods)
elif oc == "movq":
const = asm[i+4][1].split(", ")[1]
ods = ods.replace("mm0","rbx")
out.append("mov rbx, "+const)
out.append("xor "+ods)
i += 4
elif oc == "movabs":
out.append("mov "+ods)
else:
out.append(oc+" "+ods)
i += 1

newasm = """global _start
section .text

_start:
%s

mov rax,1
mov rdi,1
mov rsi, var
mov rdx, 0x41
syscall
mov rax, 0x3c
mov rdi, 0
syscall

section .data
var db """ % "\n ".join(out)

for b in data:
newasm += str(int(b))+", "
newasm += "10, 0\n"

f = open("reverse.asm","w")
f.write(newasm)
f.close()

```
Results:
```
python exploit.py
nasm -felf64 reverse.asm -o reverse.o
ld -o reverse reverse.o -m elf_x86_64
./reverse
DrgnS{SoManyInstructionsYetSoWeak}

```