하루에 한문제씩 pwnable을 풀기 위해서 문제를 찾던 도중에
다른 블로거분이 올리신 write up을 보고 쉽겠는데?하고 생각을 하고 금방 풀고 작성해 봅니다.
BOF_Command
정말로 간단한 buf overflow + Command Injection 이다.
ida로 열어본 main의 모오습
int __cdecl main(int argc, const char **argv, const char **envp)
{
__uid_t v3; // ebx@1
__uid_t v4; // eax@1
int v6; // [sp+Ch] [bp-B0h]@2
int v7; // [sp+10h] [bp-ACh]@1
char s; // [sp+14h] [bp-A8h]@4
char command[4]; // [sp+3Ch] [bp-80h]@1
__int16 v10; // [sp+40h] [bp-7Ch]@1
__int16 v11; // [sp+42h] [bp-7Ah]@1
int v12; // [sp+44h] [bp-78h]@1
int v13; // [sp+A0h] [bp-1Ch]@1
int *v14; // [sp+B4h] [bp-8h]@1
v14 = &argc;
v13 = *MK_FP(__GS__, 20);
*(_DWORD *)command = 1869112165;
v10 = 0;
v11 = 0;
memset(&v12, 0, 0x5Cu);
v7 = 0;
v3 = geteuid();
v4 = geteuid();
setreuid(v4, v3);
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 1, 0);
puts("Hello It is My Echo system\nMy Echo System may have a bug...\nCan you find it?");
puts("Sleep 3...\n");
sleep(3u);
while ( 1 )
{
system(command); //system함수가 사용됨 이 곳을 이용하자
print_menu();
printf(">> ");
fflush(stdout);
__isoc99_scanf("%d", &v6);
fflush(stdin);
switch ( v6 )
{
case 0:
return 0;
case 1:
memset(&s, 0, 0x28u);
len = read(0, &s, 60u); //overflow발생!!! s를 가득채우고 command부분 까지 덮어 씌울수 있음.
v7 = 1;
break;
case 2:
if ( check_first(v7) )
write(1, &s, len);
break;
case 3:
if ( check_first(v7) )
strrev(&s);
break;
case 4:
if ( check_first(v7) )
strupr(&s);
break;
default:
break;
}
sleep(1u);
}
}
1번 메뉴에서
read를 통해서 s에 A를 40개를 주고 comman부분에 sh을 딱 적어주면
쉘이 뾰로롱 따지게 된다!
easyheap
ida로 열어보자~
int __cdecl main()
{
int v0; // eax@9
int v1; // eax@9
int result; // eax@21
int v3; // ecx@21
int v4; // [sp+18h] [bp-B0h]@4
int v5; // [sp+1Ch] [bp-ACh]@4
int i; // [sp+20h] [bp-A8h]@1
int v7; // [sp+24h] [bp-A4h]@4
int v8; // [sp+28h] [bp-A0h]@4
int j; // [sp+2Ch] [bp-9Ch]@18
char dest[40]; // [sp+30h] [bp-98h]@2
char src; // [sp+58h] [bp-70h]@15
int v12; // [sp+BCh] [bp-Ch]@1
v12 = *MK_FP(__GS__, 20);
puts("HELLO!\n");
for ( i = 0; i <= 9; ++i )
*(_DWORD *)&dest[4 * i] = malloc(0x100u);
v4 = 1;
v7 = 0;
v5 = 0;
v8 = 0;
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 1, 0);
while ( !v8 )
{
sub_804872A();
__isoc99_scanf("%d", &v4);
switch ( v4 )
{
case 2:
printf("id? : ");
__isoc99_scanf("%d", &v5);
if ( v5 <= 10 )
{
printf("\nName : %s", *(_DWORD *)&dest[4 * v5]);
(*(void (__cdecl **)(const char *))(*(_DWORD *)&dest[4 * v5] + 12))("A"); //dest[4*v5]+12에 있는 값을 실행시켜줌!
putchar(10);
}
else
{
puts("\nERROR");
}
break;
case 3:
printf("id? : ");
__isoc99_scanf("%d", &v5);
if ( v5 <= 10 )
{
printf("\nModify : ");
__isoc99_scanf("%100s", &src);
strcpy(*(char **)&dest[4 * v5], &src); //원하는 값을 dest[4*v5]에 줄수 있다.
} //위에서 dest[4*v5]에 있는 값을 실행 시켜주니
else //A를 12개 넣고 flag를 출력해주는 주소를 적어주면 flag가 출력됨!
{
puts("\nERROR");
}
break;
case 1:
*(_DWORD *)(*(_DWORD *)&dest[4 * v7] + 12) = sub_8048711;
v0 = *(_DWORD *)&dest[4 * v7];
*(_DWORD *)v0 = 1634100580;
*(_DWORD *)(v0 + 4) = 7629941;
v1 = v7++;
printf("Created...! id : %d\n", v1);
break;
default:
v8 = 1;
break;
}
}
for ( j = 0; j <= 9; ++j )
free(*(void **)&dest[4 * j]);
result = 0;
v3 = *MK_FP(__GS__, 20) ^ v12;
return result;
}
exploit.py
string을 보니 flag를 출력해주는 곳도 있었다.
그냥 이문제는 heap문제이라고 보기는 좀... 그렇다.
새벽에 푸느라 쉬운 문제를 골라서 한 것 같다.
내일은 어려운 문제를 풀길 빌며.. 끝내겠다.
'SYSTEM HACKING > 문제 풀이' 카테고리의 다른 글
HITCON 2017 - Start (0) | 2018.02.11 |
---|---|
2016 Codegate -Serial (0) | 2018.02.03 |
2016 Codegate -Watermelon (0) | 2018.01.24 |
2017 Codegate -babypwn (0) | 2018.01.12 |
2014 Codegate -nuclear (0) | 2018.01.10 |