FSOP 공격에 대해서 공부하던 중, puts 함수가 실행될 때 공격이 터지는 것을 보고, puts 함수의 동작 방식을 분석하고, 어떤 부분에서 공격이 터지는 지를 확인해보았습니다.

먼저 처음에는 문자열의 길이를 계산하기 위해 j_strlen 함수를 호출합니다.

실제로 modify finished라는 문자열을 출력하기 위해서 puts가 호출되는데, 이 때문인지 rdi 레지스터에 "modify finished!"라는 문구가 들어가있는 것을 확인할 수 있었습니다.

그리고 반환 값을 보았을 때, 출력하고자 하는 문자열의 길이인 0x10이 반환 레지스터인 RAX에 들어가 있는 것을 확인할 수 있었습니다.
그 다음, 밑에 가다보면 이런 부분이 있습니다.

stdout + 17은 정확히 말하자면 stdout + 0x8 * 17과 동일하며, 이를 gdb로 확인했을 때는 다음과 같습니다.

즉, R8 레지스터에는 stdout 주소가 들어갑니다.
이는 뒤에 _InterlockedCompareExchange에 v5가 인자로 들어가면서 사용됩니다.
그 다음 계속 진행되다가 r14 레지스터에 rdi + 0xd8 값을 넣어줍니다. 이 위치는 _IO_FILE 구조체에서 vtable 필드이며, 현재는 FSOP 공격으로 fake_vtable 주소로 덮어써진 상태입니다.

그리고 후에 r14 + 0x38 부분을 호출합니다. 이 부분은 _IO_wfile_overflow 부분과 일치합니다.

그리고, 이 함수가 호출된 이후에 FSOP 공격이 터지며 쉘을 딸 수 있는 것을 확인했습니다. 따라서 이 _IO_wfile_overflow 함수를 따라가봐야 할 것 같습니다.

또한, _IO_wfile_overflow 내부에서 _IO_wdoallocbuf 함수를 호출하는데, 여기 내부에서 쉘이 따집니다.
__int64 __fastcall IO_wdoallocbuf(__int64 a1)
{
__int64 result; // rax
int v2; // edx
__int64 v3; // rbp
__int64 v4; // r12
result = *(_QWORD *)(a1 + 160);
if ( !*(_QWORD *)(result + 48) )
{
if ( (*(_BYTE *)a1 & 2) != 0 )
{
v2 = *(_DWORD *)(a1 + 116);
v3 = result + 220;
v4 = result + 216;
}
else
{
result = (*(__int64 (**)(void))(*(_QWORD *)(result + 224) + 104LL))();
if ( (_DWORD)result != -1 )
return result;
result = *(_QWORD *)(a1 + 160);
v2 = *(_DWORD *)(a1 + 116);
v3 = result + 220;
v4 = result + 216;
if ( *(_QWORD *)(result + 48) )
{
if ( (v2 & 8) == 0 )
{
j_free();
result = *(_QWORD *)(a1 + 160);
v2 = *(_DWORD *)(a1 + 116);
}
}
}
*(__m128i *)(result + 48) = _mm_unpacklo_epi64((__m128i)(unsigned __int64)v4, (__m128i)(unsigned __int64)v3);
*(_DWORD *)(a1 + 116) = v2 | 8;
}
return result;
}
이 코드에서 else 부분에 result = (*(__int64 (**)(void))(*(_QWORD *)(result + 224) + 104LL))();와 같이 함수를 호출하는 부분이 있습니다. 따라서 결론적으로 저 부분에 원 가젯이나 쉘코드가 들어가면 쉘을 딸 수 있습니다.
'시스템해킹 > 개념' 카테고리의 다른 글
| Unsorted bin 공격 정리 (1) | 2025.07.13 |
|---|---|
| Double Free bug와 Fastbin dup 복습 (0) | 2025.06.25 |
| [Dreamhack-system] Background : _IO_FILE (1) | 2024.12.20 |
| [Dreamhack-system] SigReturn-Oriented Programming (3) | 2024.12.18 |
| [Dreamhack-system] Background : _rtld_global (3) | 2024.12.17 |