欢迎光临!欢迎分享转载本站文章,尊重原创,转载请注明出处!

Httpry:简明http抓包工具

2017年7月27日 没有评论

tcpdump是流量分析时最常用的抓包工具,功能很强大。抓取http get交互消息的常用命令是:

tcpdump -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854 -w eth0-http.pcap

通常我们会把抓取的http包保存成文件,然后用wireshark打开分析。

有时候,我们不需要对流量观察得特别深入,仅仅是看一下有什么样的流量,不需要存盘分析。

使用tcpdump的话输出内容不直观,比如wget http://www.baidu.com/的输出如下:

15:05:27.837705 00:16:3e:04:af:53 > ee:ff:ff:ff:ff:ff, ethertype IPv4 (0x0800), length 165: (tos 0x0, ttl 64, id 18764, offset 0, flags [DF], proto TCP (6), length 151)
139.129.205.48.53353 > 220.181.112.244.80: Flags [P.], cksum 0xa6e5 (incorrect -> 0xe0b0), seq 2930938556:2930938667, ack 65362085, win 115, length 111
0x0000: 4500 0097 494c 4000 4006 4ab9 8b81 cd30 E…IL@.@.J….0
0x0010: dcb5 70f4 d069 0050 aeb2 92bc 03e5 58a5 ..p..i.P……X.
0x0020: 5018 0073 a6e5 0000 4745 5420 2f20 4854 P..s….GET./.HT
0x0030: 5450 2f31 2e30 0d0a 5573 6572 2d41 6765 TP/1.0..User-Age
0x0040: 6e74 3a20 5767 6574 2f31 2e31 3220 286c nt:.Wget/1.12.(l
0x0050: 696e 7578 2d67 6e75 290d 0a41 6363 6570 inux-gnu)..Accep
0x0060: 743a 202a 2f2a 0d0a 486f 7374 3a20 7777 t:.*/*..Host:.ww
0x0070: 772e 6261 6964 752e 636f 6d0d 0a43 6f6e w.baidu.com..Con
0x0080: 6e65 6374 696f 6e3a 204b 6565 702d 416c nection:.Keep-Al
0x0090: 6976 650d 0a0d 0a ive….
15:05:27.860678 ee:ff:ff:ff:ff:ff > 00:16:3e:04:af:53, ethertype IPv4 (0x0800), length 449: (tos 0x60, ttl 48, id 47418, offset 0, flags [DF], proto TCP (6), length 435)
220.181.112.244.80 > 139.129.205.48.53353: Flags [P.], cksum 0x6a94 (correct), seq 65362085:65362480, ack 2930938667, win 772, length 395
0x0000: 4560 01b3 b93a 4000 3006 e94e dcb5 70f4 E`…:@.0..N..p.
0x0010: 8b81 cd30 0050 d069 03e5 58a5 aeb2 932b …0.P.i..X….+
0x0020: 5018 0304 6a94 0000 4854 5450 2f31 2e31 P…j…HTTP/1.1
0x0030: 2032 3030 204f 4b0d 0a53 6572 7665 723a .200.OK..Server:
0x0040: 2062 6665 2f31 2e30 2e38 2e31 380d 0a44 .bfe/1.0.8.18..D
0x0050: 6174 653a 2054 6875 2c20 3237 204a 756c ate:.Thu,.27.Jul
0x0060: 2032 3031 3720 3037 3a30 353a 3237 2047 .2017.07:05:27.G
0x0070: 4d54 0d0a 436f 6e74 656e 742d 5479 7065 MT..Content-Type
0x0080: 3a20 7465 7874 2f68 746d 6c0d 0a43 6f6e :.text/html..Con
0x0090: 7465 6e74 2d4c 656e 6774 683a 2032 3338 tent-Length:.238

此时,httpry是一个很好的替代工具。使用httpry捕获上述请求,输出如下:

2017-07-27 15:08:50 139.129.205.48 220.181.112.244 > GET www.baidu.com / HTTP/1.0 – –
2017-07-27 15:08:50 220.181.112.244 139.129.205.48 < – – – HTTP/1.1 200 OK

简单明了。

  • 安装
    • 下载源码,make && make install就ok了
    • 这个程序依赖libpcap-devel库,没有的话就yum install -y libpcap-devel
  • 使用
    • 最简单的:httpry -i eth0
    • 支持过滤http请求方法:httpry -i eth0 -m GET
    • 支持保存抓包:httpry -i eth0 -o eth0-http.log
    • 可以指定packet filter:httpry -i eth0 ‘dst host www.baidu.com’
分类: 工具 标签: , , ,

一个从MongoDB中导出给定日期范围内数据的shell脚本

2017年6月29日 没有评论

前几天介绍了使用mongoexport的使用方法,结合date命令的使用,这里给出一个完整的脚本,用来从MongoDB中导出某个日期范围内的数据,数据导出后从MongoDB中进行删除

#!/bin/sh
d1=$1 #the beginning date, 2017-06-28

d1=`date -d $d1 +%F`

 

d2=`date -d $d1 +%s`
d2=`expr $d2 + 86400` #One day
d2=`date -d @$d2 +%F`

qj='{“time”:{$gte:ISODate(“‘”$d1″‘T00:00:00Z”)}, “time”:{$lt:ISODate(“‘”$d2″‘T00:00:00Z”)}}’
./mongoexport –db testDB –collection testColl –query=”$qj” –fields=”userId,userName” –type=”csv” –out results”-$d1″ –noHeaderLine

echo ‘var db = connect(“testDB”);’ > delete.js
echo ‘db.testColl.remove({“time”:{$gte:ISODate(“‘”$d1″‘T00:00:00Z”)}, “time”:{$lt:ISODate(“‘”$d2″‘T00:00:00Z”)}})’ >> delete.js
./mongo delete.js

备注:如果MongoDB使用的不是默认端口27017,上面的脚本里mongoexport和mongo都需要增加–port参数,并且delete.js中的connect方法也需要指定端口,指定方式为:

var db = connect(“127.0.0.1:port/testDB”);

分类: MongoDB, Shell 标签: ,

shell中计算偏移日期的方法

2017年6月29日 没有评论

给定一个日期,如何在shell中计算前几天或者后几天的日期?

方法如下:

d1=`date +%F` #给定当前日期

offset=2 #计算两天后的日期

d1s=`date -d $d1 +%s` #d1 in seconds, since 1970-01-01 00:00:00 UTC

offset_s=`expr 86400 \* $offset` #offset in seconds

d2s=`expr $d1s + $offset_s` #d2 in seconds

d2=`date -d @$d2s + %F` #get d2

主要原理就是通过date -d +%s来实现日期和秒之间的互转,详情man date一下吧。

分类: Shell 标签: ,

Android应用商店apk下载重定向测试

2017年6月24日 没有评论

首先声明:本文仅用于学习测试,不进行任何目的的实际应用,请勿用作非法用途!

服务器对下载的处理一般有3种方法:

  • 直接返回下载文件内容
  • 进行简单校验,将下载请求302重定向至下载文件
  • 进行简单校验,通过200返回下载URL和校验数据,客户端将文件下载完成后再次进行校验

目前大部分应用商店是通过第三种方法处理apk下载的,这样可以初步避免客户端发起的下载请求被重定向。但只要数据是通过http协议进行传输的,都不能完全避免被重定向。

比如,返回给客户端的校验数据也是可以被抓包工具捕获的,这样就提供了被修改的可能。经过认真分析比对下载过程,可以修改下载URL和校验数据,让手机应用商店下载修改后的URL,并使用伪校验数据来校验。这样就有可能将apk重定向至非法应用!

我们测试了一款appstore,发现它的下载过程分三步:

  • appstore发起下载请求,服务器通过200返回下载URL和校验数据
  • appstore再次发起下载请求,服务器通过302返回真正的下载地址
  • appstore第三次发起下载请求,下载apk后进行校验
  • 校验内容包括但不限于:文件名称、大小、md5、版本

测试过程中遇到一些问题及对应的解决办法

  • 测试环境不佳,只能在重定向服务器所在的网段内能100%捕获到下载请求:在重定向服务器上搭建nginx透明代理,将测试客户端上特定的域名解析到代理服务器
  • 使用Android模拟器测试无效果,没有办法解析域名,无法捕获到下载请求:使用真机测试
  • 在手机上下载应用商店,修改手机上的hosts文件,可以捕获到下载请求
  • 不同APP下载后无法进行安装:只能进行同一APP的下载重定向。

由于各应用商店厂商也在不断做安全调整,所以需要实时跟踪下载协议,更新重定向策略。

本文亦提醒应用商店厂商及时调整下载策略,避免流量损失。

分类: 开发 标签: ,

使用mongoexport导出某个时间段内的数据

2017年6月24日 没有评论

mongoexport是MongoDB自带一个数据导出工具,可以方便的导出查询结果。现通过一条命令来演示使用方法,特别是如何查询某个时间段内的数据。

数据库名称:testDB

集合名称:testColl

查询条件:2017-06-12当天的所有记录

导出列:userId, userName

导出文件类型:csv,不含“表头”

./mongoexport –db testDB –collection testColl –query='{“time”:{$gte:ISODate(“2017-06-12T00:00:00Z”)}, “time”:{$lt:ISODate(“2017-06-13T00:00:00Z”)}}’ –fields=”userId,userName” –type=”csv” –noHeaderLine –out results

请注意加粗参数的用法。

–query:指定查询条件,多个条件可以进行and或or的逻辑组合。此处组合了起止时间。

–fields:指定输出字段,默认输出全部字段

–noHeaderLine:不输出字段名称

官方文档指出:export不适于用作生产环境的全库数据备份,请使用mongodump进行全库备份。

分类: MongoDB 标签:

多网卡环境下VMware虚拟机桥接宿主机网络不通的解决办法

2017年5月22日 没有评论

如题所述,一般都是在个人电脑上安装VMwareWorkStation,然后装几个虚拟机进行测试。自己的电脑一般都是一个网卡,直接将虚拟机桥接到物理网卡上就行了,无须过多设置。

今天在一台Windows服务器上装了一个VMwareWorkStation,通过桥接将虚拟机连上宿主机后,网络一直不通。

service network restart命令提示网线未接入或者网卡设备未激活之类的信息,但宿主机明明是可以上网的。搜了好久终于找到原因和解决办法:

  • 宿主机上有多块网卡,只有一个网卡插入了网线
  • VMware桥接选项默认自动选择了一块网卡,恰好不是可以上网的网卡

这种情况下,需要手动编辑虚拟网络,步骤如下:

  • VMware菜单中选择“编辑”->“虚拟网络编辑器”,打开虚拟网络编辑器
  • 选中“VMnet0”,如果看不到“VMnet0”可以通过“添加网络”手动将VMnet0添加进来
  • 在下边的“桥接模式”中,通过下拉选择可以联网的网卡,保存设置
  • 重启虚拟机网络
分类: 资料 标签:

wtail:可以多屏输出的多文件跟踪查看工具

2017年5月17日 没有评论

tail是我们常用到的文件跟踪查看工具,-n可以查看末尾n行,-f可以实时跟踪文件(描述符)的最新变化。当然也可以同时查看多个文件,但是多文件的输出是混杂在一起的,没那么直观。

现在好了,我们有了wtail。这是一个可以在同一个终端窗口中同时输出多个被跟踪文件数据的工具,每个文件可以在单独的小屏幕中输出,即一个窗口分屏输出。

  1. 安装
    • wtail依赖libncurses,某些机器上可能没有这个库,需要手动安装:

      wget http://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.0.tar.gz

      tar xzvf ncurses-6.0.tar.gz && cd ncurses-6.0

      ./configure && make && make install

    • 下载wtail源码包,解压,make && make install
  2. 使用
    • wtail *.log
分类: Shell, 工具, 运维 标签: , ,

低版本Java会导致APKTool解析apk包时产生异常

2017年5月8日 没有评论

通过java -jar apktool_2.2.2.jar d -s -f a.apk解析apk包时产生一个异常报错:

Exception in thread “main” java.lang.ClassFormatError: brut.apktool.Main (unrecognized class file version)
at java.lang.VMClassLoader.defineClass(libgcj.so.10)
at java.lang.ClassLoader.defineClass(libgcj.so.10)
at java.security.SecureClassLoader.defineClass(libgcj.so.10)
at java.net.URLClassLoader.findClass(libgcj.so.10)
at java.lang.ClassLoader.loadClass(libgcj.so.10)
at java.lang.ClassLoader.loadClass(libgcj.so.10)
at gnu.java.lang.MainThread.run(libgcj.so.10)

在stackoverflow.com上找到了问题的原因:执行解析的服务器上安装的Java版本较低

so,更新Java到最新版本,重新执行,问题解决。

分类: 开发 标签: ,

使用rsync进行文件同步

2017年4月25日 没有评论
  1. rysnc是什么
    1. 这是一个linux平台上通用的文件同步工具,可以在本地目录或本地与服务器之间进行文件同步
    2. 安全:支持自定义端口,支持口令配置
    3. 高效:只传输差异部分,支持压缩传输
    4. 易用:支持通配符,支持exclude来排除特定文件
  2. 安装
    1. 大多数linux服务器默认安装有rsync
    2. 如果没有,简单运行yum -y install rsync就ok了
  3. 简单示例
    1. 同步的前提是两端服务器都安装了rsync
    2. push方式:rsync /localDir/file user@remoteServerAddress:/remoteDir
    3. pull方式:rsync user@remoteServerAddress:/remoteDir/file /localDir
    4. 上述两条命令实际上是通过ssh来通信的,所以如果对端服务器用户配置了密码的话需要输入密码
    5. rsync还支持通过rync协议来通信,有两种命令方式可以使用该协议
      1. 在服务器和路径之间使用双冒号,比如

        rsync /localDir/file user@remoteServerAddress::/remoteDir

      2. 显式使用,如

        rsync rsync://user@remoteServerAddress[:remoteServerPort]/remoteDir/file /localDir

  4. 以daemon方式配置和运行
    1. rsync可以在一端或者两端以daemon进程形式来运行,通过配置rsyncd.conf来定制同步业务
    2. 这里列举一个简单的配置文件/etc/rsyncd.conf:

      #global settings
      pid file = /var/rsync/rsync.pid
      port = 873
      lock file = /var/rsync/lock.log
      log file = /var/rsync/rsync.log

      #module settings
      [SyncFiles]
      path=/data/files/
      use chroot = no
      max connections = 5
      read only = yes
      write only = no
      list = no
      uid = nobody
      gid = nobody
      incoming chmod = 644
      auth users = syncUser
      secrets file = /etc/rsync.pass
      strict modes = yes
      hosts allow = 192.168.1.119
      hosts deny = *
      ignore errors = yes
      timeout = 120

    3. 授权文件/etc/rsync.pass格式

      syncUser:_password_

    4. 注意事项:需要chmod 600 /etc/rsync.pass
    5. 启动进程:rsync –daemon,可将此命令加入/etc/rc.local
    6. 客户端同步命令:

      rsync -az –password-file=./sync_auth rsync://syncUser@remoteServerAddress[:remoteServerPort]/SyncFiles/* /localDir

    7. 由于同步用户配置了权限,客户端每次rsync操作都需要输入密码,可以通过–password-file选项来指定密码文件,这样就可免去输入密码了,如上面命令所示。该密码文件的格式很简单,单行文本写入密码即可,同样需要chmod 600 ./sync_auth
  5. 检测文件是否需要同步
    1. -i参数:可以对对端文件的变更进行摘要,据此可以判断是否需要同步
    2. -n参数:尝试同步操作但不传输文件
    3. 结合起来,-in就可以根据输出来判断是否需要同步了
  6. 其他:
    1. –delete参数支持删除文件的同步
    2. -L支持软链接目标目录的同步
    3. 如果写入的目录没有权限,会报以下错误,执行chown -R nobody.nobody /data/files/修改权限即可解决

      rsync: mkstemp failed: Permission denied (13)

分类: Shell, 运维 标签: , , ,

扑克洗牌算法(c++版)

2017年3月20日 没有评论

这是三年前去一家游戏公司面试时被问到的一个问题,当时由于自己在传统软件公司做业务,对算法没有留心学习,虽勉强答出来了,但从未实现过。今天随手写了个小程序做下验证。

基本思路:将代表扑克牌的52个数字放入vector中,每次随机抽取一张放入新的vector,并将被抽取牌从原vector中删除。如此循环52次,即可得到随机化的牌面。

代码如下:

#include <iostream>
using namespace std;
#include <vector>
#include <stdlib.h>

int main()
{
unsigned int total;
cout << “Please input the TOTAL:” << endl;  //输入52
cin >> total;

//将52个数放入vCards0

vector<unsigned int> vCards0;
unsigned int i=1;
while(i <= total)
{
vCards0.push_back(i++);
}

vector<unsigned int> vCards1(vCards0);   //初始化另一个vector
unsigned int idx=0;
srand(time(NULL));

i=0;
unsigned int tt=total;
while(i < total)  //依次抽取52张牌
{
idx = rand() % tt;  //从vCards0中随机抽取一张牌
–tt;
vCards1[i++]=vCards0[idx];  //放入vCards1

//从vCards0中删除被抽取的那张牌

vector<unsigned int>::iterator vi=vCards0.begin();
unsigned int j=0;
while(j < idx)
{
++j;
++vi;
}
vCards0.erase(vi);
}

vector<unsigned int>::iterator vib=vCards1.begin();
vector<unsigned int>::iterator vie=vCards1.end();
while(vib != vie)
{
cout << *vib++ << ” “;
}
cout << endl;

return 0;
}

当然网上还有一些效率更高的算法,大家有兴趣可以找来看看。

分类: C/C++ 标签: