ELF 실행 파일에 대한 간단한 코드 인젝션
Source: Dev.to
Example Source
/**
* Simple Code Injection
*/
#include
#include
#include
int main(int argc, char *argv[])
{
int i, num;
num = 10;
for (i = 0; i :
1149: f3 0f 1e fa endbr64
114d: 55 push %rbp
114e: 48 89 e5 mov %rsp,%rbp
1151: 48 83 ec 20 sub $0x20,%rsp
1155: 89 7d ec mov %edi,-0x14(%rbp)
1158: 48 89 75 e0 mov %rsi,-0x20(%rbp)
115c: c7 45 fc 0a 00 00 00 movl $0xa,-0x4(%rbp)
1163: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp)
116a: eb 1d jmp 1189
116c: 8b 45 f8 mov -0x8(%rbp),%eax
116f: 89 c6 mov %eax,%esi
1171: 48 8d 05 8c 0e 00 00 lea 0xe8c(%rip),%rax # 2004
1178: 48 89 c7 mov %rax,%rdi
117b: b8 00 00 00 00 mov $0x0,%eax
1180: e8 cb fe ff ff call 1050
1185: 83 45 f8 01 addl $0x1,-0x8(%rbp)
1189: 8b 45 f8 mov -0x8(%rbp),%eax
118c: 3b 45 fc cmp -0x4(%rbp),%eax
118f: 7c db jl 116c
1191: b8 00 00 00 00 mov $0x0,%eax
1196: c9 leave
1197: c3 ret
Identifying the Instruction to Change
num = 10을 설정하는 명령은 다음과 같습니다:
c7 45 fc 0a 00 00 00 movl $0xa,-0x4(%rbp)
c7– 32‑비트 즉시값을 갖는movl의 opcode.45 fc– 변위-0x4(%rbp).0a 00 00 00– 리틀 엔디안 순서로 저장된 즉시값0x0a(10).
opcode는 주소 0x115c에서 시작하고, 즉시값 바이트 0x0a는 0x115f에 위치합니다.
Modifying the Binary
헥스 에디터로 실행 파일을 열고 0x115f에 있는 바이트(0x0a)를 0x05로 교체합니다:
$ hexedit ./main
오프셋 0x115f로 이동하여 값을 변경하고 저장한 뒤 종료합니다.
Result
패치된 바이너리를 실행하면:
$ ./main
다음과 같이 출력됩니다:
#0
#1
#2
#3
#4
프로그램이 이제 5번만 반복되며, ELF 실행 파일의 머신 코드를 직접 수정함으로써 간단한 코드 인젝션을 수행한 것을 보여줍니다.
Note: 이 기법은 바이트를 교체하면서 바이너리 전체 레이아웃을 변경하지 않을 때만 동작합니다. 명령 길이를 바꾸거나 코드를 재배치해야 하는 경우에는 보다 고급 방법이 필요하며, 이는 다음 기사에서 다룹니다.