반응형

Learning-eBPF의 pdf에 기인한 내용(chapter4)이며 개인적으로 공부하며 작성되었기에 틀린 내용이 있다면 말씀해주시면 감사하겠습니다.

 

https://cilium.isovalent.com/hubfs/Learning-eBPF%20-%20Full%20book.pdf

 

본 chapter에서는 system call에 대해 다룬다.

우선적으로 ebpf() systemcall에 대해 살펴보자.

간만에 보는 반가운 녀석...(one-day분석때 징글징글하게 봄)

int bpf(int cmd, union bpf_attr *attr, unsigned int size);

해당 함수는 ebpf map이나  program에 대한 명령을 수행하기 위한 친구이다.

- cmd: 말그대로 수행할 command

eBPF map과program을 조절하기 위한 많은 command들이 있다.

아래의 예시는 기본적으로 사용되는 load, create map, attach programs 등등이다.

 

attr: 말그대로 각종 속성들을 저장하는 곳인데 워낙 포함되는 데이터들이 많기에 kernel code를 통해 확인하는 것을 추천한다.

이제 본격적으로 bpf syscall을 파헤치기 위해 syscall을 tracing하는 strace를 활용하여 보자.

활용될 예시 프로그램은 아래와 같으며 이는 실행될때마다 perf buffer에 message를 보내고, execve() syscall event에 대한 정보를 userspace로 전달한다. chapter2인가...에서 있었던 프로그램과 유사하지만 각 사용자 ID에 대해 서로 다른 message를 구성할 수 있다는 차이점이 있다.

#!/usr/bin/python3  
# -*- coding: utf-8 -*-
from bcc import BPF
import ctypes as ct

program = r"""
struct user_msg_t {
   char message[12];
};

BPF_HASH(config, u32, struct user_msg_t);

BPF_PERF_OUTPUT(output); 

struct data_t {     
   int pid;
   int uid;
   char command[16];
   char message[12];
};

int hello(void *ctx) {
   struct data_t data = {}; 
   struct user_msg_t *p;
   char message[12] = "Hello World";

   data.pid = bpf_get_current_pid_tgid() >> 32;
   data.uid = bpf_get_current_uid_gid() & 0xFFFFFFFF;

   bpf_get_current_comm(&data.command, sizeof(data.command));

   p = config.lookup(&data.uid);
   if (p != 0) {
      bpf_probe_read_kernel(&data.message, sizeof(data.message), p->message);       
   } else {
      bpf_probe_read_kernel(&data.message, sizeof(data.message), message); 
   }

   output.perf_submit(ctx, &data, sizeof(data)); 
 
   return 0;
}
"""

b = BPF(text=program)
syscall = b.get_syscall_fnname("execve")
b.attach_kprobe(event=syscall, fn_name="hello")
b["config"][ct.c_int(0)] = ct.create_string_buffer(b"Hey root!")
b["config"][ct.c_int(501)] = ct.create_string_buffer(b"Hi user 501!")

def print_event(cpu, data, size):
   data = b["output"].event(data)
   print(f"{data.pid} {data.uid} {data.command.decode()} {data.message.decode()}")

b["output"].open_perf_buffer(print_event)
while True:
   b.perf_buffer_poll()

line 7~9: message출력할 배열 선언

line 11: data를 저장할 hash table map(type을 따로 지정하지 않을 시에 default는 u64)

line 32: helper function을 통해 userID를 받아온다. 매칭되는 userID에 따라 출력될 메세지를 결정한다. 

 

상기의 코드를 실행해 보자.

sudo python3 ./hello-buffer-config.py

 

ls와 sudo ls 수행시의 output

 

이후에 strace로 확인

옵션 ref

https://itwiki.kr/w/%EB%A6%AC%EB%88%85%EC%8A%A4_strace

sudo strace -e bpf ./hello-buffer-config.py

output

 

상기의 output을 가지고 분석해보자.

bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_PERF_EVENT_ARRAY, , key_size=4,
value_size=4, max_entries=4, ... map_name="output", ...}, 128) = 4

출력에 사용될 perf buffer map을 생성

-map_type : PERF_EVENT_ARRAY

-name : output

-key / value size : 4

-return value(문장 상에서 제일 마지막에 있는 4) : 4(fd를 의미)  -> userspace에서 output map에 access하기 위해 사용

bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_HASH, key_size=4, value_size=12,
max_entries=10240... map_name="config", ...btf_fd=3,...}, 128) = 5

 

hash table map생성

key : 4byte  -> u32type의 userID담김

value : 12byte -> msg_t의 크기(char[12])

btf_fd : 3 -> kernel에서 사용될 요소

bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_KPROBE, insn_cnt=44,
insns=0xffffa836abe8, license="GPL", ... prog_name="hello", ...
expected_attach_type=BPF_CGROUP_INET_INGRESS, prog_btf_fd=3,...}, 128) = 6

 

prog_type : program type, kprobe에 연결

insn_cnt : instruction count, program의 bytecode 명령어 수

- 바이트코드 명령어는 insns 필드에 지정된 주소의 메모리에 보관

license = "GPL" : GPL-licensed BPF helper functions를 사용할 수 있도록 선언

program name : hello

expected_attatch_type : 해당 혜제에서는 일부 프로그램 유형에서만 활용(설명 미기재), 첫항목이기에 value는 0

prog_btf_fd : 3(fd)

 

만약 해당 프로그램이 verifier에 의해 거부된다면 -1의 value를 가지지만, value가 6이기에 적상적으로 통화되었음을 알 수 있으며 각 fd에 대한 정리는 아래와 같다.

 

bpf(BPF_MAP_UPDATE_ELEM, {map_fd=5, key=0xffffa7842490, value=0xffffa7a2b410,
flags=BPF_ANY}, 128) = 0

 

BPF_MAP_UPDATE_ELEM : map의 key-value쌍을 업데이트

BPF_ANY flag : map내에 key가 존재하지 않는 경우, 생성되어야함을 알리는 flag

map_fd : 어떤 map이 현재 사용되는지 식별

- 이때, key / value는 모두 pointer이므로, strace에 의해 수치화된 값이 나오는 것은 아니지만, bpftool을 활용하여 아래와 같이 요소들의 내용을 볼 수 있다.

#bpftool map dump name config output

[{
 "key": 0,
 "value": {
 "message": "Hey root!"
 }
 },{
 "key": 501,
 "value": {
 "message": "Hi user 501!"
 }
 }
]

해당 요소들을 가져올 수 있는 이유는 BTF 정보 내에 정의된 것들을 사용하기 때문이다.

 

● BPF Program and Map References

- pinning

이미 chapter 3에서 나왔던 부분이다.

pinned object는 실제로 disk에 영구적으로 있는 파일이 아니다. 일반적인 file system과 같이 동작하는 pesudo filesystem으로써 존재한다. 그러나 메모리에 보관되기에 재부팅 시에 유지되지 않는다.

-about pseudo file system-

https://superuser.com/questions/1198292/what-is-a-pseudo-file-system-in-linux

 

pinning되지 않은 채로 ebpf program이 load되는 것을 허용한다면, bpftool이 종료될 때 fd가 해제되고 reference가 0이 될시에 program이 삭제될 것이다. 허나 pinng된 ebpf program의 경우 command가 수행된 이후에도 지속될 것이다. 

reference counter는 trigger되는 hook이 연결될 때에도 증가한다. count는 eBPF program type에 의존적이며 tracing과 연관있고(chapter 7에서 다뤄질 예정) 항상 user space process와 연결된다. 이러한 경우, process가 종료되면 kernel의 참조 횟수가 감소한다. 

 

netwrok stack이나 cgroup과 함께 부착된 program은 어떠한 user space process와 연관있지 않기에 load가 종료된 이후에도 유지된다. 이전에 봤던 XDP program에 대한 예시와 같다.

(아마 이전 챕터에서 실습 때, 따로 unload해주지 않으면 유지되어 있는 모습을 떠올리면 될 듯하다.)

ip link set dev eth0 xdp obj hello.bpf.o sec xdp

 

ip명령어가 수행된 이후 pinned location에 대한 정의가 없지만, bpftool은 XDP program이 kernel에 load된 상태를 보여준다.

$ bpftool prog list
…
1255: xdp name hello tag 9d0e949f89f1a82c gpl
 loaded_at 2022-11-01T19:21:14+0000 uid 0
 xlated 48B jited 108B memlock 4096B map_ids 612

reference count는 0이 아니며, 이는 XDP hook이 ip link명령어가 수행된 이후에 지속적으로 부착되어 있기 때문이다.

eBPF map역시 reference count를 가지며 0이 될 시에 초기화 된다. map역시 사용하는 각 eBPF program의 counter를 증가시켜 user space의 program이 map을 가지고 있게 해준다.

map은 file system에 고정될 수도 있으며, user space program은 map 경로를 알면 map에 접근할 수 있다.

 

위와 같이 fd와 reference counter를 통해 참조하게 할 수도 있지만 다른 방법으로는 eBPF link도 있다.

 

● BPF link

BPF link는 eBPF program과 event같의 추상화된 layer를 제공한다. BPF link는 자체적으로 file system에 고정되어 program에 대해 추가적인 참조를 생성할 수 있다. 이는 kernel에 load한 user space process가 종료되어도 program이 load된 상태로 남아 있을 수 있다는 의미라고 한다.

user space loader program의 fd가 해제되어도 program에 대한 reference count는 감소하지만, BPF link에 의해 0이 되지는 않는다. 

 

이후의 내용들은 너무 deep해서 현시점의 나에겐 이해하기에 너무 어려워 생략한다.

대략적으로 다루는 내용은 perf buffers, ring buffers, kprobes, and map iterations에 관련된 syscall에 대해 자세히 본다.

 

이상 chapter 4

반응형

'ebpf' 카테고리의 다른 글

ebpf 공부용 링크들 다시 정리  (0) 2024.06.19
CO-RE, BTF, and Libbpf  (0) 2024.02.11
Anatomy of an eBPF Program  (0) 2024.01.24
eBPF programming  (0) 2024.01.09
Troubleshooting - learning eBPF  (0) 2024.01.01
반응형

Learning-eBPF의 pdf에 기인한 내용(chapter3)이며 개인적으로 공부하며 작성되었기에 틀린 내용이 있다면 말씀해주시면 감사하겠습니다.

 

https://cilium.isovalent.com/hubfs/Learning-eBPF%20-%20Full%20book.pdf

1. compile with clang

hello.bpf.o: %.o: %.c	
 clang \	
 -target bpf \	
 -I/usr/include/$(shell uname -m)-linux-gnu \	
 -g \	
 -O2 -c $< -o $@

 

line1: .o파일을 .c파일로부터 만듦(% : 와일드 카드)

line2: LLVM 컴파일러인 Clang을 사용하여 소스 코드를 컴파일

line3: Clang이 BPF 목표 아키텍처를 컴파일하도록 지정하는 옵션

line4: 헤더 파일을 조회할 디렉터리 지정

line5: 디버그 정보를 포함하여 컴파일

line6: O2 - 최적화 레벨,   $< - 현재 목표의 종속 항목 중 첫번째 (해당 코드에서는 .c파일) , $@ - 현재 목표 (해당 코드에서는 .c파일)  => .c를 compile하여 .o파일로 생성

https://hyeonbell.tistory.com/174

 

2. llvm-objdump -S hello.bpf.o

- eBPF IR파악을 위한 dump

https://github.com/chubin/cheat.sheets/blob/master/sheets/objdump

 

result

hello.bpf.o:    file format elf64-bpf

Disassembly of section xdp:

0000000000000000 <hello>:
;     bpf_printk("Hello World %d", counter);
       0:       18 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r6 = 0 ll
       2:       61 63 00 00 00 00 00 00 r3 = *(u32 *)(r6 + 0)
       3:       18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
       5:       b7 02 00 00 0f 00 00 00 r2 = 15
       6:       85 00 00 00 06 00 00 00 call 6
;     counter++; 
       7:       61 61 00 00 00 00 00 00 r1 = *(u32 *)(r6 + 0)
       8:       07 01 00 00 01 00 00 00 r1 += 1
       9:       63 16 00 00 00 00 00 00 *(u32 *)(r6 + 0) = r1
;     return XDP_PASS;
      10:       b7 00 00 00 02 00 00 00 r0 = 2
      11:       95 00 00 00 00 00 00 00 exit

IR opcode에 대한 reference

https://github.com/iovisor/bpf-docs/blob/master/eBPF.md

 

3. load program with "bpftool" (require root previlige)

sudo bpftool prog load hello.bpf.o /sys/fs/bpf/hello

 

how to check

 ls /sys/fs/bpf

 

4. list bpf programs

sudo bpftool prog list

 

get output with prettified JSON

sudo bpftool prog show id 101 --pretty

output

{
    "id": 101,
    "type": "xdp",
    "name": "hello",
    "tag": "d35b94b4c0c10efb",
    "gpl_compatible": true,
    "loaded_at": 1706073152,
    "uid": 0,
    "bytes_xlated": 96,
    "jited": true,
    "bytes_jited": 64,
    "bytes_memlock": 4096,
    "map_ids": [4,5
    ],
    "btf_id": 159
}

-program ID: 101

-xdp event를 통한 attach

-program name: hello

-identifier

-GPL compatible license
-program이 로딩된 시점의 timestamp - 부팅이후의 시점부터

-userID 0 (root) 로 load

-eBPF bytecode로 변환된 프로그램의 크기

-JIT compiled 및 컴파일 이후 machine code의 크기

-BPF map ID들

- -g flag로 컴파일 했을시 포함되는 정보이며, 해당 BTF id 는 단일 블록의 BTF 정보를 포함

 

program ID는 load와 unload를 할때마다 바뀌지만 tag는 유지된다 -> tag가 고유한 것은 아니다.

같은 name으로 program을 생성할 수 있으며 여러 인스턴스를 가질 수 있지만, ID와 pinned path는 고유하다. 

그리고 아래의 instruction들을 통해 bpf program의 정보를 파악할 수 있다. (네가지 모두 동일한 output)

• bpftool prog show id 540
• bpftool prog show name hello
• bpftool prog show tag d35b94b4c0c10efb
• bpftool prog show pinned /sys/fs/bpf/hello

 

Translated Byte code확인

sudo bpftool prog dump xlated name hello

output

int hello(struct xdp_md * ctx):
; bpf_printk("Hello World %d", counter);
   0: (18) r6 = map[id:4][0]+0
   2: (61) r3 = *(u32 *)(r6 +0)
   3: (18) r1 = map[id:5][0]+0
   5: (b7) r2 = 15
   6: (85) call bpf_trace_printk#-66752
; counter++; 
   7: (61) r1 = *(u32 *)(r6 +0)
   8: (07) r1 += 1
   9: (63) *(u32 *)(r6 +0) = r1
; return XDP_PASS;
  10: (b7) r0 = 2
  11: (95) exit

상기의 output은 verifier를 통과한 이후의 bytecode이다.

 

해당 bytecode는 저수준언어와 유사하게 생겼지만 machine code 급은 아니다(?) 그 사이 어딘가 애매한 상태이다.

eBPF는 JIT compiler를 통해 eBPF bytecode를 machine code로 변환한다.

-> 퍼포먼스를 위해서!

 

JITed code를 assembly어의 형태로!

sudo bpftool prog dump jited name hello

output

int hello(struct xdp_md * ctx):
bpf_prog_d35b94b4c0c10efb_hello:
; bpf_printk("Hello World %d", counter);
   0:   nopl    (%rax,%rax)
   5:   nop
   7:   pushq   %rbp
   8:   movq    %rsp, %rbp
   b:   pushq   %rbx
   c:   movabsq $-99790339293184, %rbx
  16:   movl    (%rbx), %edx
  19:   movabsq $-124354625743600, %rdi
  23:   movl    $15, %esi
  28:   callq   0xffffffffce103260
; counter++; 
  2d:   movl    (%rbx), %edi
  30:   addq    $1, %rdi
  34:   movl    %edi, (%rbx)
; return XDP_PASS;
  37:   movl    $2, %eax
  3c:   popq    %rbx
  3d:   leave
  3e:   retq
  3f:   int3

 

ps. JIT compilation을 활용하기 위해서는 CONFIG_BPF_JIT옵션이 켜져있는 kernel이어야 한다.

상기의 IR은 내가 보던 pdf와 달랐는데, 느낌상으로는 내 pc와 예제의 환경이 상이하여 발생한 차이인듯하다.

 

이제 program이 load된 것을 보았으니 event와 attach하고 trigger해보자.

attach할 때, 유의할 부분이 type이다.

위에서 우린 xdp event에 attach하겠다고 하였으므로 bpftool을 사용하여 eBPF 프로그램에 xdp event를 attach해보자.

sudo bpftool net attach xdp id 101 dev enp5s0

뒷쪽의 id와 device는 적절하게 맞추어 주자!

현재 본인의 경우..

ifconfig로 확인하자~

cf. lo는 loopback interface이다. 해당 interface는 traffic을 내 machine에 보내기 위해 사용

enp5s0

-ref-

https://unix.stackexchange.com/questions/134483/why-is-my-ethernet-interface-called-enp0s10-instead-of-eth0

https://blog.naver.com/snrndi121/220999725150

이후에 network interface가 추가된 것을 볼 수 있다.

sudo bpftool net list

output( enp5s0 interface가 attach된 상태)

xdp:
enp5s0(2) generic id 101

tc:

flow_dissector:

netfilter:

 

ip link명령어로도 확인가능

현 상태에서는 network packet 수신에 대해 output을 매번 trace utput으로 저장해야 되며 아래의 명령을 통해 확인가능하다.

cat /sys/kernel/debug/tracing/trace_pipe

요로코롬

아래의 명령어로도 tracelog를 확인할 수 있다.

sudo bpftool prog tracelog

kernel에 load된 map들을 보고싶다면!

그리고 생성된 program에 대해 section도 관찰할 수 있다.

sudo bpftool map dump name hello.bss

output(.bss section(초기화되지 않은 전역변수)의 전역변수를 볼 수 있다.)

[{
        "value": {
            ".bss": [{
                    "counter": 124555
                }
            ]
        }
    }
]

.rodata section

sudo bpftool map dump name hello.rodata

output

[{
        "value": {
            ".rodata": [{
                    "hello.____fmt": "Hello World %d"
                }
            ]
        }
    }
]

 

attach했던 program을 해제하고 싶다면!

sudo bpftool net detach xdp dev enp5s0

이후에 net list를 입력해보면 비어있는 것을 확인할 수 있다.

다음으로 unload하고 싶다면!

sudo rm /sys/fs/bpf/hello
sudo bpftool prog show name hello

output이 아무것도 없다면 된다. 더이상 load된 program이 없기 때문~

 

마저 진행해보자!

 

tail call에 대해서부터 시작이다.

간단한 예제코드를 먼저 보자.

#include <linux/bpf.h>
#include <bpf_helpers.h>

static __attribute((noinline)) int get_opcode(struct bpf_raw_tracepoint_args *ctx) {
    return ctx->args[1];
}

SEC("raw_tp/")
int hello(struct bpf_raw_tracepoint_args *ctx) {
    int opcode = get_opcode(ctx);
    bpf_printk("Syscall: %d", opcode);
    return 0;
}

char LICENSE[] SEC("license") = "Dual BSD/GPL";

- opcode를 추출하는 간단한 함수인데 compiler에서 저 함수만을 지속적으로 처리할 경우, 인라인 처리 하는 것을 방지하기 위해 noinline 속성으로 정의한다.

 

- opcode를 추출하여 printk로 출력

 

이제 이전 글에서 수행했던 것 처럼 파일을 load해보자.

sudo bpftool prog load hello-func.bpf.o /sys/fs/bpf/hello
sudo bpftool prog list name hello

output

166: raw_tracepoint  name hello  tag 3d9eb0c23d4ab186  gpl
        loaded_at 2024-01-25T08:36:33+0900  uid 0
        xlated 80B  jited 62B  memlock 4096B  map_ids 37
        btf_id 207

 

이제 get_opcode() 함수를 보기 위해 eBPF 바이트코드 살펴보자.

sudo bpftool prog dump xlated name hello

output

int hello(struct bpf_raw_tracepoint_args * ctx):
; int opcode = get_opcode(ctx);
   0: (85) call pc+7#bpf_prog_cbacc90865b1b9a5_get_opcode
; bpf_printk("Syscall: %d", opcode);
   1: (18) r1 = map[id:37][0]+0
   3: (b7) r2 = 12
   4: (bf) r3 = r0
   5: (85) call bpf_trace_printk#-66752
; return 0;
   6: (b7) r0 = 0
   7: (95) exit
int get_opcode(struct bpf_raw_tracepoint_args * ctx):
; return ctx->args[1];
   8: (79) r0 = *(u64 *)(r1 +8)
; return ctx->args[1];
   9: (95) exit

- hello()이 get_opcode()를 호출하며 eBPF IR기준으로 offset 0은 0x85이며 이는 "Function call"을 의미한다.

이후에, offset 1에 있는 다음 명령어를 실행하는 대신, 7개의 IR을 건너뛰어(pc+7에 의해) offset 8을 향하게 된다.

 

- 해당 위치에 get_opcode()이 존재한다.

 

하지만 위와 같은 tail call은 stack size가 512byte로 제한적인 eBPF 에서는 많이 활용되기 어렵다.

 

이상으로 chapter3의 내용을 마친다.

 

반응형

'ebpf' 카테고리의 다른 글

CO-RE, BTF, and Libbpf  (0) 2024.02.11
The bpf() System Call  (0) 2024.01.25
eBPF programming  (0) 2024.01.09
Troubleshooting - learning eBPF  (0) 2024.01.01
JIT for BPF  (0) 2023.09.21
반응형

거의 다 풀었는데 끝마무리를 못짓거나 시간 투자를 많이 못해서 못 푼 문제들이 많아서 많이 아쉬웠다.

1. FLAG HOLDING

초기화면에서 보여주는 것이다.

referer에 해당 url을 추가해주면 다음  step으로 넘어간다.

다음 step이다.

약간의 guessing을 했던 문제인데 secret에 대한 인자가 없는거 아닐까 싶어서 추가해봤다.

burp의  response에서  hint를 발견할 수 있다.

당연히 http지 뭐....이제 마지막 step이다.

ㅇㅎ method 만 바꿔주면 되겄네~

쨘!

이후의 문제 3개는 다 풀거나 많은 삽질을 했지만 해결못해서 아쉬운 마음에 정리해둔다.

 

2. NOVEL READER

...진짜 다풀었었느데...

기능

-balance 10 당 words balance 1이고 words balance가 추가될때마다 novels를 볼 수 있는 글자가 한글자씩 추가되는 구조이다. 

-balance와  words balance의 교환은 charge account를 통해 이뤄진다.

-private novels는 읽을 수 없다.

 

무슨 방법을 써도 읽을 수가 없기에 경로추적을 수행해봤었는데...

분명 안풀렸었다가 추후에 알아보니.. 인코딩을 해주어야 했었다..코드를 안보고 푼 내탓이었다..

제공해주는 것을 잘 활용하자 제발

암튼 코드에 보면

 name = unquote(name)

이런 부분이 있었다.....

그래서 url double encoding을 해주어야했었..;;;; 애초에 파일이름도 secret을 읽는게 아니었다 ㅋㅋ;;

 

3. NOVEL READER2

이 친구 역시 코드를 안봐서 생긴 참사였다

buf = readFile(name).split(' ')
buf = ' '.join(buf[0:session['words_balance']])+'... Charge your account to unlock more of the novel!'

이러한 부분이 있었는데...

혼자 -1일때 balance의 숫자가 올라가는 것을 보고 이게 중요포인트겠구나 까지는 접근했었다ㅠㅠㅠ

코드봤으면 바로 풀었을 텐데....

 

session을 통해 words_balance와 balance를 파악하는데 -1일 경우 파이썬이기에 역순으로 모든 걸 볼 수 있다.

그러므로, words_balance를 -1로 맞추어 준다.

요런느낌으로...

 

3. Advanced JSON Cutifier

가장 많은 시간을 들였던 문제이다... GO언어 관련 문제인줄 알고 GO언어의 framwork인 gin을 후다닥 공부하며 풀어보려했었는데 생각보다 너무 간단했던 문제였기에 많은 허탈함을 느꼈다.

소스코드에 아래와 같은 부분이 있었다.

import (
    "net/http"
    "github.com/gin-gonic/gin"
    "github.com/REDACTED/REDACTED"
)

처음에 당연히 7*7이 계산되기에 알아보니 GO환경에서도 SSTI가 가능하다고 하여 SSTI를 포인트로 잡고 풀고 있었다..

하지만 전혀 다른 부분의 취약점이었다ㅠ

JSONNET llibrary에 대한 부분이었다.

아래의 링크를 첨부한다.

Read file contents and do string replacement on that · Issue #238 · google/jsonnet · GitHub

하하..

너무나 쉽게 풀 수 있는 문제였다ㅠㅠㅠ...

 

그래도 덕분에 때로는 쉽게도 생각해야하며, go언어에 대해 찍먹해보며 삽질하는 기회가 되었던 CTF였다.

아직 많은 공부가 필요함을 다시금 되새기도록 해주었다.

 

반응형

'CTF' 카테고리의 다른 글

BuckeyeCTF 2024  (0) 2024.09.29
ASIS CTF 2024  (0) 2024.09.23
RSTCON 2024 CTF  (0) 2024.09.16
BSidesSF 2024 CTF  (0) 2024.05.06
0xl4ugh CTF 2024  (0) 2024.02.11

반응형

https://cilium.isovalent.com/hubfs/Learning-eBPF%20-%20Full%20book.pdf


상기의 내용을 기반으로 아래의 링크에서 학습하던 와중 생긴 에러에 대한 처리

https://github.com/lizrice/learning-ebpf

 

GitHub - lizrice/learning-ebpf: Learning eBPF, published by O'Reilly - out now! Here's where you'll find a VM config for the exa

Learning eBPF, published by O'Reilly - out now! Here's where you'll find a VM config for the examples, and more - GitHub - lizrice/learning-ebpf: Learning eBPF, published by O'Reill...

github.com

 

처음에 계속 libbpf/src를 시작할떼 make build를 수행해 주었으나 path를 잡지 못해 에러를 처리하지 못하고 있었다.

그렇기에 기본으로 주어지는 makefile을 뜯어보니 참조하는 디렉터리가 달랐기에 수정하였다.

makefile의 -I플래그로 -I/home/username/bpf/learning-ebpf/libbpf/src \ 추가

 -I 플래그 : 해당 디렉터리를 포함하도록 지정

수정된 makefile

TARGETS = hello hello-func

all: $(TARGETS)
.PHONY: all

$(TARGETS): %: %.bpf.o

%.bpf.o: %.bpf.c
        clang \
            -target bpf \
                -I/home/hackin/bpf/learning-ebpf/libbpf/src \
                -I/usr/include/$(shell uname -m)-linux-gnu \
                -g \
            -O2 -o $@ -c $<

clean: 
        - rm *.bpf.o
        - rm -f /sys/fs/bpf/hello 
        - rm -f /sys/fs/bpf/hello-func

또한, 헤더파일들이 위치한 디렉터리는 src디렉터리 이기에 c code들도 모두 수정해 주었다.

각 소스코드의 <bpf/bpf_helper.h> -> <bpf_helper.h> 로 변경

이제 정상적으로 생성된 것을 확인할 수 있다.

 

그리고 정상적으로 이제 덤프가 떠지는 것까지 확인!

 

추후에 상기에 언급해뒀던 pdf 내용들도 좀 정리해야겠다....

 

 

옛날에는 이걸 못해서 학습이 막혔었는데.. 이걸 왜 못했을까...

반응형

'ebpf' 카테고리의 다른 글

Anatomy of an eBPF Program  (0) 2024.01.24
eBPF programming  (0) 2024.01.09
JIT for BPF  (0) 2023.09.21
JIT(Just In Time) Compiler - Verifier - SAT/SMT solver  (0) 2023.09.17
Buzzer(eBPF fuzzer) build  (0) 2023.08.11

+ Recent posts