macOS MIG - Mach Interface Generator

Tip

AWS ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°:HackTricks Training AWS Red Team Expert (ARTE)
GCP ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: HackTricks Training GCP Red Team Expert (GRTE) Azure ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks μ§€μ›ν•˜κΈ°

Basic Information

MIGλŠ” Mach IPC μ½”λ“œ 생성을 λ‹¨μˆœν™”ν•˜κΈ° μœ„ν•΄ λ§Œλ“€μ–΄μ‘ŒμŠ΅λ‹ˆλ‹€. 기본적으둜 μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈκ°€ μ£Όμ–΄μ§„ μ •μ˜λ‘œ ν†΅μ‹ ν•˜κΈ° μœ„ν•΄ ν•„μš”ν•œ μ½”λ“œλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. μƒμ„±λœ μ½”λ“œκ°€ 보기 μ’‹μ§€ μ•Šλ”λΌλ„, κ°œλ°œμžλŠ” 이λ₯Ό κ°€μ Έμ˜€κΈ°λ§Œ ν•˜λ©΄ 그의 μ½”λ“œλŠ” 이전보닀 훨씬 κ°„λ‹¨ν•΄μ§ˆ κ²ƒμž…λ‹ˆλ‹€.

μ •μ˜λŠ” μΈν„°νŽ˜μ΄μŠ€ μ •μ˜ μ–Έμ–΄(IDL)μ—μ„œ .defs ν™•μž₯자λ₯Ό μ‚¬μš©ν•˜μ—¬ μ§€μ •λ©λ‹ˆλ‹€.

이 μ •μ˜λŠ” 5개의 μ„Ήμ…˜μœΌλ‘œ κ΅¬μ„±λ©λ‹ˆλ‹€:

  • μ„œλΈŒμ‹œμŠ€ν…œ μ„ μ–Έ: ν‚€μ›Œλ“œ subsystem은 이름과 idλ₯Ό λ‚˜νƒ€λ‚΄λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€. μ„œλ²„κ°€ μ»€λ„μ—μ„œ μ‹€ν–‰λ˜μ–΄μ•Ό ν•˜λŠ” 경우 **KernelServer**둜 ν‘œμ‹œν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
  • 포함 및 μž„ν¬νŠΈ: MIGλŠ” C μ „μ²˜λ¦¬κΈ°λ₯Ό μ‚¬μš©ν•˜λ―€λ‘œ μž„ν¬νŠΈλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ, μ‚¬μš©μž λ˜λŠ” μ„œλ²„ 생성 μ½”λ“œμ— λŒ€ν•΄ uimport 및 simportλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • νƒ€μž… μ„ μ–Έ: 데이터 νƒ€μž…μ„ μ •μ˜ν•  수 μžˆμ§€λ§Œ, 일반적으둜 mach_types.defs 및 std_types.defsλ₯Ό κ°€μ Έμ˜΅λ‹ˆλ‹€. μ‚¬μš©μž μ •μ˜ νƒ€μž…μ˜ 경우 일뢀 ꡬ문을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€:
  • [in/out]tran: λ“€μ–΄μ˜€λŠ” λ©”μ‹œμ§€ λ˜λŠ” λ‚˜κ°€λŠ” λ©”μ‹œμ§€λ‘œ λ³€ν™˜ν•΄μ•Ό ν•˜λŠ” ν•¨μˆ˜
  • c[user/server]type: λ‹€λ₯Έ C νƒ€μž…μ— λ§€ν•‘.
  • destructor: νƒ€μž…μ΄ ν•΄μ œλ  λ•Œ 이 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•©λ‹ˆλ‹€.
  • μž‘μ—…: RPC λ©”μ„œλ“œμ˜ μ •μ˜μž…λ‹ˆλ‹€. 5κ°€μ§€ μœ ν˜•μ΄ μžˆμŠ΅λ‹ˆλ‹€:
  • routine: 응닡을 κΈ°λŒ€ν•©λ‹ˆλ‹€.
  • simpleroutine: 응닡을 κΈ°λŒ€ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • procedure: 응닡을 κΈ°λŒ€ν•©λ‹ˆλ‹€.
  • simpleprocedure: 응닡을 κΈ°λŒ€ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • function: 응닡을 κΈ°λŒ€ν•©λ‹ˆλ‹€.

Example

μ •μ˜ νŒŒμΌμ„ μƒμ„±ν•©λ‹ˆλ‹€. 이 경우 맀우 κ°„λ‹¨ν•œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€:

subsystem myipc 500; // Arbitrary name and id

userprefix USERPREF;        // Prefix for created functions in the client
serverprefix SERVERPREF;    // Prefix for created functions in the server

#include <mach/mach_types.defs>
#include <mach/std_types.defs>

simpleroutine Subtract(
server_port :  mach_port_t;
n1          :  uint32_t;
n2          :  uint32_t);

첫 번째 μΈμžλŠ” 바인딩할 포트이며 MIGλŠ” 응닡 포트λ₯Ό μžλ™μœΌλ‘œ μ²˜λ¦¬ν•©λ‹ˆλ‹€(ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œμ—μ„œ mig_get_reply_port()λ₯Ό ν˜ΈμΆœν•˜μ§€ μ•ŠλŠ” ν•œ). λ˜ν•œ, μž‘μ—…μ˜ IDλŠ” μ§€μ •λœ μ„œλΈŒμ‹œμŠ€ν…œ IDλΆ€ν„° 순차적으둜 μ‹œμž‘λ©λ‹ˆλ‹€(μž‘μ—…μ΄ 더 이상 μ‚¬μš©λ˜μ§€ μ•ŠλŠ” 경우 μ‚­μ œλ˜κ³  skip이 μ‚¬μš©λ˜μ–΄ μ—¬μ „νžˆ ν•΄λ‹Ή IDλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€).

이제 MIGλ₯Ό μ‚¬μš©ν•˜μ—¬ μ„œλ‘œ 톡신할 수 μžˆλŠ” μ„œλ²„ 및 ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œλ₯Ό μƒμ„±ν•˜μ—¬ Subtract ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ‹­μ‹œμ˜€:

mig -header myipcUser.h -sheader myipcServer.h myipc.defs

ν˜„μž¬ 디렉토리에 μ—¬λŸ¬ 개의 μƒˆλ‘œμš΄ 파일이 μƒμ„±λ©λ‹ˆλ‹€.

Tip

μ‹œμŠ€ν…œμ—μ„œ 더 λ³΅μž‘ν•œ 예제λ₯Ό 찾으렀면: mdfind mach_port.defs
그리고 파일과 λ™μΌν•œ ν΄λ”μ—μ„œ μ»΄νŒŒμΌν•˜λ €λ©΄: mig -DLIBSYSCALL_INTERFACE mach_ports.defs

파일 **myipcServer.c**와 **myipcServer.h**μ—μ„œ μˆ˜μ‹ λœ λ©”μ‹œμ§€ ID에 따라 ν˜ΈμΆœν•  ν•¨μˆ˜λ₯Ό μ •μ˜ν•˜λŠ” ꡬ쑰체 **SERVERPREFmyipc_subsystem**의 μ„ μ–Έ 및 μ •μ˜λ₯Ό 찾을 수 μžˆμŠ΅λ‹ˆλ‹€(μ‹œμž‘ 번호둜 500을 μ§€μ •ν–ˆμŠ΅λ‹ˆλ‹€):

/* Description of this subsystem, for use in direct RPC */
const struct SERVERPREFmyipc_subsystem SERVERPREFmyipc_subsystem = {
myipc_server_routine,
500, // start ID
501, // end ID
(mach_msg_size_t)sizeof(union __ReplyUnion__SERVERPREFmyipc_subsystem),
(vm_address_t)0,
{
{ (mig_impl_routine_t) 0,
// Function to call
(mig_stub_routine_t) _XSubtract, 3, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__Subtract_t)},
}
};

이전 ꡬ쑰λ₯Ό 기반으둜 ν•¨μˆ˜ **myipc_server_routine**은 λ©”μ‹œμ§€ IDλ₯Ό κ°€μ Έμ™€μ„œ ν˜ΈμΆœν•  μ μ ˆν•œ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€:

mig_external mig_routine_t myipc_server_routine
(mach_msg_header_t *InHeadP)
{
int msgh_id;

msgh_id = InHeadP->msgh_id - 500;

if ((msgh_id > 0) || (msgh_id < 0))
return 0;

return SERVERPREFmyipc_subsystem.routine[msgh_id].stub_routine;
}

이 μ˜ˆμ œμ—μ„œλŠ” μ •μ˜μ—μ„œ 1개의 ν•¨μˆ˜λ§Œ μ •μ˜ν–ˆμ§€λ§Œ, 더 λ§Žμ€ ν•¨μˆ˜λ₯Ό μ •μ˜ν–ˆλ‹€λ©΄, κ·Έ ν•¨μˆ˜λ“€μ€ SERVERPREFmyipc_subsystem λ°°μ—΄ μ•ˆμ— μœ„μΉ˜ν–ˆμ„ 것이며, 첫 번째 ν•¨μˆ˜λŠ” ID 500에, 두 번째 ν•¨μˆ˜λŠ” ID 501에 ν• λ‹Ήλ˜μ—ˆμ„ κ²ƒμž…λ‹ˆλ‹€β€¦

ν•¨μˆ˜κ°€ replyλ₯Ό 보내야 ν•œλ‹€λ©΄, ν•¨μˆ˜ mig_internal kern_return_t __MIG_check__Reply__<name>도 μ‘΄μž¬ν•  κ²ƒμž…λ‹ˆλ‹€.

μ‹€μ œλ‘œ 이 κ΄€κ³„λŠ” **myipcServer.h**의 ꡬ쑰체 **subsystem_to_name_map_myipc**μ—μ„œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€ (**λ‹€λ₯Έ νŒŒμΌμ—μ„œλŠ” **`subsystemto_name_map*****둜 ν‘œμ‹œλ¨):

#ifndef subsystem_to_name_map_myipc
#define subsystem_to_name_map_myipc \
{ "Subtract", 500 }
#endif

λ§ˆμ§€λ§‰μœΌλ‘œ, μ„œλ²„κ°€ μž‘λ™ν•˜λ„λ‘ ν•˜λŠ” 또 λ‹€λ₯Έ μ€‘μš”ν•œ κΈ°λŠ₯은 **myipc_server**둜, μ΄λŠ” μˆ˜μ‹ λœ ID와 κ΄€λ ¨λœ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€:

mig_external boolean_t myipc_server
(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP)
{
/*
* typedef struct {
* 	mach_msg_header_t Head;
* 	NDR_record_t NDR;
* 	kern_return_t RetCode;
* } mig_reply_error_t;
*/

mig_routine_t routine;

OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0);
OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port;
/* μ΅œμ†Œ 크기: routine()이 λ‹€λ₯΄λ©΄ μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€ */
OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t);
OutHeadP->msgh_local_port = MACH_PORT_NULL;
OutHeadP->msgh_id = InHeadP->msgh_id + 100;
OutHeadP->msgh_reserved = 0;

if ((InHeadP->msgh_id > 500) || (InHeadP->msgh_id < 500) ||
	    ((routine = SERVERPREFmyipc_subsystem.routine[InHeadP->msgh_id - 500].stub_routine) == 0)) {
		((mig_reply_error_t *)OutHeadP)->NDR = NDR_record;
((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID;
return FALSE;
}
	(*routine) (InHeadP, OutHeadP);
	return TRUE;
}

ID둜 ν˜ΈμΆœν•  ν•¨μˆ˜λ₯Ό μ ‘κ·Όν•˜λŠ” 이전에 κ°•μ‘°λœ 쀄을 ν™•μΈν•˜μ„Έμš”.

λ‹€μŒμ€ ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλ²„μ—μ„œ Subtract ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  수 μžˆλŠ” κ°„λ‹¨ν•œ μ„œλ²„ 및 ν΄λΌμ΄μ–ΈνŠΈλ₯Ό μƒμ„±ν•˜λŠ” μ½”λ“œμž…λ‹ˆλ‹€:

// gcc myipc_server.c myipcServer.c -o myipc_server

#include <stdio.h>
#include <mach/mach.h>
#include <servers/bootstrap.h>
#include "myipcServer.h"

kern_return_t SERVERPREFSubtract(mach_port_t server_port, uint32_t n1, uint32_t n2)
{
printf("Received: %d - %d = %d\n", n1, n2, n1 - n2);
return KERN_SUCCESS;
}

int main() {

mach_port_t port;
kern_return_t kr;

// Register the mach service
kr = bootstrap_check_in(bootstrap_port, "xyz.hacktricks.mig", &port);
if (kr != KERN_SUCCESS) {
printf("bootstrap_check_in() failed with code 0x%x\n", kr);
return 1;
}

// myipc_server is the function that handles incoming messages (check previous exlpanation)
mach_msg_server(myipc_server, sizeof(union __RequestUnion__SERVERPREFmyipc_subsystem), port, MACH_MSG_TIMEOUT_NONE);
}

NDR_record

NDR_recordλŠ” libsystem_kernel.dylib에 μ˜ν•΄ 내보내지며, MIGκ°€ μ‹œμŠ€ν…œμ— λ¬΄κ΄€ν•˜κ²Œ 데이터λ₯Ό λ³€ν™˜ν•  수 μžˆλ„λ‘ ν•˜λŠ” κ΅¬μ‘°μ²΄μž…λ‹ˆλ‹€. MIGλŠ” μ„œλ‘œ λ‹€λ₯Έ μ‹œμŠ€ν…œ 간에 μ‚¬μš©λ˜λ„λ‘ μ„€κ³„λ˜μ—ˆκΈ° λ•Œλ¬Έμ— (같은 λ¨Έμ‹ μ—μ„œλ§Œ μ‚¬μš©λ˜λŠ” 것이 μ•„λ‹™λ‹ˆλ‹€).

이것은 ν₯미둜운데, λ§Œμ•½ _NDR_recordκ°€ 이진 νŒŒμΌμ—μ„œ μ˜μ‘΄μ„±μœΌλ‘œ λ°œκ²¬λœλ‹€λ©΄ (jtool2 -S <binary> | grep NDR λ˜λŠ” nm), μ΄λŠ” ν•΄λ‹Ή 이진 파일이 MIG ν΄λΌμ΄μ–ΈνŠΈ λ˜λŠ” μ„œλ²„μž„μ„ μ˜λ―Έν•©λ‹ˆλ‹€.

κ²Œλ‹€κ°€ MIG μ„œλ²„λŠ” __DATA.__const에 λ””μŠ€νŒ¨μΉ˜ ν…Œμ΄λΈ”μ„ κ°€μ§€κ³  μžˆμŠ΅λ‹ˆλ‹€ (macOS μ»€λ„μ—μ„œλŠ” __CONST.__constdata, λ‹€λ₯Έ *OS μ»€λ„μ—μ„œλŠ” __DATA_CONST.__const에 μžˆμŠ΅λ‹ˆλ‹€). μ΄λŠ” **jtool2**둜 덀프할 수 μžˆμŠ΅λ‹ˆλ‹€.

그리고 MIG ν΄λΌμ΄μ–ΈνŠΈλŠ” __mach_msgλ₯Ό μ‚¬μš©ν•˜μ—¬ μ„œλ²„μ— μ „μ†‘ν•˜κΈ° μœ„ν•΄ __NDR_recordλ₯Ό μ‚¬μš©ν•  κ²ƒμž…λ‹ˆλ‹€.

이진 뢄석

jtool

λ§Žμ€ 이진 파일이 이제 MIGλ₯Ό μ‚¬μš©ν•˜μ—¬ mach 포트λ₯Ό λ…ΈμΆœν•˜λ―€λ‘œ, MIGκ°€ μ‚¬μš©λ˜μ—ˆμŒμ„ μ‹λ³„ν•˜λŠ” 방법과 각 λ©”μ‹œμ§€ ID에 λŒ€ν•΄ MIGκ°€ μ‹€ν–‰ν•˜λŠ” ν•¨μˆ˜λ₯Ό μ•„λŠ” 것이 ν₯λ―Έλ‘­μŠ΅λ‹ˆλ‹€.

jtool2λŠ” Mach-O 이진 νŒŒμΌμ—μ„œ MIG 정보λ₯Ό ꡬ문 λΆ„μ„ν•˜μ—¬ λ©”μ‹œμ§€ IDλ₯Ό ν‘œμ‹œν•˜κ³  μ‹€ν–‰ν•  ν•¨μˆ˜λ₯Ό 식별할 수 μžˆμŠ΅λ‹ˆλ‹€:

jtool2 -d __DATA.__const myipc_server | grep MIG

λ˜ν•œ, MIG ν•¨μˆ˜λŠ” ν˜ΈμΆœλ˜λŠ” μ‹€μ œ ν•¨μˆ˜μ˜ λž˜νΌμ— λΆˆκ³Όν•˜λ―€λ‘œ, ν•΄λ‹Ή ν•¨μˆ˜μ˜ λ””μŠ€μ–΄μ…ˆλΈ”λ¦¬λ₯Ό κ°€μ Έμ˜€κ³  BL을 κ²€μƒ‰ν•˜λ©΄ ν˜ΈμΆœλ˜λŠ” μ‹€μ œ ν•¨μˆ˜λ₯Ό 찾을 수 μžˆμŠ΅λ‹ˆλ‹€:

jtool2 -d __DATA.__const myipc_server | grep BL

Assembly

이전에 μˆ˜μ‹ λœ λ©”μ‹œμ§€ ID에 따라 μ˜¬λ°”λ₯Έ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” κΈ°λŠ₯을 λ‹΄λ‹Ήν•˜λŠ” ν•¨μˆ˜λŠ” myipc_server라고 μ–ΈκΈ‰λ˜μ—ˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 일반적으둜 λ°”μ΄λ„ˆλ¦¬μ˜ 기호(ν•¨μˆ˜ 이름)κ°€ μ—†κΈ° λ•Œλ¬Έμ— λ””μ»΄νŒŒμΌλœ λͺ¨μŠ΅μ΄ μ–΄λ–»κ²Œ μƒκ²ΌλŠ”μ§€ ν™•μΈν•˜λŠ” 것이 ν₯λ―Έλ‘­μŠ΅λ‹ˆλ‹€. 이 ν•¨μˆ˜μ˜ μ½”λ“œλŠ” λ…ΈμΆœλœ ν•¨μˆ˜μ™€λŠ” 독립적이기 λ•Œλ¬Έμ— 항상 맀우 μœ μ‚¬ν•©λ‹ˆλ‹€:

int _myipc_server(int arg0, int arg1) {
var_10 = arg0;
var_18 = arg1;
// μ˜¬λ°”λ₯Έ ν•¨μˆ˜ 포인터λ₯Ό μ°ΎκΈ° μœ„ν•œ 초기 λͺ…λ Ήμ–΄
*(int32_t *)var_18 = *(int32_t *)var_10 & 0x1f;
*(int32_t *)(var_18 + 0x8) = *(int32_t *)(var_10 + 0x8);
*(int32_t *)(var_18 + 0x4) = 0x24;
*(int32_t *)(var_18 + 0xc) = 0x0;
*(int32_t *)(var_18 + 0x14) = *(int32_t *)(var_10 + 0x14) + 0x64;
*(int32_t *)(var_18 + 0x10) = 0x0;
if (*(int32_t *)(var_10 + 0x14) <= 0x1f4 && *(int32_t *)(var_10 + 0x14) >= 0x1f4) {
rax = *(int32_t *)(var_10 + 0x14);
// 이 ν•¨μˆ˜λ₯Ό μ‹λ³„ν•˜λŠ” 데 도움이 λ˜λŠ” sign_extend_64 호좜
// μ΄λŠ” ν˜ΈμΆœν•΄μ•Ό ν•  호좜의 포인터λ₯Ό rax에 μ €μž₯ν•©λ‹ˆλ‹€
// μ£Όμ†Œ 0x100004040(ν•¨μˆ˜ μ£Όμ†Œ λ°°μ—΄)의 μ‚¬μš©μ„ ν™•μΈν•©λ‹ˆλ‹€
// 0x1f4 = 500 (μ‹œμž‘ ID)
            rax = *(sign_extend_64(rax - 0x1f4) * 0x28 + 0x100004040);
            var_20 = rax;
// if - else, ifλŠ” falseλ₯Ό λ°˜ν™˜ν•˜κ³ , elseλŠ” μ˜¬λ°”λ₯Έ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ³  trueλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€
            if (rax == 0x0) {
                    *(var_18 + 0x18) = **_NDR_record;
*(int32_t *)(var_18 + 0x20) = 0xfffffffffffffed1;
var_4 = 0x0;
}
else {
// 두 개의 인수둜 μ˜¬λ°”λ₯Έ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” κ³„μ‚°λœ μ£Όμ†Œ
                    (var_20)(var_10, var_18);
                    var_4 = 0x1;
}
}
else {
*(var_18 + 0x18) = **_NDR_record;
*(int32_t *)(var_18 + 0x20) = 0xfffffffffffffed1;
var_4 = 0x0;
}
rax = var_4;
return rax;
}

μ‹€μ œλ‘œ 0x100004000 ν•¨μˆ˜λ‘œ κ°€λ©΄ routine_descriptor ꡬ쑰체 배열을 찾을 수 μžˆμŠ΅λ‹ˆλ‹€. ꡬ쑰체의 첫 번째 μš”μ†ŒλŠ” ν•¨μˆ˜κ°€ κ΅¬ν˜„λœ μ£Όμ†Œμ΄λ©°, κ΅¬μ‘°μ²΄λŠ” 0x28 λ°”μ΄νŠΈλ₯Ό μ°¨μ§€ν•˜λ―€λ‘œ, 0λΆ€ν„° μ‹œμž‘ν•˜μ—¬ 0x28 λ°”μ΄νŠΈλ§ˆλ‹€ 8 λ°”μ΄νŠΈλ₯Ό κ°€μ Έμ˜€λ©΄ 호좜될 ν•¨μˆ˜μ˜ μ£Όμ†Œκ°€ λ©λ‹ˆλ‹€:

이 λ°μ΄ν„°λŠ” 이 Hopper 슀크립트λ₯Ό μ‚¬μš©ν•˜μ—¬ μΆ”μΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Debug

MIG에 μ˜ν•΄ μƒμ„±λœ μ½”λ“œλŠ” λ˜ν•œ kernel_debugλ₯Ό ν˜ΈμΆœν•˜μ—¬ μ§„μž… 및 μ’…λ£Œ μž‘μ—…μ— λŒ€ν•œ 둜그λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. trace λ˜λŠ” **kdv**λ₯Ό μ‚¬μš©ν•˜μ—¬ 이λ₯Ό 확인할 수 μžˆμŠ΅λ‹ˆλ‹€: kdv all | grep MIG

References

Tip

AWS ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°:HackTricks Training AWS Red Team Expert (ARTE)
GCP ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: HackTricks Training GCP Red Team Expert (GRTE) Azure ν•΄ν‚Ή 배우기 및 μ—°μŠ΅ν•˜κΈ°: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks μ§€μ›ν•˜κΈ°