欢迎访问皮皮网官网
皮皮网

【溯源码sk】【银河麒麟os源码】【金融cms网站源码】expr源码

时间:2024-11-19 08:53:26 分类:焦点 来源:取小程序源码

1.Nftables CVE-2023-0179提权利用
2.求c++编译一个简单的源码计算程序(四则运算)。

expr源码

Nftables CVE-2023-0179提权利用

       在分析了CVE---Nftables整型溢出漏洞的源码成因之后,本文接下来将深入探讨如何利用这一漏洞。源码首先,源码了解到payload_eval_copy_vlan函数中存在整型溢出问题,源码这使得我们可以将vlan头部结构拷贝至寄存器(NFT_REG_-NFT_REG_)中,源码溯源码sk而该变量位于栈上,源码因此可以覆盖到栈上的源码其他变量。

       然而,源码观察源码后发现regs变量无法直接覆盖到返回地址。源码进一步分析后发现,源码jumpstack变量位于regs变量下方,源码银河麒麟os源码因此可以利用整型溢出覆盖到jumpstack变量。源码接下来,源码我们关注nft_jumpstack结构体,源码该结构体在nft_do_chain函数中起作用,当状态寄存器被设置为JUMP条件时,程序将跳转至其他chain进行处理。保存完当前chain状态后,程序将跳转至目的chain,即存储在regs.verdict.chain中。

       还原chain的过程涉及通过递减stackptr来取出存储在jumpstack变量中的chain、rule、金融cms网站源码lastrule,然后进行rule的解析。需要注意的是,在遍历rule时,循环条件为rule < lastrule。因此,在伪造lastrule时,需要确保其值大于rule,否则无法进入循环内部。

       接着,观察nft_rule_dp结构体,POI源码深度解析发现其中包含用于存储nft_expr结构体指针的八个字节。通过篡改该指针,可以劫持程序流程。为了解决这一问题,作者从ctfiot.com/.html中学习了一个技巧:使用ptype /o struct xxx显示结构体信息与偏移。

       构建流程如下:通过漏洞溢出至nft_jumpstack结构体,并修改rule变量指向可控内容的地址。同时,将lastrule值篡改为大于rule的值。接下来,在可控内容中伪造一个nft_rule_dp结构体,空单号网源码篡改第一个八个字节(填充位)和第二个八个字节(函数表指针)的值,使其分别指向可控内容的地址。之后,在该地址处伪造nft_expr,将ops变量指向所需执行的函数。

       分析后得知,通过上述手段可以实现程序流程的劫持。接下来,需要考虑如何伪造上述结构体。在nft_payload_copy_vlan函数中,漏洞点在于将vlan头数据复制到寄存器中,由于vlan头地址低于寄存器地址,导致在复制完vlan头后会覆盖寄存器值。这里,我们可以通过控制NFT_REG_的值来实现对jumpstack结构体的篡改。

       由于可以控制regs变量,首先泄露regs地址,然后在此基础上伪造rule并重新指向jumpstack。这里采用将last_rule设置为函数地址的技巧,以节省八个字节的空间。然而,仅控制八个字节的函数指针不足以构造完整的ROP链,因此需要使用栈迁移。栈迁移的目标是控制一段内存,选择regs作为目标。

       在寻找合适的栈迁移gadget时,作者使用了vmlinux-to-elf工具提取符号表,然后利用ropper工具搜索gadget。但尝试后发现大部分gadget不可用。作者最后尝试使用objdump工具提取gadget,并通过搜索add rsp.*等指令找到栈迁移的gadget。进一步计算栈顶与regs函数地址的差值,找到相应的栈迁移gadget。

       在提权方面,作者通过覆盖modprobe_path实现提权。选择合适的gadget将rdi设置为modprobe_path,rax设置为覆盖后的路径。然而,在返回到nf_hook_slow函数时,由于设置了rax值导致状态码无法正确设置,程序跳转至NF_DROP分支,导致内核异常。最终,作者在rbp中找到了一个do_softirq函数,并尝试将其作为返回地址。运行后发现程序能够正常返回到用户态。

       最后,验证新用户是否已写入至/etc/passwd文件中,完成提权过程。完整exploit代码可参考github.com/h0pe-ay/Vuln.../poc.c。相关资料参考链接包括github.com/TurtleARM/CV...

求c++编译一个简单的计算程序(四则运算)。

       //正解代码很长很复杂,也许对新人来说太难了。

       //此程序可以运算+、-、*、/、乘方(^)、求余数(%),也可以出现( )规定优先级。

       //按Ctrl+C退出。

       #include <stdio.h>

       #include <stdlib.h>

       #include <setjmp.h>

       #include <math.h>

       typedef enum BinOpr

       {

       OP_ADD, OP_SUB, OP_MUL, OP_DIV, OP_MOD, OP_POW, OP_NON

       } BinOpr;

       static struct { int left, right; } binop_prio[] =

       {

       { 6, 6}, { 6, 6}, { 7, 7}, { 7, 7}, { 7, 7}, { ,9},

       };

       #define UNARY_PRIO 8

       static BinOpr get_binop(const char **s)

       {

       switch (**s)

       {

       case '+': ++*s; return OP_ADD;

       case '-': ++*s; return OP_SUB;

       case '*': ++*s; return OP_MUL;

       case '/': ++*s; return OP_DIV;

       case '%': ++*s; return OP_MOD;

       case '^': ++*s; return OP_POW;

       default: return OP_NON;

       }

       }

       static double doexpr(int op, double a, double b)

       {

       switch (op)

       {

       case OP_ADD: return a+b;

       case OP_SUB: return a-b;

       case OP_MUL: return a*b;

       case OP_DIV: return a/b;

       case OP_MOD: return a-floor(a/b)*b;

       case OP_POW: return pow(a, b);

       default: return 0;

       }

       }

       typedef struct ExprContext

       {

       jmp_buf jbuf;

       const char *errmsg, *s;

       BinOpr op;

       } Expr;

       static double error(Expr *e, const char *msg)

       {

       e->errmsg = msg;

       longjmp(e->jbuf, 1);

       }

       static double expr(Expr *e, int limit)

       {

       double n;

       BinOpr op;

       if (*e->s == '-')

       {

       ++e->s;

       n = -expr(e, UNARY_PRIO);

       }

       else if (*e->s == '(')

       {

       ++e->s;

       n = expr(e, 0);

       if (*e->s++ != ')') error(e, "')' expected");

       }

       else {

       const char *s = e->s;

       n = strtod(s, (char**)&e->s);

       if (e->s == s) error(e, "'number' expected");

       }

       op = get_binop(&e->s);

       while (op != OP_NON && binop_prio[op].left > limit)

       {

       n = doexpr(op, n, expr(e, binop_prio[op].right));

       op = e->op;

       }

       e->op = op;

       return n;

       }

       double calc(const char *s, const char **perr)

       {

       Expr e;

       e.s = s;

       e.errmsg = NULL;

       if (setjmp(e.jbuf) == 0)

       {

       double n = expr(&e, 0);

       if (*e.s != '\n' && *e.s != '\0' && *e.s != '=')

       error(&e, "traling chars detected");

       return n;

       }

       if (perr) *perr = e.errmsg;

       return 0;

       }

       int main(void)

       {

       char buff[BUFSIZ];

       while (printf("> "), fgets(buff, BUFSIZ, stdin) != NULL)

       {

       const char *errmsg = NULL;

       double n = calc(buff, &errmsg);

       if (errmsg) printf("ERROR: %s\n", errmsg);

       else printf("%g\n", n);

       }

       return 0;

       }

       //可以把这个程序留下来,等以后再慢慢研究。正解太复杂太复杂了。

       //望采纳

       ------------------------------------------------------------------------------------

copyright © 2016 powered by 皮皮网   sitemap