### microsoft <3 linux

thought it was a binfmt_misc thing with wsl considering the name, so i just ran it in wsl for a bit

except IDA crashes every time i try to debug it and core dumps arent that helpful either lmao

[@Robert](https://maplebacon.org/authors/Nneonneo/) helped cleaning the elf up for a bit but i realized it really is just a small program 

if i just paid more attention i wouldve realized its bitwise rotation from the start lol

was finding reimplementations rol/ror in python but had a few duds before i found one that works

that only got me half the flag though so i had to figure out whats left

in the meantime [@Robert](https://maplebacon.org/authors/Nneonneo/) spotted the `$` at the end of the string after i pointed out i cant run it on windows since its not compatible

so he instantly concluded that this is a DOS COM file and indeed it is

except binja's decompilation with the DOS plugin really is not that good so i just used IDA and manually reversed it from assembly lol

turns out its just a simple 0xD xor anyway

either way flage `corctf{3mbr4c3,3xt3nd,3Xt1ngu15h!!1}`
```py
rol = lambda val, r_bits, max_bits: (val << r_bits%max_bits) & (2**max_bits-1) | ((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))

ror = lambda val, r_bits, max_bits: ((val & (2**max_bits-1)) >> r_bits%max_bits) | (val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))

#ELF
print(''.join([chr(rol(i, 3, 8)) for i in b'l\xedNl\x8e\xccof\xadLN\x86lf\x85f\x0f\x8e>ci!>Uy<cjx<8e,,<p'[:18]]), end='')

#COM 16 bit
print(''.join([chr(i ^ 0xD) for i in b'l\xedNl\x8e\xccof\xadLN\x86lf\x85f\x0f\x8e>ci!>Uy<cjx<8e,,<p'[18:]]))
```

### msfrob

[@Em]() was looking at it and got me interested coz i see dlopen

but she said she couldnt even get it to run so i thought there might be some anti debugging thing

turns out its just coz if we pass nothing to the parameters thats supposed to be the flag to be checked it just terminates lol

so with that i just looked at the functions and realized they are all jump outs which means the got and stuff is kinda screwed

not the first time ive encountered this tho i think last time was cyber apoc's shuffleme

so same deal dynamically trace the function resolving and manually name it again

eventually after a bit of renaming i realized its just zlib and aes 256 cbc

though i wasnt sure what the loop was doing coz the code was still messy so i had to tidy the stack variables up

IDA's local type -> insert C declaration really helped for the `z_stream` struct

[@Angus](https://maplebacon.org/authors/alueft/) was helping on the side testing out different stuff but nothing really worked

until i realized it really is just running the AES 20 times so i looked to see if my codes for that was wrong since i can only run it once before dying

turns out i just forgot to put AES initialization inside the loop lol which means its considered the same stream which ofc aint gonna work

anyway flage again `corctf{why_w0u1d_4ny0n3_us3_m3mfr0b??}`

i completely didnt touch memfrob aside from the chall desc that [@Angus](https://maplebacon.org/authors/alueft/) pointed out lmao
```py
import zlib
import base64
from Crypto.Cipher import AES

data = base64.b64decode('TO80+tElRUvnrZnEsdf2LFvzE7/MAx0WgdtQOKi23SCQKm6i7/5rj9uAb3B063025NyH8yDr5Q8+KDVYrQfSPdhdQTVeT0GbkYXhXBi49lrfCDUxBNLgRGT8BsbWW5ggTxweuCDVntqB1jZbVWCoLPLaV5LJ4BTwQ0suEdNwZ6hVCH3Hdk936L7zGQSEsqAg3EzSyJQXm3VPeDU15mJ0LQyoNPGQqf1Z1PgkuTuUvXnHeLlWweO2Lhc6MvlOR/kJxOj6SVNqC7k2CytcyfM5Y7PRrHBs8UZCvAuROmSVd+wkAWTSmOG/OBfU0DkWEx00pBr6M1+IIdVcTr8zneEqzEcVA52mhTYtbTEBPZUI3HLT9vdlt8CVXfTJp/rc71E2wR3mCOuK7F3JWj3TmqatKJkkiJJALasSWfiER7K5SPePHjJkuiTSPfPEhL3S4QEHoXYYRR5UkZMRbkFUfkDnAg==')
print(len(data))

key = b'\xd4\xf5\xd9g\x15/w\x7fl|Fs\xf6\xf0\x92\xf0wP;0\x0c\x87\x8a\r\x9c\x1dr\xa2eF\xc8\xdc'
print(len(key))
iv = b'\0'*16

for i in range(20):
    c = AES.new(key, AES.MODE_CBC, iv)
    print(i)
    strm = c.decrypt(data)
    print(strm)
    data = zlib.decompress(strm)
    print('\n', data, sep='')
    #data = bytes([x ^ 42 for x in data])

with open('dump', 'wb') as wb:
    print(data)
    wb.write(data)


#oops too late
desc = bytes.fromhex('6b0a444558474b460a5a58454d584b470a5f5943444d0a444558474b460a4d464348490a4c5f44495e4345445904')
desc = bytes([x ^ 42 for x in desc])
print(desc)
```

### turbocrab

beeg rust binary that looks like its crafting some sort of shellcode and executing it?

dont care, i can just breakpoint after it finishes crafting the shellcode and jump to it 

the shellcode looks quite confusing though with IDA's decompiler not working that well

and i cant really use binja for it coz i dont really know how to use binjas debugger still yet and the shellcode has to be dynamically obtained

so i tried to look for places that might be potential instruction counting sites and see if there are patterns considering it looks like its AND-ing until one of the recursion fails which will return 0 for the entire chain

but somehow my breakpoints were all not working 

after a bit of digging around and finding alternatives like tracepoints or even counting steps a thought came to my mind 

would it be because im lacking write perms for the new page 

so i patched mprotect and breakpoints actually work now so that saved a lot of time

eventually i found a `test al al` location that looks kinda interesting and i wanna automate it to see if it really can be instruction counted

but pwntools was having a field day with my usual gdb method by breaking the child process read() that it kept saying `SIGTTIN`

had to mess around quite a bit again here too trying out temp files as stdin or in memory buffers like StringIO but none worked until i changed stdin to PTY

still there was quite a bit of wackiness when it comes to communicating with the process and my instruction counting script ended up only working 50% of the time

but theres not really that many false positives so its just a big waiting game

eventually some false positives did pop up but they were scarse enough that i can just reason my way through the flag 

for some reason using DEBUG prints for pwntools also helped in stabilizing the script too lol

either way aside from the last char of the flag which i didnt put in the dictionary until i manually submitted the flags to the platform (i forgot the binary was a flag checker itself lmfao) i realized it was a question mark

anyway heres flage lol `corctf{x86_j1t_vm_r3v3rs1ng?}` took way too long

also another chall that i didnt touch what they expected me to touch again lmao
```py
from pwn import *
import string
import io

#context.log_level = 'ERROR'

flag = 'corctf{x86_j1t_vm_r3v3rs1ng'

while len(flag) < 29:

    #val = {}
    for c in string.printable:
        p = process(['/usr/bin/gdb', '-q', './turbocrab'], stdin=PTY)
        p.sendline(b'start')
        p.recvuntil(b'turbocrab::main')
        p.sendline(b'catch syscall read') #need to break for mprotect to be run before breakpoint in shellcode
        p.recvuntil(b'(gdb) ')
        p.sendline(b'continue')
        p.recvuntil(b'(gdb) ')
        p.sendline(b'continue')
        #p.interactive()
        p.send(flag + c)  #sendline's \n screws up the counter sometimes
        p.recvuntil(b'(gdb) ')
        p.sendline(b'i r rax')
        r = p.recvuntil(b'(gdb) ')
        print(r)
        p.sendline(b'b *0x00007ffff7ffa228')  #gdb is pie disabled; this seems to be where the 1s change to 0s and the recursion ends
        p.recvuntil(b'(gdb) ')
        p.sendline(b'continue')

        count = 0
        try:
            while True:
                print(count)
                p.sendline(b'continue')
                r = p.recvuntil(b'(gdb) ')
                print(r)
                if b'incorrect' in r:
                    p.close()
                    break  
                count += 1
        except EOFError:
            p.close()

        print(count, c, flag)
        # if count > len(flag) + 2:
        #     flag += c
        #     break
        #val[c] = count
    #print(max(val, key=val.get))
```
