# Pin and triton: Binary instrumentation and symbolic execution


Installation

$ wget 'http://old-releases.ubuntu.com/releases/14.04.0/ubuntu-14.04.1-server-amd64.iso' # kernel 3.x
$ # Install ubuntu server
$ # The installed server needs the following software
$ sudo apt-get install libboost1.55-dev
$ sudo apt-get install libpython2.7-dev
$ git clone https://github.com/Z3Prover/z3.git
$ cd z3
$ python scripts/mk_make.py --python
$ cd
$ wget 'http://www.capstone-engine.org/download/3.0.4/ubuntu-14.04/libcapstone3_3.0.4-0.1ubuntu1_amd64.deb'
$ wget 'http://www.capstone-engine.org/download/3.0.4/ubuntu-14.04/libcapstone-dev_3.0.4-0.1ubuntu1_amd64.deb'
$ sudo dpkg -i libcapstone3_3.0.4-0.1ubuntu1_amd64.deb
$ sudo dpkg -i libcapstone-dev_3.0.4-0.1ubuntu1_amd64.deb
$ # Pin version 71313
$ wget 'http://software.intel.com/sites/landingpage/pintool/downloads/pin-2.14-71313-gcc.4.4.7-linux.tar.gz'
$ tar xvzf pin-2.14-71313-gcc.4.4.7-linux.tar.gz
$ cd pin-2.14-71313-gcc.4.4.7-linux/source/tools
$ git clone https://github.com/JonathanSalwan/Triton.git
$ cd Triton
$ mkdir build
$ cd build
$ cmake -DPINTOOL=on ..
$ make
$ PATH=$PATH;~/pin-2.14-71313-gcc.4.4.7-linux/source/tools/Triton
$ cd ..
$ sysctl kernel.yama.ptrace_scope=0
$ triton ./src/examples/pin/ir.py /usr/bin/id

Challenge

$ wget 'https://raw.githubusercontent.com/black-bunny/First-hands-with-Triton/master/CrackMe.c'
$ gcc -o CrackMe CrackMe.c
$ cat CrackMe.py
import pintool
import triton

SNAPSHOT = False
ARGV1 = 0

MAIN = 0x4005bd
AVOID = [0x4006f2, 0x400714, 0x400727, 0x400744, 0x400760, 0x400782, 0x4007a4, 0x4007c3, 0x4007e7, 0x40082f, 0x400869, 0x40088e, 0x4008cf, 0x40096e]
TAKE = [0x40080b, 0x400910]
PASSWORD_SIZE = 11
SYMVAR_CONSTRAINTS = []
NUM_MANDATORY_PATHS = 0
LAST_INJECTED = ''

def superAnd(constraints):
 pc = triton.ast.equal(triton.ast.bvtrue(), triton.ast.bvtrue())
 for i in range(len(constraints)):
  pc = triton.ast.land(pc, constraints[i])
 return pc

def model2string(model):
 s = ''
 for i in range(PASSWORD_SIZE):
  try:
   s += chr(model[i].getValue())
  except:
   pass
 return s

def inject(address, data):
 for i, char in enumerate(data):
  pintool.setCurrentMemoryValue(address + i, ord(char))

def before(instruction):
 global SNAPSHOT
 global ARGV1
 global SYMVAR_CONSTRAINTS
 ia = instruction.getAddress()
 if ia == MAIN:
  if not SNAPSHOT:
   rsi = pintool.getCurrentRegisterValue(triton.REG.RSI)
   ARGV1 = pintool.getCurrentMemoryValue(rsi + 8, triton.CPUSIZE.REG)
   print 'rsi = ', rsi
   print 'ARGV1 = ', ARGV1

   offset = 0
   while offset < PASSWORD_SIZE:
    address = ARGV1 + offset
    pintool.setCurrentMemoryValue(address, ord('*'))
    symvar = triton.convertMemoryToSymbolicVariable(triton.MemoryAccess(address, triton.CPUSIZE.BYTE))
    SYMVAR_CONSTRAINTS.append(triton.ast.bvuge(triton.ast.variable(symvar), triton.ast.bv(0x20, 8)))
    SYMVAR_CONSTRAINTS.append(triton.ast.bvule(triton.ast.variable(symvar), triton.ast.bv(0x7e, 8)))
    offset +=1
   pintool.setCurrentMemoryValue(ARGV1 + offset, 0x0)

   print '[+] Symbolized %d bytes of memory at 0x%x' % (offset, ARGV1)
   print '[+] Taking snapshot'
   pintool.takeSnapshot()
   SNAPSHOT = True

def before_symproc(instruction):
 global NUM_MANDATORY_PATHS
 global LAST_INJECTED
 path_constraints = []
 ia = instruction.getAddress()

 if ia in TAKE:
  NUM_MANDATORY_PATHS += 1

 if (ia in AVOID) or (ia == 0x40080f and NUM_MANDATORY_PATHS != 1) or (ia == 0x400914 and NUM_MANDATORY_PATHS != 2):
  NUM_MANDATORY_PATHS = 0
  print '[+] Wrong password'
  pc = triton.getPathConstraints()
  for i in pc:
   if i.isMultipleBranches():
    for branch in i.getBranchConstraints():
     if branch['dstAddr'] in AVOID:
      path_constraints.append(triton.ast.lnot(branch['constraint']))
     if branch['dstAddr'] in TAKE:
      path_constraints.append(branch['constraint'])
  full_constraint = superAnd(SYMVAR_CONSTRAINTS + path_constraints)
  model = triton.getModel(triton.ast.assert_(full_constraint))
  s = model2string(model)
  LAST_INJECTED = s
  print '[+] Posible solution: ' + s + ' - ' + s.encode('hex')
  s += chr(0)
  print '[+] Injecting it and restoring snapshot'
  inject(ARGV1, s)
  triton.clearPathConstraints()
  pintool.restoreSnapshot()

 if ia == 0x400978:
  print '[+] Good password: ', LAST_INJECTED
  pintool.disableSnapshot()
  triton.clearPathConstraints()
  pintool.setCurrentRegisterValue(triton.REG.RIP, 0x400982)


def constantFolding(node):
 if node.isSymbolized():
  return node
 else:
  return triton.ast.bv(node.evaluate(), node.getBitvectorSize())

if __name__ == '__main__':
 triton.setArchitecture(triton.ARCH.X86_64)
 triton.enableSymbolicOptimization(triton.OPTIMIZATION.ALIGNED_MEMORY, True)
 triton.enableSymbolicOptimization(triton.OPTIMIZATION.ONLY_ON_SYMBOLIZED, True)

 #pintool.startAnalysisFromEntry()
 pintool.startAnalysisFromAddress(MAIN)

 triton.addCallback(constantFolding, triton.CALLBACK.SYMBOLIC_SIMPLIFICATION)
 pintool.insertCall(before, pintool.INSERT_POINT.BEFORE) # Before the instruction processing
 pintool.insertCall(before_symproc, pintool.INSERT_POINT.BEFORE_SYMPROC) # Before the symbolic processing
 pintool.runProgram()

$ triton CrackMe.py ./CrackMe -
rsi =  140734613450744
ARGV1 =  140734613456483
[+] Symbolized 11 bytes of memory at 0x7fff54a48663
[+] Taking snapshot
[+] Wrong password
[+] Posible solution: @@@ @@@@@ @ - 4040402040404040402040
[+] Injecting it and restoring snapshot
[+] Wrong password
[+] Posible solution: B*@!o@@A H; - 422a40216f40404120483b
[+] Injecting it and restoring snapshot
[+] Wrong password
[+] Posible solution: @@'@_H.@r\O - 404027405f482e40725c4f
[+] Injecting it and restoring snapshot
[+] Wrong password
[+] Posible solution: AQ%!$HD zR9 - 41512521244844207a5239
[+] Injecting it and restoring snapshot
[+] Wrong password
[+] Posible solution: Ui(1\GDAp^@ - 556928315c474441705e40
[+] Injecting it and restoring snapshot
[+] Wrong password
[+] Posible solution: 9\*(00 'xA& - 395c2a2830302027784126
[+] Injecting it and restoring snapshot
[+] Wrong password
[+] Posible solution: 7T"W8$$Bl9  - 37542257382424426c3920
[+] Injecting it and restoring snapshot
[+] Wrong password
[+] Posible solution: 0=#E$/oDy8% - 303d2345242f6f44793825
[+] Injecting it and restoring snapshot
[+] Wrong password
[+] Posible solution: 5G1x:)lgy@  - 354731783a296c67794020
[+] Injecting it and restoring snapshot
[+] Wrong password
[+] Posible solution: Gx/t0TRoqq( - 47782f743054526f717128
[+] Injecting it and restoring snapshot
[+] Wrong password
[+] Posible solution: or9t0NRo{kP - 6f723974304e526f7b6b50
[+] Injecting it and restoring snapshot
[+] Wrong password
[+] Posible solution: Tr;t0NRo}k5 - 54723b74304e526f7d6b35
[+] Injecting it and restoring snapshot
[+] Wrong password
[+] Posible solution: Tr!t0NRock5 - 54722174304e526f636b35
[+] Injecting it and restoring snapshot
[+] Good password:  Tr!t0NRock5

References

http://blackbunny.io/solving-a-crack-me-with-triton-and-pin-a-k-a-the-lazy-way/
https://github.com/black-bunny/First-hands-with-Triton

# TumCTF 2k16 - zwiebel (55)


$ wget 'https://2016.ctf.link/assets/files/zwiebel.tar.xz'
$ tar xvf zwiebel.tar.xz
$ r2 -wA zwiebel
[0x004006d0]> s sym.imp.ptrace
[0x004006b0]> pd 3
/ (fcn) sym.imp.ptrace 48
|   sym.imp.ptrace ();
|           ; CALL XREF from 0x004007db (sym.__printf)
|           0x004006b0      ff25aa0b2000   jmp qword [reloc.ptrace_96] ; [0x601260:8]=0x4006b6 LEA reloc.ptrace_96 ; reloc.ptrace_96
|           0x004006b6      6808000000     push 8
\           0x004006bb      e960ffffff     jmp 0x400620                ; sym.imp.printf-0x40
[0x004007d0]> s sym.__printf
[0x004007d0]> pd 12
/ (fcn) sym.__printf 45
|   sym.__printf ();
|           0x004007d0      50             push rax
|           0x004007d1      31ff           xor edi, edi
|           0x004007d3      31f6           xor esi, esi
|           0x004007d5      31d2           xor edx, edx
|           0x004007d7      31c9           xor ecx, ecx
|           0x004007d9      31c0           xor eax, eax
|           0x004007db      e8d0feffff     call sym.imp.ptrace
|           0x004007e0      4885c0         test rax, rax
|       ,=< 0x004007e3      7504           jne 0x4007e9
|       |   0x004007e5      31c0           xor eax, eax
|       |   0x004007e7      5a             pop rdx
|       |   0x004007e8      c3             ret

[0x004007db]> s 0x004007db
[0x004007db]> wx 90909090909090909090
[0x004007db]> pd 19 @ sym.__printf
/ (fcn) sym.__printf 45
|   sym.__printf ();
|           0x004007d0      50             push rax
|           0x004007d1      31ff           xor edi, edi
|           0x004007d3      31f6           xor esi, esi
|           0x004007d5      31d2           xor edx, edx
|           0x004007d7      31c9           xor ecx, ecx
|           0x004007d9      31c0           xor eax, eax
|           0x004007db      90             nop
|           0x004007dc      90             nop
|           0x004007dd      90             nop
|           0x004007de      90             nop
|           0x004007df      90             nop
|           0x004007e0      90             nop
|           0x004007e1      90             nop
|           0x004007e2      90             nop
|           0x004007e3      90             nop
|           0x004007e4      90             nop
|           0x004007e5      31c0           xor eax, eax
|           0x004007e7      5a             pop rdx
|           0x004007e8      c3             ret

$ cat zwiebel.py
import re
import r2pipe
import sys

def convert2int(value):
 if '0x' in value: t = 16
 else: t = 10
 return int(value, t)

def step():
 r2.cmd('ds')
 r2.cmd('sr rip')

r2 = r2pipe.open(filename = '', flags = ['-dA', 'rarun2', 'program=zwiebel', 'stdin="AAAA"'])
r2.cmd('dc')
r2.cmd('db 0x00400875')
r2.cmd('dc')

flag = [0x20] * 50

while True:
 while True:
  step()
  ci = r2.cmdj('pdj 1~:0')[0]
  o = ci['opcode']
  #print o
  ot = ci['type']
  if ot == 'cjmp':
   m = re.search('\[(.*)\]', r2.cmdj('pdj -2~:0')[0]['opcode'])
   #print m[0]
   mask = convert2int(r2.cmdj('pdj -1~:0')[0]['opcode'].split()[2])
   if '+' in m.group(1):
    offset = convert2int(m.group(1).split()[2])
   else:
    offset = 0
   #print offset
   o = o.split(' ')
   j = o[0]
   a = o[1]
   #print o, j, a
   if j == 'je':
    r2.cmd('dr zf=0')
    flag[offset] |= mask

   elif j == 'jne':
    r2.cmd('dr zf=1')
    flag[offset] &= (~mask & 0xff)
   step()
   break

 r = r2.cmdj('pdj 8')
 a = r[7]['offset']
 r2.cmd('db ' + hex(a))
 r2.cmd('dc')
 step()
 sys.stdout.write('\r' + ''.join(map(chr,flag)))

print
r2.quit()

$ python zwiebel.py 2> /dev/null
hxp{1_h0p3_y0u_d1dnt_p33l_th3_0ni0n_by_h4nd}

Reference

https://www.youtube.com/watch?v=y69uIxU0eI8

# Ekoparty pre-challenges 2k16 - roboto (80)


$ wget 'https://ctf.ekoparty.org/static/pre-ekoparty/roboto.elf'
$ sudo apt-get install binutils-avr
$ avr-objdump --disassemble-all roboto.elf | less

$ cat roboto.py
import re
import r2pipe

def get_instruction():
 i = r2.cmdj('pdj 1~:0')[0]
 return int(i['offset']), i['opcode'].split()

def get_value(wv, dv):
 if wv == 0x1 and dv == 0x96:
  return '-'
 elif wv == 0x1 and dv == 0xa:
  return '.'
 elif wv == 0x0 and dv == 0x28:
  return ' '
 else:
  return ''

def step(v = 1):
 r2.cmd('so ' + str(v))

BEGIN = '0x00000fba'
END = int('0x00001a46' , 16)

a = 0
code = ''

r2 = r2pipe.open(filename = 'roboto.elf', flags = ['-A'])

r2.cmd('s ' + BEGIN)

while a != END:
 a, o = get_instruction()
 #print a, o
 wv = int(o[2], 16)
 step(2)
 a, o = get_instruction()
 #print a, o
 dv = int(o[2], 16)
 step(5)
 a, o = get_instruction()
 #print a, o
 if 'ser' in o[0]:
  # add space
  dv *= 2
  step(5)
  a, o = get_instruction()
 # add value
 code += get_value(wv, dv)

print 'morse = ' + code

r2.quit()

$ python roboto.py 2> /dev/null
morse = . -.- --- -.--. --- .-.. -.. .-.-.- .. ... .-.-.- -. . .-- .-.-.- .- --. .- .. -. -.--.-

$ git clone https://github.com/morse-talk/morse-talk.git
$ cd morse_talk
$ sed -i -e '0,/-.--.-/ s/-.--.-/-.--./' morse_talk/encoding.py # Wrong left parenthesis

$ ipython
In [1]: import morse_talk

In [2]: morse_talk.decode('. -.- --- -.--. --- .-.. -.. .-.-.- .. ... .-.-.- -. . .-- .-.-.- .- --. .- .. -. -.--.-').replace('(', '{').replace(')', '}').replace('.', '_')
Out[2]: 'EKO{OLD_IS_NEW_AGAIN}'

# Ekoparty pre-challenges 2k16 - backdoor (50)


$ cat solver.py
from z3 import *

## Defining and initializing

flag = []
for i in range(18):
 flag.append(Int('v%.2d' % i))

s = Solver()

# Constraints

s.add(flag[0] == 69)
s.add(flag[1] == 75)
s.add(flag[1] + flag[2] == 154)
s.add(flag[2] + flag[3] == 202)
s.add(flag[3] + flag[4] == 241)
s.add(flag[4] + flag[5] == 233)
s.add(flag[5] + flag[6] == 217)
s.add(flag[6] + flag[7] == 218)
s.add(flag[7] + flag[8] == 228)
s.add(flag[8] + flag[9] == 212)
s.add(flag[9] + flag[10] == 195)
s.add(flag[10] + flag[11] == 195)
s.add(flag[11] + flag[12] == 201)
s.add(flag[12] + flag[13] == 207)
s.add(flag[13] + flag[14] == 203)
s.add(flag[14] + flag[15] == 215)
s.add(flag[15] + flag[16] == 235)
s.add(flag[16] + flag[17] == 242)

# Checking and printing

if s.check() == sat:
 m = s.model()
 #print m
 for v in m:
  print v, m[v]
  p = int(str(v)[1:])
  v = chr(int(str(m[v])))
  flag[p] = v

 print flag
 print ''.join(flag)

$ python solver.py
v17 125
v16 117
v15 118
v14 97
v13 106
v12 101
v11 100
v10 95
v09 100
v08 112
v07 116
v06 102
v05 115
v04 118
v03 123
v02 79
v01 75
v00 69
['E', 'K', 'O', '{', 'v', 's', 'f', 't', 'p', 'd', '_', 'd', 'e', 'j', 'a', 'v', 'u', '}']
EKO{vsftpd_dejavu}

Reference

http://jolmos.blogspot.com.es/2016/10/vsftpd-backdoor-ekoparty-prectf.html

# Riscure hack me 2 (quals)


Download

# wget https://github.com/Riscure/Rhme-2016/raw/master/RHme2_prequalification_challenge
# file RHme2_prequalification_challenge
RHme2_prequalification_challenge: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=d2e181c26c49dbf067beaba93387f7ef75bc3a91, not stripped

Option 1: Hopper and gdb

# strings RHme2_prequalification_challenge | grep Well
Well done! You found the secret password!

1. Load the binary using hopper.
2. Search the previous string.
3. Go to the address where is referenced (0x400855).
4. Do a decompilation:

int main() {
    stack[2047] = rbx;
    rsp = rsp - 0x8 - 0x1b0;
    rbx = arg_32;
    rax = 0x0;
    asm{ rep stosq  qword [ds:rdi], rax };
    do {
            rsi = sign_extend_64(rax);
            rdx = rax << 0x4 | rax;
            rax = rax + 0x1;
            *(int8_t *)(rsi + 0x601080) = rdx ^ *(int8_t *)(rsi + 0x601080) & 0xff;
    } while (rax != 0x20);
    AES_set_decrypt_key(0x601080, 0x100, var_4);
    AES_decrypt(arg_30, rbx, var_4);
    puts("What is the secret password?");
    fgets(arg_42, 0x50, *__TMC_END__);
    if (memcmp(arg_42, rbx, 0x10) != 0x0) {
            __printf_chk(0x1, "\nThat is not correct!");
    }
    else {
            __printf_chk(0x1, "\nWell done! You found the secret password!");
    }
    rax = 0x0;
    rbx = stack[1993] ^ *0x28;
    COND = rbx != 0x0;
    if (COND) {
            rax = __stack_chk_fail();
    }
    return rax;
}
5. Find the address where memcmp is called:
000000000040081d         call       j_memcmp
# gdb ./RHme2_prequalification_challenge
(gdb) b *0x40081d
(gdb) run
What is the secret password?
IDONTKNOW

Breakpoint 1, 0x000000000040081d in main ()
(gdb) x/s $rbx
0x7fffffffe508: "TH1S 1s s3cr3t!!"

Option 2: LD_PRELOAD

# cat mylib.c
int memcmp(const void *s1, const void *s2, int n){
    printf("%s\n", s1);
    printf("%s\n", s2);
}
# gcc -fPIC -shared mylib.c -o mylib.dylib
# LD_PRELOAD=/tmp/mylib.dylib ./RHme2_prequalification_challenge
What is the secret password?
IDONTKNOW
IDONTKNOW

TH1S 1s s3cr3t!!

That is not correct!

Option 3: Frida

# cat hook.py
import frida
import sys

process = sys.argv[1]
address = str(int(sys.argv[2], 16))

session = frida.attach(process)
script = session.create_script('''
Interceptor.attach(ptr("''' + address + '''"), {
    onEnter: function(args) {
        // User password
        send(Memory.readCString(args[0]));
        // Secret password
        send(Memory.readCString(args[1]));
    }
});
''')

def on_message(message, data):
    print message['payload'].strip()

script.on('message', on_message)
script.load()
sys.stdin.read()

# ./RHme2_prequalification_challenge
What is the secret password?
IDONTKNOW

That is not correct!

# python hook.py RHme2_prequalification_challenge 0x400730
IDONTKNOW
TH1S 1s s3cr3t!!

Option 4: Radare

# r2 -d ./RHme2_prequalification_challenge
Process with PID 31679 started...
attach 31679 31679
bin.baddr 0x00400000
Assuming filepath ./RHme2_prequalification_challenge
asm.bits 64
[0x7f6fa0ec02d0]> dcu sym.imp.memcmp
Continue until 0x00400730 using 1 bpsize
What is the secret password?
IDONTKNOW
hit breakpoint at: 400730
attach 31679 1
[0x00400730]> ps @ rbx
TH1S 1s s3cr3t!!

Reference

https://www.riscure.com/challenge

# NN2k16 CTF - moneymoneymoney (extra) (55pts)


# cat moneymoneymoney.py
#!/usr/bin/python

import base58
import bs4
import pyblake2
import re
import requests
import socket
import sys
import uu

def base58encode(hex_addr):
 ha = hex_addr[::-1]
 return base58.b58encode(ha.decode('hex'))


def crack_blake2(bh):
 a = ['0', '1', '2', '3','4','5','6','7','8','9','a','b','c','d','e','f']
 for i1 in a:
     for i2 in a:
  for i3 in a:
      for i4 in a:
   for i5 in a:
       for i6 in a:
    p = i1+i2+i3+i4+i5+i6
    if pyblake2.blake2b(p).hexdigest() == bh:
        return p

def get_bitcoins(addr):
 r = requests.get('https://blockchain.info/address/' + addr)
 soup = bs4.BeautifulSoup(r.text)
 tag = soup.findAll('span', {'data-c': True})
 m = re.findall('>(.*) BTC<', str(tag[1]))
 #return m[0].replace(',', '')
 return m[0]

def rot(text, n):
 I = 32
 F = 126
 a = []

 for i in xrange(I, F + 1):
  a.append(chr(i))

 result = ''
 for i in text:
  oi = ord(i)
  if I <= oi and oi <= F:
   r = (oi - I + n) % len(a)
   result += a[r]
  else:
   result += i
 return result

def shamir_secret(ss1, ss2):
 payload = {'message': ss1[2:] + '\r\n' + ss2[2:]}
 r = requests.post('http://asecuritysite.com/encryption/shamir_decode', data = payload)
 m = re.findall('share of 2: (.*?)\n<', r.text)
 flag = m[0]
 return flag

def uudecode(encoded):
 ui = 'uu.in'
 uo = 'uu.out'

 f = open(ui, 'w')
 f.write(encoded)
 f.close()

 uu.decode(ui, uo)

 f = open(uo)
 decoded = f.read()
 f.close()

 return decoded

def xor(text, key):
 r = ''
 lk = len(key)
 for i in range(len(text)):
  r += chr(ord(text[i]) ^ ord(key[i % lk]))
 return r


HOST = 'challenges.ka0labs.org'
PORT = 1337
DELIMITER = '-' * 32

server_socket = (HOST, PORT)

print server_socket
print DELIMITER

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(server_socket)

data = client.recv(1024)

print data
print DELIMITER

m = re.findall('= (.*?)\.', data)
blake2_hash = m[0]

print '[+] blake2 hash = ' + blake2_hash 

x = crack_blake2(blake2_hash)

print '[+] x = ' + x
print DELIMITER

client.send(x + '\n')
data = client.recv(1024)
print data
print DELIMITER

m = re.findall('(1-000.*?)\.', data)
shamir_secret_1 = m[0]
print '[+] shamir secret 1 = ' + shamir_secret_1
print DELIMITER

data = client.recv(1024)
print data
print DELIMITER

m = re.findall('([0-9A-Z]+00A)', data)
challenge = m[0]
print '[+] shamir secret 1 = ' + shamir_secret_1
print '[+] challenge = ' + challenge
print DELIMITER

hex_challenge = challenge.decode('hex')
print '[+] hex_challenge = ' + hex_challenge
print DELIMITER

rot52 = rot(hex_challenge, 52)
print '[+] rot52 = ', rot52
print DELIMITER

uud = uudecode(rot52[22:])
print '[+] uudecode = ', uud
print DELIMITER

byte_uud = ''.join(map(chr, map(int, uud[11:].split(','))))
print '[+] byte_uud = ', repr(byte_uud)
print DELIMITER

xored = xor(byte_uud, 'ANDYRLZ')
print '[+] xored = ', xored
print DELIMITER

hex_addr = xored[18:]
bitcoin_addr = base58encode(hex_addr)
print '[+] bitcoin addr = ' + hex_addr + ' --> ' + bitcoin_addr
print DELIMITER

bitcoins = get_bitcoins(bitcoin_addr)
print '[+] bitcoins = ' + bitcoins
print DELIMITER

client.send(bitcoins + '\n')
data = client.recv(1024)
print data
print DELIMITER

m = re.findall('\((.*)\)', data)
shamir_secret_2 = m[0]
print '[+] shamir secret 2 = ' + shamir_secret_2
print DELIMITER
client.close()

flag = shamir_secret(shamir_secret_1, shamir_secret_2)
print '[+] flag = 8===D{' + flag + '}'


# python moneymoneymoney.py
('challenges.ka0labs.org', 1337)
--------------------------------

Welcome to the Dr. Utonium computer! As he usually says, passwords are out-of-style nowadays. So I'm going to test if you're my lovely boss through crypto challenges that only him can solve <3

First of all, let's fight fire with fire. BLAKE2B(X) = b8d1e72b927e9dd122fd4e7cb7574c9b768ad677cf9c0b5435d00c31f0be854efff199ab23dd8f8aa2843321345803b0ad7fd0c0cd3d4090038db421632a68cd. Let me know X. Hint: my $X =~ ^[0-9a-f]{6}$
Solution: 
--------------------------------
[+] blake2 hash = b8d1e72b927e9dd122fd4e7cb7574c9b768ad677cf9c0b5435d00c31f0be854efff199ab23dd8f8aa2843321345803b0ad7fd0c0cd3d4090038db421632a68cd
[+] x = 8d40cf
--------------------------------


Auto-attaching to session 2...
irssi | MojoJojo@CP3kc2.F5htj.virtual (Ka0chat)
<+MojoJojo> Hi my little minion! I have info that can be useful for you. I don't know when, but I'm sure you are going to need what I found last month sniffing Utonium's communications: 1-000O4LkoDev88CEhevvRqbVSc/Fbh+BS47N0NL0jUoQneR9/Ah+yoYr3qDxzlHJ3EI0MITTz4kCwmxHdKye02rjZIMmduk=. I don't know what it means...:_S
Detaching...

--------------------------------
[+] shamir secret 1 = 1-000O4LkoDev88CEhevvRqbVSc/Fbh+BS47N0NL0jUoQneR9/Ah+yoYr3qDxzlHJ3EI0MITTz4kCwmxHdKye02rjZIMmduk=
--------------------------------

Hmmm...ok, here is your challenge. Hint: !yenom eht em wohS

49657021204E657874212074313C4C4B793144404C4B2E3133353A4B6161614B580A785D61607B535D4C5964626C20535D4B24564E5B7E564E5F7D564E4F7D574D7B7C575E5B77576D7B22577D7B21587D7B21594D7B7C574E4F77575E537C0A78564E537B564E5F77576E4B77574D7B7D564E4F7B575D7B7C576E4F77575E4B7E564E5B23564E4F7B585D7B7E586D7B20584D7B7C575E6B77575E4B200A78564E6F22564E5B23564E4F7B587D7B7E585D7B7C576E4B77575E4F25564E4F7B584D7B20595D7B7C575E6377575E4B22564E5723564E4F7C594D7B7C0A78576E5F77595E6777595E6F77584E4F77575E4B24564E4F7C586D7B7C575E6B77575E4F21564E5F22564E4F7B587D7B20576D7B22576D7B7E595D7B7C0A78576E5F77577E5777586E4F77575E4B7B564E4F7C586D7B22576D7B7C575E6F77575E4F24564E4F7C595D7B7C574E6777585E5377575E5322564E6F240A5E564E4F7C586D7B7C576E6377575E4F7E564E4F7B585D7B25594B4B4B0A4B0A313A300A

Solution: 
--------------------------------
[+] shamir secret 1 = 1-000O4LkoDev88CEhevvRqbVSc/Fbh+BS47N0NL0jUoQneR9/Ah+yoYr3qDxzlHJ3EI0MITTz4kCwmxHdKye02rjZIMmduk=
[+] challenge = 49657021204E657874212074313C4C4B793144404C4B2E3133353A4B6161614B580A785D61607B535D4C5964626C20535D4B24564E5B7E564E5F7D564E4F7D574D7B7C575E5B77576D7B22577D7B21587D7B21594D7B7C574E4F77575E537C0A78564E537B564E5F77576E4B77574D7B7D564E4F7B575D7B7C576E4F77575E4B7E564E5B23564E4F7B585D7B7E586D7B20584D7B7C575E6B77575E4B200A78564E6F22564E5B23564E4F7B587D7B7E585D7B7C576E4B77575E4F25564E4F7B584D7B20595D7B7C575E6377575E4B22564E5723564E4F7C594D7B7C0A78576E5F77595E6777595E6F77584E4F77575E4B24564E4F7C586D7B7C575E6B77575E4F21564E5F22564E4F7B587D7B20576D7B22576D7B7E595D7B7C0A78576E5F77577E5777586E4F77575E4B7B564E4F7C586D7B22576D7B7C575E6F77575E4F24564E4F7C595D7B7C574E6777585E5377575E5322564E6F240A5E564E4F7C586D7B7C576E6377575E4F7E564E4F7B585D7B25594B4B4B0A4B0A313A300A
--------------------------------
[+] hex_challenge = Iep! Next! t1<LKy1D@LK.135:KaaaKX
x]a`{S]LYdbl S]K$VN[~VN_}VNO}WM{|W^[wWm{"W}{!X}{!YM{|WNOwW^S|
xVNS{VN_wWnKwWM{}VNO{W]{|WnOwW^K~VN[#VNO{X]{~Xm{ XM{|W^kwW^K 
xVNo"VN[#VNO{X}{~X]{|WnKwW^O%VNO{XM{ Y]{|W^cwW^K"VNW#VNO|YM{|
xWn_wY^gwY^owXNOwW^K$VNO|Xm{|W^kwW^O!VN_"VNO{X}{ Wm{"Wm{~Y]{|
xWn_wW~WwXnOwW^K{VNO|Xm{"Wm{|W^owW^O$VNO|Y]{|WNgwX^SwW^S"VNo$
^VNO|Xm{|WncwW^O~VNO{X]{%YKKK
K
1:0

--------------------------------
[+] rot52 =  }:EUT#:MIUTIep! Next! begin 666 -
M265P(2!.97AT(2 X+#0S+#4R+#$R,"PQ,30L,BPV,RPU-RPU."PQ,#$L,3(Q
M+#(P+#4L,C L,"PR+#$P,2PQ,C$L,3 S+#0W+#$P-2PS-BPT-"PQ,3@L,3 T
M+#DV+#0W+#$P-RPS-2PQ,C L,3$Y+#$P-"PT.2PQ,38L,3 V+#,W+#$Q."PQ
M,C4L.3<L.3DL-#$L,3 X+#$Q-BPQ,3@L,3$U+#4V+#$P-RPT,BPV,BPS.2PQ
M,C4L,S,L-C$L,3 P+#$Q-BPV,BPQ,3DL,3$X+#$Q.2PQ,#<L-3(L,3(V+#DX
3+#$Q-BPQ,C8L,3$S+#$P-2PY.   
 
end

--------------------------------
[+] uudecode =  Iep! Next! 8,43,52,120,114,2,63,57,58,101,121,20,5,20,0,2,101,121,103,47,105,36,44,118,104,96,47,107,35,120,119,104,49,116,106,37,118,125,97,99,41,108,116,118,115,56,107,42,62,39,125,33,61,100,116,62,119,118,119,107,52,126,98,116,126,113,105,98
--------------------------------
[+] byte_uud =  "\x08+4xr\x02?9:ey\x14\x05\x14\x00\x02eyg/i$,vh`/k#xwh1tj%v}ac)ltvs8k*>'}!=dt>wvwk4~bt~qib"
--------------------------------
[+] xored =  Iep! Next! FINAL! 5c3eb212c1b631c80d8981e6587a9fdf3ed68d6832f2850500
--------------------------------
[+] bitcoin addr = 5c3eb212c1b631c80d8981e6587a9fdf3ed68d6832f2850500 --> 18KphVHKBw2brgxc2SQtEWWijQYA8LMsFa
--------------------------------
[+] bitcoins = 0.67472019
--------------------------------
YEAH! 8===D{Shamir(2-00124TdmxdOWx6fO3Ju/OPaW1kutWmNKsWrhLxH2W+T7R4QfQ/+NzDebCfTltfTKbgukGlR4yweJn3UW1qw2s5TBCnSQUw=)}

--------------------------------
[+] shamir secret 2 = 2-00124TdmxdOWx6fO3Ju/OPaW1kutWmNKsWrhLxH2W+T7R4QfQ/+NzDebCfTltfTKbgukGlR4yweJn3UW1qw2s5TBCnSQUw=
--------------------------------
[+] flag = 8===D{Enc0ders_D0_N0t_G1v3_R34l_Secur1ty_But_S3cret_Shar1ng_M4ybe_D03s}


Known-plaintext attack

# ipython

In [1]: challenge = '49657021204E657874212074313C4C4B793144404C4B2E3133353A4B6161614B580A785D61607B535D4C5964626C20535D4B24564E5B7E564E5F7D564E4F7D574D7B7C575E5B77576D7B22577D7B21587D7B21594D7B7C574E4F77575E537C0A78564E537B564E5F77576E4B77574D7B7D564E4F7B575D7B7C576E4F77575E4B7E564E5B23564E4F7B585D7B7E586D7B20584D7B7C575E6B77575E4B200A78564E6F22564E5B23564E4F7B587D7B7E585D7B7C576E4B77575E4F25564E4F7B584D7B20595D7B7C575E6377575E4B22564E5723564E4F7C594D7B7C0A78576E5F77595E6777595E6F77584E4F77575E4B24564E4F7C586D7B7C575E6B77575E4F21564E5F22564E4F7B587D7B20576D7B22576D7B7E595D7B7C0A78576E5F77577E5777586E4F77575E4B7B564E4F7C586D7B22576D7B7C575E6F77575E4F24564E4F7C595D7B7C574E6777585E5377575E5322564E6F240A5E564E4F7C586D7B7C576E6377575E4F7E564E4F7B585D7B25594B4B4B0A4B0A313A300A'

In [2]: hex_challenge = challenge.decode('hex')

In [3]: %paste
def rot(text, n):
        I = 32
        F = 126
        a = []

        for i in xrange(I, F + 1):
                a.append(chr(i))

        result = ''
        for i in text:
                oi = ord(i)
                if I <= oi and oi <= F:
                        r = (oi - I + n) % len(a)
                        result += a[r]
                else:
                        result += i
        return result
## -- End pasted text --


In [4]: for i in xrange(126 - 32)
 print rot(hex_challenge, i)
 print i
 print '-' * 20
 raw_input()

...

50
--------------------

|9DTS"9LHTSHdo ~Mdws ~adfhm~555~,
L154O'1 -86@S'1~W*"/R*"3Q*"#Q+!OP+2/K+AOU+QOT,QOT-!OP+"#K+2'P
L*"'O*"3K+B~K+!OQ*"#O+1OP+B#K+2~R*"/V*"#O,1OR,AOS,!OP+2?K+2~S
L*"CU*"/V*"#O,QOR,1OP+B~K+2#X*"#O,!OS-1OP+27K+2~U*"+V*"#P-!OP
L+B3K-2;K-2CK,"#K+2~W*"#P,AOP+2?K+2#T*"3U*"#O,QOS+AOU+AOR-1OP
L+B3K+R+K,B#K+2~O*"#P,AOU+AOP+2CK+2#W*"#P-1OP+";K,2'K+2'U*"CW
2*"#P,AOP+B7K+2#R*"#O,1OX-~~~
~
dmc

51
--------------------

}:EUT#:MIUTIep! Next! begin 666 -
M265P(2!.97AT(2 X+#0S+#4R+#$R,"PQ,30L,BPV,RPU-RPU."PQ,#$L,3(Q
M+#(P+#4L,C L,"PR+#$P,2PQ,C$L,3 S+#0W+#$P-2PS-BPT-"PQ,3@L,3 T
M+#DV+#0W+#$P-RPS-2PQ,C L,3$Y+#$P-"PT.2PQ,38L,3 V+#,W+#$Q."PQ
M,C4L.3<L.3DL-#$L,3 X+#$Q-BPQ,3@L,3$U+#4V+#$P-RPT,BPV,BPS.2PQ
M,C4L,S,L-C$L,3 P+#$Q-BPV,BPQ,3DL,3$X+#$Q.2PQ,#<L-3(L,3(V+#DX
3+#$Q-BPQ,C8L,3$S+#$P-2PY.   
 
end

52
--------------------


# ipython

In [1]: byte_uud =  "\x08+4xr\x02?9:ey\x14\x05\x14\x00\x02eyg/i$,vh`/k#xwh1tj%v}ac)ltvs8k*>'}!=dt>wvwk4~bt~qib"

In [2]: r = byte_uud

In [3]: %paste
def xor(text, key):
 r = ''
 lk = len(key)
 for i in range(len(text)):
  r += chr(ord(text[i]) ^ ord(key[i % lk]))
 return r
## -- End pasted text --

In [4]: find = 'Iep! Next!'

In [5]: %paste
keys = []

for i in xrange(len(r)):
 key = xor(r[i:i+len(find)], find)
 if len(key) == len(find):
  keys.append(key)

for k in keys:
 for i in xrange(len(find)):
  nk = k[i:]+k[:i]
  result = xor(r, nk)
  if find in result:
   print '-----------------------------', nk
   print result
   raw_input()
## -- End pasted text --
----------------------------- ANDYRLZAND
Iep! Next!8ZAMRN?8)k(jh/:,u*m<6&u-8i,</'h"0/!t1kpc<oy=&r-79/u0&-,=3#
---------------------------------------------------------------------------
KeyboardInterrupt

In [6]: find = 'Iep! Ne'

In [7]: %paste
keys = []

for i in xrange(len(r)):
 key = xor(r[i:i+len(find)], find)
 if len(key) == len(find):
  keys.append(key)

for k in keys:
 for i in xrange(len(find)):
  nk = k[i:]+k[:i]
  result = xor(r, nk)
  if find in result:
   print '-----------------------------', nk
   print result
   raw_input()
## -- End pasted text --
----------------------------- ANDYRLZ
Iep! Next! FINAL! 5c3eb212c1b631c80d8981e6587a9fdf3ed68d6832f2850500

# NN2k16 CTF - chemical x (crypto) (80pts)


# wget 'https://challenges.ka0labs.org/download?file=moji.png

# r2 -w moji.png

[0x00000000]> px
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x00000000  4954 535f 415f 4b45 593f 000d 4948 4452  ITS_A_KEY?..IHDR

[0x00000000]> wx 8950 4e47 0d0a 1a0a 0000

# git clone https://github.com/cyberinc/cloacked-pixel.git

# python cloacked-pixel/lsb.py extract moji.png hide_info ITS_A_KEY?
[+] Image size: 589x385 pixels.
[+] Written extracted data to hide_info.

# cat hide_info
Well done! Next step:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCx5QBxa6pHCE8k9yteQH1EYY+J5HKTsmJXIklWW7oOSozg4kTdyQ8KS8cSsSwLFB7RWS9R09sBC3SuslFqoUNg9WF6HfggqwFcQrYr/Y219QrKUHdGc4Ww2VMMsu1Z7J/CdoCaVOtvzorrRn84D1Yup/O4mElJtFKPqVRexPH4nQ==nope@challenges.ka0labs.org

# mv hide_info rsa.pub

# git clone https://github.com/nccgroup/featherduster.git
# apt-get install libncurses-dev
# apt-get install libgmp3-dev
# apt-get install python-gmpy

# ssh-keygen -f rsa.pub -e -m pem | tee rsa.pem
-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBALHlAHFrqkcITyT3K15AfURhj4nkcpOyYlciSVZbug5KjODiRN3JDwpL
xxKxLAsUHtFZL1HT2wELdK6yUWqhQ2D1YXod+CCrAVxCtiv9jbX1CspQd0ZzhbDZ
Uwyy7Vnsn8J2gJpU62/OiutGfzgPVi6n87iYSUm0Uo+pVF7E8fidAgMBAAE=
-----END RSA PUBLIC KEY-----

# python featherduster/featherduster.py rsa.pem
FeatherDuster> autopwn
[+] Analyzing samples...
[+] At least one RSA key was discovered among the samples.
Running module: rsa_fermat
Starting factorization...

Modulus factored!
Found private key:
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCx5QBxa6pHCE8k9yteQH1EYY+J5HKTsmJXIklWW7oOSozg4kTd
yQ8KS8cSsSwLFB7RWS9R09sBC3SuslFqoUNg9WF6HfggqwFcQrYr/Y219QrKUHdG
c4Ww2VMMsu1Z7J/CdoCaVOtvzorrRn84D1Yup/O4mElJtFKPqVRexPH4nQIDAQAB
AoGADoDMA3Myo63ivfHEwF9jlxKZIDXWvYHakJ4D+p1p0sZzK9ZmpOpCZqV86mI1
ZAXU6V5rBDHQdgpYDfINvzK8imVLC6lujEY16RIxDMb8PWVP+TBvvGPZU4tfMJEe
FqjJpqsaWtH70dCMbhrA02/KDT6zV1hwcEdKIrUCI6u+T8ECQQDVZ0PHZbgn1kUy
so1Ylu7fj6L0j3dAVP68/rdC7b7EJDfdGJOPdQ5ev4ZiW5IcCJSVivw0ReTLawR8
PqbVwIgxAkEA1WdDx2W4J9ZFMrKNWJbu34+i9I93QFT+vP63Qu2+w3d+rj9aE3t4
FPzC41P7yAOfTmqN7OlXy2sEfD6m1cCILQJBAMasFaDMJS8JP3DcY9Tm50pAee/+
pIHC30lqRYjMt335TfzLRY0X6CHzYpOtNpBcuJ+kPfoYW9G5NvrIhR+Y1/ECQAzh
suGybi9Za8vno0iZs8mi7f89OcGUX9wgtAdCOqWp7Oevw0wxw8ngiBMY2rX0IgWl
wPNwEnChASBO19tHR/ECQQDStJZH+WDMfOGKwgdIlKXA6KCZSj7e0UkFhpC+B7ml
7N8tPh8OXEKApLBECKZfXI2h/t8mNRubT7oqAtNekotX
-----END RSA PRIVATE KEY-----

# chmod 400 rsa.priv
# ssh -i rsa.priv nope@challenges.ka0labs.org
=== Welcome to Barad-dur ===
The trees are strong, my lord. Their roots go deep...

nope:~$ more ../noruas/flag.txt
nn6ed{RSA_w0rks_Gr34t_1f_You_Us3_It_Pr0perly}