> Broken Packer>> rev150> > Description: Looks like this packer can not unpack what has been packed :( There are 2 mistakes in unpacking procedure. It leads to the error. Try to fix unpacker and figure out what is inside.> > Webpage: [broken_packer.zip](https://0xd13a.github.io/ctfs/hackit2017/rev150/broken_packer.zip)
We are given an archive with 2 files - a packer and a packed executable. As it later turns out the packer is not even needed to solve it, so let's concentrate on the packed application, ```packed```.
Running the application from command line yields a segfault:
```sh$ ./packedSegmentation fault```
We better fix those errors the description is talking about. Let's open it in IDA:
![img1.png](https://0xd13a.github.io/ctfs/hackit2017/rev150/img1.png)
The unpacking routine is very simple and the errors are easy to spot. The loop index is in ```rax``` so ```xor [rdx], dl``` should really be ```xor [rax], dl```. Also, we go byte-by-byte, so the index increment should be ```add rax, 1```, not ```add rax,2```. Let's patch the binary to correct these.
Patching the application gets us further:
```sh$ ./packedThe hardest part is overcome.Segmentation fault```
Let's debug the application and look at the disassembly to see what function outputs that:
```.text:0000000000400BA9 sub_400BA9      proc near               ; DATA XREF: sub_400990+1D.text:0000000000400BA9.text:0000000000400BA9 var_10          = qword ptr -10h.text:0000000000400BA9 var_4           = dword ptr -4.text:0000000000400BA9.text:0000000000400BA9                 push    rbp.text:0000000000400BAA                 mov     rbp, rsp.text:0000000000400BAD                 sub     rsp, 10h.text:0000000000400BB1                 mov     [rbp+var_4], edi.text:0000000000400BB4                 mov     [rbp+var_10], rsi.text:0000000000400BB8                 lea     rdi, aTheHardestPart ; "The hardest part is overcome.".text:0000000000400BBF                 call    sub_407FC0.text:0000000000400BC4                 mov     rax, [rbp+var_10].text:0000000000400BC8                 add     rax, 8.text:0000000000400BCC                 mov     rax, [rax].text:0000000000400BCF                 lea     rsi, aCryp      ; "cryp".text:0000000000400BD6                 mov     rdi, rax.text:0000000000400BD9                 call    sub_400370.text:0000000000400BDE                 test    eax, eax.text:0000000000400BE0                 jnz     short loc_400BF5.text:0000000000400BE2                 mov     rax, [rbp+var_10].text:0000000000400BE6                 add     rax, 10h.text:0000000000400BEA                 mov     rax, [rax].text:0000000000400BED                 mov     rdi, rax.text:0000000000400BF0                 call    sub_400AAE.text:0000000000400BF5.text:0000000000400BF5 loc_400BF5:                             ; CODE XREF: sub_400BA9+37.text:0000000000400BF5                 mov     rax, [rbp+var_10].text:0000000000400BF9                 add     rax, 8.text:0000000000400BFD                 mov     rax, [rax].text:0000000000400C00                 lea     rsi, aDecr      ; "decr".text:0000000000400C07                 mov     rdi, rax.text:0000000000400C0A                 call    sub_400370.text:0000000000400C0F                 test    eax, eax.text:0000000000400C11                 jnz     short loc_400C18.text:0000000000400C13                 call    sub_400B39.text:0000000000400C18.text:0000000000400C18 loc_400C18:                             ; CODE XREF: sub_400BA9+68.text:0000000000400C18                 mov     eax, 0.text:0000000000400C1D                 leave.text:0000000000400C1E                 retn.text:0000000000400C1E sub_400BA9      endp```
Looks like there is a ```cryp``` and a ```decr``` command line parameters. Assuming we need to decrypt the flag, we first need to find where the encrypted flag is. Running with ```cryp``` parameter gives us a hint at what it looks like:
```sh$ ./packed cryp h4ck1t{test}The hardest part is overcome.0x95, 0xc0, 0x90, 0x8e, 0xc5, 0x8f, 0x74, 0x31, 0x6b, 0x63, 0x34, 0x68,```
The encrypted bytes look like this:
```95 C0 90 8E C5 8F 74 31 6B 63 34 68   ......t1kc4h```
So the ending is just the flag prefix, reversed. Luckily, the encrypted flag is embedded in the binary:
![img2.png](https://0xd13a.github.io/ctfs/hackit2017/rev150/img2.png)
Now let's analyze the decryption algorithm so that we could reproduce it:
```.text:0000000000400B39 sub_400B39      proc near               ; CODE XREF: sub_400BA9+6A.text:0000000000400B39.text:0000000000400B39 var_9           = byte ptr -9.text:0000000000400B39 var_8           = dword ptr -8.text:0000000000400B39 var_4           = dword ptr -4.text:0000000000400B39.text:0000000000400B39                 push    rbp.text:0000000000400B3A                 mov     rbp, rsp.text:0000000000400B3D                 sub     rsp, 10h.text:0000000000400B41                 lea     rdi, byte_6B20A0.text:0000000000400B48                 call    sub_417BB0.text:0000000000400B4D                 mov     [rbp+var_8], eax.text:0000000000400B50                 mov     eax, [rbp+var_8].text:0000000000400B53                 mov     [rbp+var_4], eax.text:0000000000400B56.text:0000000000400B56 loc_400B56:                             ; CODE XREF: sub_400B39+6B.text:0000000000400B56                 cmp     [rbp+var_4], 0.text:0000000000400B5A                 js      short loc_400BA6.text:0000000000400B5C                 mov     eax, [rbp+var_4].text:0000000000400B5F                 movsxd  rdx, eax.text:0000000000400B62                 lea     rax, byte_6B20A0.text:0000000000400B69                 movzx   ecx, byte ptr [rdx+rax].text:0000000000400B6D                 mov     eax, [rbp+var_8].text:0000000000400B70                 sub     eax, 1.text:0000000000400B73                 sub     eax, [rbp+var_4].text:0000000000400B76                 movsxd  rdx, eax.text:0000000000400B79                 lea     rax, byte_6B20A0.text:0000000000400B80                 movzx   eax, byte ptr [rdx+rax].text:0000000000400B84                 xor     eax, ecx.text:0000000000400B86                 xor     eax, 0FFFFFF80h.text:0000000000400B89                 mov     [rbp+var_9], al.text:0000000000400B8C                 mov     eax, [rbp+var_4].text:0000000000400B8F                 movsxd  rdx, eax.text:0000000000400B92                 lea     rax, byte_6B20A0.text:0000000000400B99                 movzx   ecx, [rbp+var_9].text:0000000000400B9D                 mov     [rdx+rax], cl.text:0000000000400BA0                 sub     [rbp+var_4], 1.text:0000000000400BA4                 jmp     short loc_400B56.text:0000000000400BA6 ; ---------------------------------------------------------------------------.text:0000000000400BA6.text:0000000000400BA6 loc_400BA6:                             ; CODE XREF: sub_400B39+21.text:0000000000400BA6                 nop.text:0000000000400BA7                 leave.text:0000000000400BA8                 retn.text:0000000000400BA8 sub_400B39      endp```
Essentially the algorithm reverses the flag, and then encodes the first part of it by XORing it with characters in the second part and with ```0x80```.
To decode it let's write a short script:
```pythondata = bytearray(open("packed","rb").read())
off = 0xb20a0out = ""
for x in range(0x30/2):	out += chr(data[off + x] ^ data[off + 0x30 - x - 1] ^ 0x80) print (out + str(data[off + 0x30/2: off + 0x30]))[::-1]```
The flag is ```h4ck1t{mor0ns_rel1es_on_p4ck3r5_vari0rs_d03sn0t}```:
```sh$ python solve.py h4ck1t{mor0ns_rel1es_on_p4ck3r5_vari0rs_d03sn0t}```